From 6396019dc99fa01562aeb0f0a60b24b8ccab50ec Mon Sep 17 00:00:00 2001 From: Leon Date: Thu, 29 Aug 2024 12:36:02 +0800 Subject: [PATCH 01/15] chore: service descriptor v1 --- PROJECT | 17 + apis/apps/v1/doc.go | 20 + apis/apps/v1/groupversion_info.go | 39 + apis/apps/v1/servicedescriptor_conversion.go | 22 + apis/apps/v1/servicedescriptor_types.go | 169 +++++ apis/apps/v1/servicedescriptor_webhook.go | 79 +++ apis/apps/v1/types.go | 31 + apis/apps/v1/webhook_suite_test.go | 135 ++++ apis/apps/v1/zz_generated.deepcopy.go | 183 +++++ .../v1alpha1/servicedescriptor_conversion.go | 105 +++ apis/apps/v1alpha1/servicedescriptor_types.go | 4 - .../v1alpha1/servicedescriptor_types_test.go | 59 -- .../v1alpha1/servicedescriptor_webhook.go | 79 +++ apis/apps/v1alpha1/webhook_suite_test.go | 135 ++++ apis/apps/v1alpha1/zz_generated.deepcopy.go | 2 +- cmd/manager/main.go | 17 +- ...apps.kubeblocks.io_servicedescriptors.yaml | 669 +++++++++++++++++- config/samples/apps_v1_servicedescriptor.yaml | 12 + config/webhook/manifests.yaml | 80 +++ .../apps/servicedescriptor_controller.go | 16 +- .../apps/servicedescriptor_controller_test.go | 30 +- controllers/apps/suite_test.go | 5 + ...apps.kubeblocks.io_servicedescriptors.yaml | 669 +++++++++++++++++- docs/developer_docs/api-reference/cluster.md | 467 ++++++++++++ .../builder/builder_service_descriptor.go | 22 +- .../builder_service_descriptor_test.go | 14 +- pkg/controller/component/component_test.go | 7 +- .../component/service_descriptor_utils.go | 51 +- pkg/controller/component/service_reference.go | 10 +- pkg/controller/component/suite_test.go | 5 + pkg/controller/component/type.go | 55 +- pkg/controller/component/vars.go | 11 +- pkg/controller/component/vars_test.go | 17 +- .../apps/servicedescriptor_factory.go | 16 +- 34 files changed, 3062 insertions(+), 190 deletions(-) create mode 100644 apis/apps/v1/doc.go create mode 100644 apis/apps/v1/groupversion_info.go create mode 100644 apis/apps/v1/servicedescriptor_conversion.go create mode 100644 apis/apps/v1/servicedescriptor_types.go create mode 100644 apis/apps/v1/servicedescriptor_webhook.go create mode 100644 apis/apps/v1/types.go create mode 100644 apis/apps/v1/webhook_suite_test.go create mode 100644 apis/apps/v1/zz_generated.deepcopy.go create mode 100644 apis/apps/v1alpha1/servicedescriptor_conversion.go delete mode 100644 apis/apps/v1alpha1/servicedescriptor_types_test.go create mode 100644 apis/apps/v1alpha1/servicedescriptor_webhook.go create mode 100644 apis/apps/v1alpha1/webhook_suite_test.go create mode 100644 config/samples/apps_v1_servicedescriptor.yaml diff --git a/PROJECT b/PROJECT index 2a51e53d607..fcb8e454948 100644 --- a/PROJECT +++ b/PROJECT @@ -153,6 +153,23 @@ resources: kind: ServiceDescriptor path: github.com/apecloud/kubeblocks/apis/apps/v1alpha1 version: v1alpha1 + webhooks: + defaulting: true + validation: true + webhookVersion: v1 +- api: + crdVersion: v1 + namespaced: true + controller: true + domain: kubeblocks.io + group: apps + kind: ServiceDescriptor + path: github.com/apecloud/kubeblocks/apis/apps/v1 + version: v1 + webhooks: + defaulting: true + validation: true + webhookVersion: v1 - api: crdVersion: v1 namespaced: true diff --git a/apis/apps/v1/doc.go b/apis/apps/v1/doc.go new file mode 100644 index 00000000000..f6b5ed9ac01 --- /dev/null +++ b/apis/apps/v1/doc.go @@ -0,0 +1,20 @@ +/* +Copyright (C) 2022-2024 ApeCloud Co., Ltd + +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. +*/ + +// +k8s:deepcopy-gen=package,register +// +k8s:openapi-gen=true +// +groupName=apps.kubeblocks.io +package v1 diff --git a/apis/apps/v1/groupversion_info.go b/apis/apps/v1/groupversion_info.go new file mode 100644 index 00000000000..b1f1fa6b6b8 --- /dev/null +++ b/apis/apps/v1/groupversion_info.go @@ -0,0 +1,39 @@ +/* +Copyright (C) 2022-2024 ApeCloud Co., Ltd + +This file is part of KubeBlocks project + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ + +// Package v1 contains API Schema definitions for the apps v1 API group +// +kubebuilder:object:generate=true +// +groupName=apps.kubeblocks.io +package v1 + +import ( + "k8s.io/apimachinery/pkg/runtime/schema" + "sigs.k8s.io/controller-runtime/pkg/scheme" +) + +var ( + // GroupVersion is group version used to register these objects + GroupVersion = schema.GroupVersion{Group: "apps.kubeblocks.io", Version: "v1"} + + // SchemeBuilder is used to add go types to the GroupVersionKind scheme + SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion} + + // AddToScheme adds the types in this group-version to the given scheme. + AddToScheme = SchemeBuilder.AddToScheme +) diff --git a/apis/apps/v1/servicedescriptor_conversion.go b/apis/apps/v1/servicedescriptor_conversion.go new file mode 100644 index 00000000000..db15538881b --- /dev/null +++ b/apis/apps/v1/servicedescriptor_conversion.go @@ -0,0 +1,22 @@ +/* +Copyright (C) 2022-2024 ApeCloud Co., Ltd + +This file is part of KubeBlocks project + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ + +package v1 + +func (*ServiceDescriptor) Hub() {} diff --git a/apis/apps/v1/servicedescriptor_types.go b/apis/apps/v1/servicedescriptor_types.go new file mode 100644 index 00000000000..26836d330dc --- /dev/null +++ b/apis/apps/v1/servicedescriptor_types.go @@ -0,0 +1,169 @@ +/* +Copyright (C) 2022-2024 ApeCloud Co., Ltd + +This file is part of KubeBlocks project + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ + +package v1 + +import ( + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// +genclient +// +k8s:openapi-gen=true +// +kubebuilder:object:root=true +// +kubebuilder:subresource:status +// +kubebuilder:storageversion +// +kubebuilder:resource:categories={kubeblocks},shortName=sd +// +kubebuilder:printcolumn:name="SERVICE_KIND",type="string",JSONPath=".spec.serviceKind",description="service kind" +// +kubebuilder:printcolumn:name="SERVICE_VERSION",type="string",JSONPath=".spec.serviceVersion",description="service version" +// +kubebuilder:printcolumn:name="STATUS",type="string",JSONPath=".status.phase",description="status phase" +// +kubebuilder:printcolumn:name="AGE",type="date",JSONPath=".metadata.creationTimestamp" + +// ServiceDescriptor describes a service provided by external sources. +// It contains the necessary details such as the service's address and connection credentials. +// To enable a Cluster to access this service, the ServiceDescriptor's name should be specified +// in the Cluster configuration under `clusterComponent.serviceRefs[*].serviceDescriptor`. +type ServiceDescriptor struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec ServiceDescriptorSpec `json:"spec,omitempty"` + Status ServiceDescriptorStatus `json:"status,omitempty"` +} + +// +kubebuilder:object:root=true + +// ServiceDescriptorList contains a list of ServiceDescriptor. +type ServiceDescriptorList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []ServiceDescriptor `json:"items"` +} + +func init() { + SchemeBuilder.Register(&ServiceDescriptor{}, &ServiceDescriptorList{}) +} + +// ServiceDescriptorSpec defines the desired state of ServiceDescriptor +type ServiceDescriptorSpec struct { + // Describes the type of database service provided by the external service. + // For example, "mysql", "redis", "mongodb". + // This field categorizes databases by their functionality, protocol and compatibility, facilitating appropriate + // service integration based on their unique capabilities. + // + // This field is case-insensitive. + // + // It also supports abbreviations for some well-known databases: + // - "pg", "pgsql", "postgres", "postgresql": PostgreSQL service + // - "zk", "zookeeper": ZooKeeper service + // - "es", "elasticsearch": Elasticsearch service + // - "mongo", "mongodb": MongoDB service + // - "ch", "clickhouse": ClickHouse service + // + // +kubebuilder:validation:Required + ServiceKind string `json:"serviceKind"` + + // Describes the version of the service provided by the external service. + // This is crucial for ensuring compatibility between different components of the system, + // as different versions of a service may have varying features. + // + // +kubebuilder:validation:Required + ServiceVersion string `json:"serviceVersion"` + + // Specifies the endpoint of the external service. + // + // If the service is exposed via a cluster, the endpoint will be provided in the format of `host:port`. + // + // +optional + Endpoint *CredentialVar `json:"endpoint,omitempty"` + + // Specifies the service or IP address of the external service. + // + // +optional + Host *CredentialVar `json:"host,omitempty"` + + // Specifies the port of the external service. + // + // +optional + Port *CredentialVar `json:"port,omitempty"` + + // Specifies the authentication credentials required for accessing an external service. + // + // +optional + Auth *ConnectionCredentialAuth `json:"auth,omitempty"` +} + +// ServiceDescriptorStatus defines the observed state of ServiceDescriptor +type ServiceDescriptorStatus struct { + // Represents the generation number that has been processed by the controller. + // + // +optional + ObservedGeneration int64 `json:"observedGeneration,omitempty"` + + // Indicates the current lifecycle phase of the ServiceDescriptor. This can be either 'Available' or 'Unavailable'. + // + // +optional + Phase Phase `json:"phase,omitempty"` + + // Provides a human-readable explanation detailing the reason for the current phase of the ServiceConnectionCredential. + // + // +optional + Message string `json:"message,omitempty"` +} + +// ConnectionCredentialAuth specifies the authentication credentials required for accessing an external service. +type ConnectionCredentialAuth struct { + // Specifies the username for the external service. + // + // +optional + Username *CredentialVar `json:"username,omitempty"` + + // Specifies the password for the external service. + // + // +optional + Password *CredentialVar `json:"password,omitempty"` +} + +// CredentialVar represents a variable that retrieves its value either directly from a specified expression +// or from a source defined in `valueFrom`. +// Only one of these options may be used at a time. +type CredentialVar struct { + // Holds a direct string or an expression that can be evaluated to a string. + // + // It can include variables denoted by $(VAR_NAME). + // These variables are expanded to the value of the environment variables defined in the container. + // If a variable cannot be resolved, it remains unchanged in the output. + // + // To escape variable expansion and retain the literal value, use double $ characters. + // + // For example: + // + // - "$(VAR_NAME)" will be expanded to the value of the environment variable VAR_NAME. + // - "$$(VAR_NAME)" will result in "$(VAR_NAME)" in the output, without any variable expansion. + // + // Default value is an empty string. + // + // +optional + Value string `json:"value,omitempty" protobuf:"bytes,2,opt,name=value"` + + // Specifies the source for the variable's value. + // + // +optional + ValueFrom *corev1.EnvVarSource `json:"valueFrom,omitempty" protobuf:"bytes,3,opt,name=valueFrom"` +} diff --git a/apis/apps/v1/servicedescriptor_webhook.go b/apis/apps/v1/servicedescriptor_webhook.go new file mode 100644 index 00000000000..e87ff9167ac --- /dev/null +++ b/apis/apps/v1/servicedescriptor_webhook.go @@ -0,0 +1,79 @@ +/* +Copyright (C) 2022-2024 ApeCloud Co., Ltd + +This file is part of KubeBlocks project + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ + +package v1 + +import ( + "k8s.io/apimachinery/pkg/runtime" + ctrl "sigs.k8s.io/controller-runtime" + logf "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/webhook" + "sigs.k8s.io/controller-runtime/pkg/webhook/admission" +) + +// log is for logging in this package. +var servicedescriptorlog = logf.Log.WithName("servicedescriptor-resource") + +func (r *ServiceDescriptor) SetupWebhookWithManager(mgr ctrl.Manager) error { + return ctrl.NewWebhookManagedBy(mgr). + For(r). + Complete() +} + +// TODO(user): EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! + +//+kubebuilder:webhook:path=/mutate-apps-kubeblocks-io-v1-servicedescriptor,mutating=true,failurePolicy=fail,sideEffects=None,groups=apps.kubeblocks.io,resources=servicedescriptors,verbs=create;update,versions=v1,name=mservicedescriptor.kb.io,admissionReviewVersions=v1 + +var _ webhook.Defaulter = &ServiceDescriptor{} + +// Default implements webhook.Defaulter so a webhook will be registered for the type +func (r *ServiceDescriptor) Default() { + servicedescriptorlog.Info("default", "name", r.Name) + + // TODO(user): fill in your defaulting logic. +} + +// TODO(user): change verbs to "verbs=create;update;delete" if you want to enable deletion validation. +//+kubebuilder:webhook:path=/validate-apps-kubeblocks-io-v1-servicedescriptor,mutating=false,failurePolicy=fail,sideEffects=None,groups=apps.kubeblocks.io,resources=servicedescriptors,verbs=create;update,versions=v1,name=vservicedescriptor.kb.io,admissionReviewVersions=v1 + +var _ webhook.Validator = &ServiceDescriptor{} + +// ValidateCreate implements webhook.Validator so a webhook will be registered for the type +func (r *ServiceDescriptor) ValidateCreate() (warnings admission.Warnings, err error) { + servicedescriptorlog.Info("validate create", "name", r.Name) + + // TODO(user): fill in your validation logic upon object creation. + return nil, nil +} + +// ValidateUpdate implements webhook.Validator so a webhook will be registered for the type +func (r *ServiceDescriptor) ValidateUpdate(old runtime.Object) (warnings admission.Warnings, err error) { + servicedescriptorlog.Info("validate update", "name", r.Name) + + // TODO(user): fill in your validation logic upon object update. + return nil, nil +} + +// ValidateDelete implements webhook.Validator so a webhook will be registered for the type +func (r *ServiceDescriptor) ValidateDelete() (warnings admission.Warnings, err error) { + servicedescriptorlog.Info("validate delete", "name", r.Name) + + // TODO(user): fill in your validation logic upon object deletion. + return nil, nil +} diff --git a/apis/apps/v1/types.go b/apis/apps/v1/types.go new file mode 100644 index 00000000000..8263b109a4d --- /dev/null +++ b/apis/apps/v1/types.go @@ -0,0 +1,31 @@ +/* +Copyright (C) 2022-2024 ApeCloud Co., Ltd + +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 v1 + +// Phase represents the status of a CR. +// +// +enum +// +kubebuilder:validation:Enum={Available,Unavailable} +type Phase string + +const ( + // AvailablePhase indicates that a CR is in an available state. + AvailablePhase Phase = "Available" + + // UnavailablePhase indicates that a CR is in an unavailable state. + UnavailablePhase Phase = "Unavailable" +) diff --git a/apis/apps/v1/webhook_suite_test.go b/apis/apps/v1/webhook_suite_test.go new file mode 100644 index 00000000000..f55e5a8e905 --- /dev/null +++ b/apis/apps/v1/webhook_suite_test.go @@ -0,0 +1,135 @@ +/* +Copyright (C) 2022-2024 ApeCloud Co., Ltd + +This file is part of KubeBlocks project + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ + +package v1 + +import ( + "context" + "crypto/tls" + "fmt" + "net" + "path/filepath" + "testing" + "time" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + + admissionv1beta1 "k8s.io/api/admission/v1beta1" + //+kubebuilder:scaffold:imports + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/client-go/rest" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/envtest" + logf "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/log/zap" +) + +// These tests use Ginkgo (BDD-style Go testing framework). Refer to +// http://onsi.github.io/ginkgo/ to learn more about Ginkgo. + +var cfg *rest.Config +var k8sClient client.Client +var testEnv *envtest.Environment +var ctx context.Context +var cancel context.CancelFunc + +func TestAPIs(t *testing.T) { + RegisterFailHandler(Fail) + + RunSpecs(t, "Webhook Suite") +} + +var _ = BeforeSuite(func() { + logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))) + + ctx, cancel = context.WithCancel(context.TODO()) + + By("bootstrapping test environment") + testEnv = &envtest.Environment{ + CRDDirectoryPaths: []string{filepath.Join("..", "..", "..", "config", "crd", "bases")}, + ErrorIfCRDPathMissing: false, + WebhookInstallOptions: envtest.WebhookInstallOptions{ + Paths: []string{filepath.Join("..", "..", "..", "config", "webhook")}, + }, + } + + var err error + // cfg is defined in this file globally. + cfg, err = testEnv.Start() + Expect(err).NotTo(HaveOccurred()) + Expect(cfg).NotTo(BeNil()) + + scheme := runtime.NewScheme() + err = AddToScheme(scheme) + Expect(err).NotTo(HaveOccurred()) + + err = admissionv1beta1.AddToScheme(scheme) + Expect(err).NotTo(HaveOccurred()) + + //+kubebuilder:scaffold:scheme + + k8sClient, err = client.New(cfg, client.Options{Scheme: scheme}) + Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient).NotTo(BeNil()) + + // start webhook server using Manager + webhookInstallOptions := &testEnv.WebhookInstallOptions + mgr, err := ctrl.NewManager(cfg, ctrl.Options{ + Scheme: scheme, + // Host: webhookInstallOptions.LocalServingHost, + // Port: webhookInstallOptions.LocalServingPort, + // CertDir: webhookInstallOptions.LocalServingCertDir, + LeaderElection: false, + // MetricsBindAddress: "0", + }) + Expect(err).NotTo(HaveOccurred()) + + err = (&ServiceDescriptor{}).SetupWebhookWithManager(mgr) + Expect(err).NotTo(HaveOccurred()) + + //+kubebuilder:scaffold:webhook + + go func() { + defer GinkgoRecover() + err = mgr.Start(ctx) + Expect(err).NotTo(HaveOccurred()) + }() + + // wait for the webhook server to get ready + dialer := &net.Dialer{Timeout: time.Second} + addrPort := fmt.Sprintf("%s:%d", webhookInstallOptions.LocalServingHost, webhookInstallOptions.LocalServingPort) + Eventually(func() error { + conn, err := tls.DialWithDialer(dialer, "tcp", addrPort, &tls.Config{InsecureSkipVerify: true}) + if err != nil { + return err + } + conn.Close() + return nil + }).Should(Succeed()) + +}) + +var _ = AfterSuite(func() { + cancel() + By("tearing down the test environment") + err := testEnv.Stop() + Expect(err).NotTo(HaveOccurred()) +}) diff --git a/apis/apps/v1/zz_generated.deepcopy.go b/apis/apps/v1/zz_generated.deepcopy.go new file mode 100644 index 00000000000..2decbe435dc --- /dev/null +++ b/apis/apps/v1/zz_generated.deepcopy.go @@ -0,0 +1,183 @@ +//go:build !ignore_autogenerated + +/* +Copyright (C) 2022-2024 ApeCloud Co., Ltd + +This file is part of KubeBlocks project + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ + +// Code generated by controller-gen. DO NOT EDIT. + +package v1 + +import ( + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ConnectionCredentialAuth) DeepCopyInto(out *ConnectionCredentialAuth) { + *out = *in + if in.Username != nil { + in, out := &in.Username, &out.Username + *out = new(CredentialVar) + (*in).DeepCopyInto(*out) + } + if in.Password != nil { + in, out := &in.Password, &out.Password + *out = new(CredentialVar) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ConnectionCredentialAuth. +func (in *ConnectionCredentialAuth) DeepCopy() *ConnectionCredentialAuth { + if in == nil { + return nil + } + out := new(ConnectionCredentialAuth) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CredentialVar) DeepCopyInto(out *CredentialVar) { + *out = *in + if in.ValueFrom != nil { + in, out := &in.ValueFrom, &out.ValueFrom + *out = new(corev1.EnvVarSource) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CredentialVar. +func (in *CredentialVar) DeepCopy() *CredentialVar { + if in == nil { + return nil + } + out := new(CredentialVar) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ServiceDescriptor) DeepCopyInto(out *ServiceDescriptor) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + out.Status = in.Status +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceDescriptor. +func (in *ServiceDescriptor) DeepCopy() *ServiceDescriptor { + if in == nil { + return nil + } + out := new(ServiceDescriptor) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ServiceDescriptor) 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 *ServiceDescriptorList) DeepCopyInto(out *ServiceDescriptorList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]ServiceDescriptor, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceDescriptorList. +func (in *ServiceDescriptorList) DeepCopy() *ServiceDescriptorList { + if in == nil { + return nil + } + out := new(ServiceDescriptorList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ServiceDescriptorList) 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 *ServiceDescriptorSpec) DeepCopyInto(out *ServiceDescriptorSpec) { + *out = *in + if in.Endpoint != nil { + in, out := &in.Endpoint, &out.Endpoint + *out = new(CredentialVar) + (*in).DeepCopyInto(*out) + } + if in.Host != nil { + in, out := &in.Host, &out.Host + *out = new(CredentialVar) + (*in).DeepCopyInto(*out) + } + if in.Port != nil { + in, out := &in.Port, &out.Port + *out = new(CredentialVar) + (*in).DeepCopyInto(*out) + } + if in.Auth != nil { + in, out := &in.Auth, &out.Auth + *out = new(ConnectionCredentialAuth) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceDescriptorSpec. +func (in *ServiceDescriptorSpec) DeepCopy() *ServiceDescriptorSpec { + if in == nil { + return nil + } + out := new(ServiceDescriptorSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ServiceDescriptorStatus) DeepCopyInto(out *ServiceDescriptorStatus) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceDescriptorStatus. +func (in *ServiceDescriptorStatus) DeepCopy() *ServiceDescriptorStatus { + if in == nil { + return nil + } + out := new(ServiceDescriptorStatus) + in.DeepCopyInto(out) + return out +} diff --git a/apis/apps/v1alpha1/servicedescriptor_conversion.go b/apis/apps/v1alpha1/servicedescriptor_conversion.go new file mode 100644 index 00000000000..97ba8deec72 --- /dev/null +++ b/apis/apps/v1alpha1/servicedescriptor_conversion.go @@ -0,0 +1,105 @@ +/* +Copyright (C) 2022-2024 ApeCloud Co., Ltd + +This file is part of KubeBlocks project + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ + +package v1alpha1 + +import ( + "sigs.k8s.io/controller-runtime/pkg/conversion" + + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" +) + +// ConvertTo converts this Demo to the Hub version (v2). +func (r *ServiceDescriptor) ConvertTo(dstRaw conversion.Hub) error { + dst := dstRaw.(*appsv1.ServiceDescriptor) + + // objectMeta + dst.ObjectMeta = r.ObjectMeta + + // spec + dst.Spec.ServiceKind = r.Spec.ServiceKind + dst.Spec.ServiceVersion = r.Spec.ServiceVersion + dst.Spec.Endpoint = r.credentialVarTo(r.Spec.Endpoint) + dst.Spec.Host = r.credentialVarTo(r.Spec.Host) + dst.Spec.Port = r.credentialVarTo(r.Spec.Port) + if r.Spec.Auth == nil { + dst.Spec.Auth = nil + } else { + dst.Spec.Auth = &appsv1.ConnectionCredentialAuth{ + Username: r.credentialVarTo(r.Spec.Auth.Username), + Password: r.credentialVarTo(r.Spec.Auth.Password), + } + } + + // status + dst.Status.ObservedGeneration = r.Status.ObservedGeneration + dst.Status.Phase = appsv1.Phase(r.Status.Phase) + dst.Status.Message = r.Status.Message + + return nil +} + +func (r *ServiceDescriptor) ConvertFrom(srcRaw conversion.Hub) error { + src := srcRaw.(*appsv1.ServiceDescriptor) + + // objectMeta + r.ObjectMeta = src.ObjectMeta + + // spec + r.Spec.ServiceKind = src.Spec.ServiceKind + r.Spec.ServiceVersion = src.Spec.ServiceVersion + r.Spec.Endpoint = r.credentialVarFrom(src.Spec.Endpoint) + r.Spec.Host = r.credentialVarFrom(src.Spec.Host) + r.Spec.Port = r.credentialVarFrom(src.Spec.Port) + if r.Spec.Auth == nil { + r.Spec.Auth = nil + } else { + r.Spec.Auth = &ConnectionCredentialAuth{ + Username: r.credentialVarFrom(src.Spec.Auth.Username), + Password: r.credentialVarFrom(src.Spec.Auth.Password), + } + } + + // status + r.Status.ObservedGeneration = src.Status.ObservedGeneration + r.Status.Phase = Phase(src.Status.Phase) + r.Status.Message = src.Status.Message + + return nil +} + +func (r *ServiceDescriptor) credentialVarTo(src *CredentialVar) *appsv1.CredentialVar { + if src != nil { + return &appsv1.CredentialVar{ + Value: src.Value, + ValueFrom: src.ValueFrom, + } + } + return nil +} + +func (r *ServiceDescriptor) credentialVarFrom(src *appsv1.CredentialVar) *CredentialVar { + if src != nil { + return &CredentialVar{ + Value: src.Value, + ValueFrom: src.ValueFrom, + } + } + return nil +} diff --git a/apis/apps/v1alpha1/servicedescriptor_types.go b/apis/apps/v1alpha1/servicedescriptor_types.go index b3acbbd32ad..12f63d9fa8c 100644 --- a/apis/apps/v1alpha1/servicedescriptor_types.go +++ b/apis/apps/v1alpha1/servicedescriptor_types.go @@ -129,10 +129,6 @@ type ServiceDescriptorStatus struct { ObservedGeneration int64 `json:"observedGeneration,omitempty"` } -func (r ServiceDescriptorStatus) GetTerminalPhases() []Phase { - return []Phase{AvailablePhase} -} - // +genclient // +k8s:openapi-gen=true // +kubebuilder:object:root=true diff --git a/apis/apps/v1alpha1/servicedescriptor_types_test.go b/apis/apps/v1alpha1/servicedescriptor_types_test.go deleted file mode 100644 index 326e60eedfd..00000000000 --- a/apis/apps/v1alpha1/servicedescriptor_types_test.go +++ /dev/null @@ -1,59 +0,0 @@ -/* -Copyright (C) 2022-2024 ApeCloud Co., Ltd - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package v1alpha1 - -import ( - "testing" - - "github.com/stretchr/testify/assert" -) - -func TestServiceDescriptorStatus(t *testing.T) { - type fields struct { - Phase Phase - Message string - ObservedGeneration int64 - } - tests := []struct { - name string - fields fields - want bool - }{{ - name: "available phase test", - fields: fields{ - Phase: AvailablePhase, - }, - want: true, - }, { - name: "unavailable phase test", - fields: fields{ - Phase: UnavailablePhase, - }, - want: false, - }} - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - sd := ServiceDescriptorStatus{ - Phase: tt.fields.Phase, - Message: tt.fields.Message, - ObservedGeneration: tt.fields.ObservedGeneration, - } - actual := sd.GetTerminalPhases()[0] == tt.fields.Phase - assert.Equalf(t, tt.want, actual, "GetTerminalPhases() = %v, want %v", sd.GetTerminalPhases(), tt.want) - }) - } -} diff --git a/apis/apps/v1alpha1/servicedescriptor_webhook.go b/apis/apps/v1alpha1/servicedescriptor_webhook.go new file mode 100644 index 00000000000..fbf31eae063 --- /dev/null +++ b/apis/apps/v1alpha1/servicedescriptor_webhook.go @@ -0,0 +1,79 @@ +/* +Copyright (C) 2022-2024 ApeCloud Co., Ltd + +This file is part of KubeBlocks project + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ + +package v1alpha1 + +import ( + "k8s.io/apimachinery/pkg/runtime" + ctrl "sigs.k8s.io/controller-runtime" + logf "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/webhook" + "sigs.k8s.io/controller-runtime/pkg/webhook/admission" +) + +// log is for logging in this package. +var servicedescriptorlog = logf.Log.WithName("servicedescriptor-resource") + +func (r *ServiceDescriptor) SetupWebhookWithManager(mgr ctrl.Manager) error { + return ctrl.NewWebhookManagedBy(mgr). + For(r). + Complete() +} + +// TODO(user): EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! + +//+kubebuilder:webhook:path=/mutate-apps-kubeblocks-io-v1alpha1-servicedescriptor,mutating=true,failurePolicy=fail,sideEffects=None,groups=apps.kubeblocks.io,resources=servicedescriptors,verbs=create;update,versions=v1alpha1,name=mservicedescriptor.kb.io,admissionReviewVersions=v1 + +var _ webhook.Defaulter = &ServiceDescriptor{} + +// Default implements webhook.Defaulter so a webhook will be registered for the type +func (r *ServiceDescriptor) Default() { + servicedescriptorlog.Info("default", "name", r.Name) + + // TODO(user): fill in your defaulting logic. +} + +// TODO(user): change verbs to "verbs=create;update;delete" if you want to enable deletion validation. +//+kubebuilder:webhook:path=/validate-apps-kubeblocks-io-v1alpha1-servicedescriptor,mutating=false,failurePolicy=fail,sideEffects=None,groups=apps.kubeblocks.io,resources=servicedescriptors,verbs=create;update,versions=v1alpha1,name=vservicedescriptor.kb.io,admissionReviewVersions=v1 + +var _ webhook.Validator = &ServiceDescriptor{} + +// ValidateCreate implements webhook.Validator so a webhook will be registered for the type +func (r *ServiceDescriptor) ValidateCreate() (warnings admission.Warnings, err error) { + servicedescriptorlog.Info("validate create", "name", r.Name) + + // TODO(user): fill in your validation logic upon object creation. + return nil, nil +} + +// ValidateUpdate implements webhook.Validator so a webhook will be registered for the type +func (r *ServiceDescriptor) ValidateUpdate(old runtime.Object) (warnings admission.Warnings, err error) { + servicedescriptorlog.Info("validate update", "name", r.Name) + + // TODO(user): fill in your validation logic upon object update. + return nil, nil +} + +// ValidateDelete implements webhook.Validator so a webhook will be registered for the type +func (r *ServiceDescriptor) ValidateDelete() (warnings admission.Warnings, err error) { + servicedescriptorlog.Info("validate delete", "name", r.Name) + + // TODO(user): fill in your validation logic upon object deletion. + return nil, nil +} diff --git a/apis/apps/v1alpha1/webhook_suite_test.go b/apis/apps/v1alpha1/webhook_suite_test.go new file mode 100644 index 00000000000..3dbd11ff519 --- /dev/null +++ b/apis/apps/v1alpha1/webhook_suite_test.go @@ -0,0 +1,135 @@ +/* +Copyright (C) 2022-2024 ApeCloud Co., Ltd + +This file is part of KubeBlocks project + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ + +package v1alpha1 + +import ( + "context" + "crypto/tls" + "fmt" + "net" + "path/filepath" + "testing" + "time" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + + admissionv1beta1 "k8s.io/api/admission/v1beta1" + //+kubebuilder:scaffold:imports + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/client-go/rest" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/envtest" + logf "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/log/zap" +) + +// These tests use Ginkgo (BDD-style Go testing framework). Refer to +// http://onsi.github.io/ginkgo/ to learn more about Ginkgo. + +var cfg *rest.Config +var k8sClient client.Client +var testEnv *envtest.Environment +var ctx context.Context +var cancel context.CancelFunc + +func TestAPIs(t *testing.T) { + RegisterFailHandler(Fail) + + RunSpecs(t, "Webhook Suite") +} + +var _ = BeforeSuite(func() { + logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))) + + ctx, cancel = context.WithCancel(context.TODO()) + + By("bootstrapping test environment") + testEnv = &envtest.Environment{ + CRDDirectoryPaths: []string{filepath.Join("..", "..", "..", "config", "crd", "bases")}, + ErrorIfCRDPathMissing: false, + WebhookInstallOptions: envtest.WebhookInstallOptions{ + Paths: []string{filepath.Join("..", "..", "..", "config", "webhook")}, + }, + } + + var err error + // cfg is defined in this file globally. + cfg, err = testEnv.Start() + Expect(err).NotTo(HaveOccurred()) + Expect(cfg).NotTo(BeNil()) + + scheme := runtime.NewScheme() + err = AddToScheme(scheme) + Expect(err).NotTo(HaveOccurred()) + + err = admissionv1beta1.AddToScheme(scheme) + Expect(err).NotTo(HaveOccurred()) + + //+kubebuilder:scaffold:scheme + + k8sClient, err = client.New(cfg, client.Options{Scheme: scheme}) + Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient).NotTo(BeNil()) + + // start webhook server using Manager + webhookInstallOptions := &testEnv.WebhookInstallOptions + mgr, err := ctrl.NewManager(cfg, ctrl.Options{ + Scheme: scheme, + // Host: webhookInstallOptions.LocalServingHost, + // Port: webhookInstallOptions.LocalServingPort, + // CertDir: webhookInstallOptions.LocalServingCertDir, + LeaderElection: false, + // MetricsBindAddress: "0", + }) + Expect(err).NotTo(HaveOccurred()) + + err = (&ServiceDescriptor{}).SetupWebhookWithManager(mgr) + Expect(err).NotTo(HaveOccurred()) + + //+kubebuilder:scaffold:webhook + + go func() { + defer GinkgoRecover() + err = mgr.Start(ctx) + Expect(err).NotTo(HaveOccurred()) + }() + + // wait for the webhook server to get ready + dialer := &net.Dialer{Timeout: time.Second} + addrPort := fmt.Sprintf("%s:%d", webhookInstallOptions.LocalServingHost, webhookInstallOptions.LocalServingPort) + Eventually(func() error { + conn, err := tls.DialWithDialer(dialer, "tcp", addrPort, &tls.Config{InsecureSkipVerify: true}) + if err != nil { + return err + } + conn.Close() + return nil + }).Should(Succeed()) + +}) + +var _ = AfterSuite(func() { + cancel() + By("tearing down the test environment") + err := testEnv.Stop() + Expect(err).NotTo(HaveOccurred()) +}) diff --git a/apis/apps/v1alpha1/zz_generated.deepcopy.go b/apis/apps/v1alpha1/zz_generated.deepcopy.go index f86aaa75efd..6619fae6820 100644 --- a/apis/apps/v1alpha1/zz_generated.deepcopy.go +++ b/apis/apps/v1alpha1/zz_generated.deepcopy.go @@ -31,7 +31,7 @@ import ( "k8s.io/api/core/v1" rbacv1 "k8s.io/api/rbac/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - runtime "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/util/intstr" ) diff --git a/cmd/manager/main.go b/cmd/manager/main.go index 389ea95db6b..03e404f79a2 100644 --- a/cmd/manager/main.go +++ b/cmd/manager/main.go @@ -49,6 +49,7 @@ import ( // +kubebuilder:scaffold:imports + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" appsv1beta1 "github.com/apecloud/kubeblocks/apis/apps/v1beta1" dpv1alpha1 "github.com/apecloud/kubeblocks/apis/dataprotection/v1alpha1" @@ -101,17 +102,18 @@ var ( func init() { utilruntime.Must(clientgoscheme.AddToScheme(scheme)) - utilruntime.Must(appsv1alpha1.AddToScheme(scheme)) + utilruntime.Must(appsv1beta1.AddToScheme(scheme)) + utilruntime.Must(appsv1.AddToScheme(scheme)) utilruntime.Must(dpv1alpha1.AddToScheme(scheme)) utilruntime.Must(snapshotv1.AddToScheme(scheme)) utilruntime.Must(snapshotv1beta1.AddToScheme(scheme)) utilruntime.Must(extensionsv1alpha1.AddToScheme(scheme)) utilruntime.Must(workloadsv1alpha1.AddToScheme(scheme)) - utilruntime.Must(appsv1beta1.AddToScheme(scheme)) utilruntime.Must(legacy.AddToScheme(scheme)) utilruntime.Must(apiextv1.AddToScheme(scheme)) utilruntime.Must(experimentalv1alpha1.AddToScheme(scheme)) + // +kubebuilder:scaffold:scheme viper.SetConfigName("config") // name of config file (without extension) @@ -520,6 +522,17 @@ func main() { os.Exit(1) } } + + if os.Getenv("ENABLE_WEBHOOKS") == "true" { + if err = (&appsv1alpha1.ServiceDescriptor{}).SetupWebhookWithManager(mgr); err != nil { + setupLog.Error(err, "unable to create webhook", "webhook", "ServiceDescriptor") + os.Exit(1) + } + if err = (&appsv1.ServiceDescriptor{}).SetupWebhookWithManager(mgr); err != nil { + setupLog.Error(err, "unable to create webhook", "webhook", "ServiceDescriptor") + os.Exit(1) + } + } // +kubebuilder:scaffold:builder if err := mgr.AddHealthzCheck("healthz", healthz.Ping); err != nil { diff --git a/config/crd/bases/apps.kubeblocks.io_servicedescriptors.yaml b/config/crd/bases/apps.kubeblocks.io_servicedescriptors.yaml index 7be8abce397..99d33d9eaff 100644 --- a/config/crd/bases/apps.kubeblocks.io_servicedescriptors.yaml +++ b/config/crd/bases/apps.kubeblocks.io_servicedescriptors.yaml @@ -20,6 +20,673 @@ spec: singular: servicedescriptor scope: Namespaced versions: + - additionalPrinterColumns: + - description: service kind + jsonPath: .spec.serviceKind + name: SERVICE_KIND + type: string + - description: service version + jsonPath: .spec.serviceVersion + name: SERVICE_VERSION + type: string + - description: status phase + jsonPath: .status.phase + name: STATUS + type: string + - jsonPath: .metadata.creationTimestamp + name: AGE + type: date + name: v1 + schema: + openAPIV3Schema: + description: |- + ServiceDescriptor describes a service provided by external sources. + It contains the necessary details such as the service's address and connection credentials. + To enable a Cluster to access this service, the ServiceDescriptor's name should be specified + in the Cluster configuration under `clusterComponent.serviceRefs[*].serviceDescriptor`. + 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: ServiceDescriptorSpec defines the desired state of ServiceDescriptor + properties: + auth: + description: Specifies the authentication credentials required for + accessing an external service. + properties: + password: + description: Specifies the password for the external service. + properties: + value: + description: |- + Holds a direct string or an expression that can be evaluated to a string. + + + It can include variables denoted by $(VAR_NAME). + These variables are expanded to the value of the environment variables defined in the container. + If a variable cannot be resolved, it remains unchanged in the output. + + + To escape variable expansion and retain the literal value, use double $ characters. + + + For example: + + + - "$(VAR_NAME)" will be expanded to the value of the environment variable VAR_NAME. + - "$$(VAR_NAME)" will result in "$(VAR_NAME)" in the output, without any variable expansion. + + + Default value is an empty string. + type: string + valueFrom: + description: Specifies the source for the variable's value. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the FieldPath is + written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the specified + API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the exposed + resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in the pod's namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + username: + description: Specifies the username for the external service. + properties: + value: + description: |- + Holds a direct string or an expression that can be evaluated to a string. + + + It can include variables denoted by $(VAR_NAME). + These variables are expanded to the value of the environment variables defined in the container. + If a variable cannot be resolved, it remains unchanged in the output. + + + To escape variable expansion and retain the literal value, use double $ characters. + + + For example: + + + - "$(VAR_NAME)" will be expanded to the value of the environment variable VAR_NAME. + - "$$(VAR_NAME)" will result in "$(VAR_NAME)" in the output, without any variable expansion. + + + Default value is an empty string. + type: string + valueFrom: + description: Specifies the source for the variable's value. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the FieldPath is + written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the specified + API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the exposed + resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in the pod's namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + type: object + endpoint: + description: |- + Specifies the endpoint of the external service. + + + If the service is exposed via a cluster, the endpoint will be provided in the format of `host:port`. + properties: + value: + description: |- + Holds a direct string or an expression that can be evaluated to a string. + + + It can include variables denoted by $(VAR_NAME). + These variables are expanded to the value of the environment variables defined in the container. + If a variable cannot be resolved, it remains unchanged in the output. + + + To escape variable expansion and retain the literal value, use double $ characters. + + + For example: + + + - "$(VAR_NAME)" will be expanded to the value of the environment variable VAR_NAME. + - "$$(VAR_NAME)" will result in "$(VAR_NAME)" in the output, without any variable expansion. + + + Default value is an empty string. + type: string + valueFrom: + description: Specifies the source for the variable's value. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the FieldPath is written + in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the specified + API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required for volumes, optional + for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the exposed + resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in the pod's namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must + be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + host: + description: Specifies the service or IP address of the external service. + properties: + value: + description: |- + Holds a direct string or an expression that can be evaluated to a string. + + + It can include variables denoted by $(VAR_NAME). + These variables are expanded to the value of the environment variables defined in the container. + If a variable cannot be resolved, it remains unchanged in the output. + + + To escape variable expansion and retain the literal value, use double $ characters. + + + For example: + + + - "$(VAR_NAME)" will be expanded to the value of the environment variable VAR_NAME. + - "$$(VAR_NAME)" will result in "$(VAR_NAME)" in the output, without any variable expansion. + + + Default value is an empty string. + type: string + valueFrom: + description: Specifies the source for the variable's value. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the FieldPath is written + in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the specified + API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required for volumes, optional + for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the exposed + resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in the pod's namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must + be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + port: + description: Specifies the port of the external service. + properties: + value: + description: |- + Holds a direct string or an expression that can be evaluated to a string. + + + It can include variables denoted by $(VAR_NAME). + These variables are expanded to the value of the environment variables defined in the container. + If a variable cannot be resolved, it remains unchanged in the output. + + + To escape variable expansion and retain the literal value, use double $ characters. + + + For example: + + + - "$(VAR_NAME)" will be expanded to the value of the environment variable VAR_NAME. + - "$$(VAR_NAME)" will result in "$(VAR_NAME)" in the output, without any variable expansion. + + + Default value is an empty string. + type: string + valueFrom: + description: Specifies the source for the variable's value. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the FieldPath is written + in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the specified + API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required for volumes, optional + for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the exposed + resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in the pod's namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must + be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + serviceKind: + description: |- + Describes the type of database service provided by the external service. + For example, "mysql", "redis", "mongodb". + This field categorizes databases by their functionality, protocol and compatibility, facilitating appropriate + service integration based on their unique capabilities. + + + This field is case-insensitive. + + + It also supports abbreviations for some well-known databases: + - "pg", "pgsql", "postgres", "postgresql": PostgreSQL service + - "zk", "zookeeper": ZooKeeper service + - "es", "elasticsearch": Elasticsearch service + - "mongo", "mongodb": MongoDB service + - "ch", "clickhouse": ClickHouse service + type: string + serviceVersion: + description: |- + Describes the version of the service provided by the external service. + This is crucial for ensuring compatibility between different components of the system, + as different versions of a service may have varying features. + type: string + required: + - serviceKind + - serviceVersion + type: object + status: + description: ServiceDescriptorStatus defines the observed state of ServiceDescriptor + properties: + message: + description: Provides a human-readable explanation detailing the reason + for the current phase of the ServiceConnectionCredential. + type: string + observedGeneration: + description: Represents the generation number that has been processed + by the controller. + format: int64 + type: integer + phase: + description: Indicates the current lifecycle phase of the ServiceDescriptor. + This can be either 'Available' or 'Unavailable'. + enum: + - Available + - Unavailable + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} - additionalPrinterColumns: - description: service kind jsonPath: .spec.serviceKind @@ -684,6 +1351,6 @@ spec: type: object type: object served: true - storage: true + storage: false subresources: status: {} diff --git a/config/samples/apps_v1_servicedescriptor.yaml b/config/samples/apps_v1_servicedescriptor.yaml new file mode 100644 index 00000000000..44a3249f972 --- /dev/null +++ b/config/samples/apps_v1_servicedescriptor.yaml @@ -0,0 +1,12 @@ +apiVersion: apps.kubeblocks.io/v1 +kind: ServiceDescriptor +metadata: + labels: + app.kubernetes.io/name: servicedescriptor + app.kubernetes.io/instance: servicedescriptor-sample + app.kubernetes.io/part-of: kubeblocks + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/created-by: kubeblocks + name: servicedescriptor-sample +spec: + # TODO(user): Add fields here diff --git a/config/webhook/manifests.yaml b/config/webhook/manifests.yaml index 80a52dae782..aa99856da03 100644 --- a/config/webhook/manifests.yaml +++ b/config/webhook/manifests.yaml @@ -4,9 +4,89 @@ kind: MutatingWebhookConfiguration metadata: name: mutating-webhook-configuration webhooks: +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: webhook-service + namespace: system + path: /mutate-apps-kubeblocks-io-v1-servicedescriptor + failurePolicy: Fail + name: mservicedescriptor.kb.io + rules: + - apiGroups: + - apps.kubeblocks.io + apiVersions: + - v1 + operations: + - CREATE + - UPDATE + resources: + - servicedescriptors + sideEffects: None +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: webhook-service + namespace: system + path: /mutate-apps-kubeblocks-io-v1alpha1-servicedescriptor + failurePolicy: Fail + name: mservicedescriptor.kb.io + rules: + - apiGroups: + - apps.kubeblocks.io + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + resources: + - servicedescriptors + sideEffects: None --- apiVersion: admissionregistration.k8s.io/v1 kind: ValidatingWebhookConfiguration metadata: name: validating-webhook-configuration webhooks: +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: webhook-service + namespace: system + path: /validate-apps-kubeblocks-io-v1-servicedescriptor + failurePolicy: Fail + name: vservicedescriptor.kb.io + rules: + - apiGroups: + - apps.kubeblocks.io + apiVersions: + - v1 + operations: + - CREATE + - UPDATE + resources: + - servicedescriptors + sideEffects: None +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: webhook-service + namespace: system + path: /validate-apps-kubeblocks-io-v1alpha1-servicedescriptor + failurePolicy: Fail + name: vservicedescriptor.kb.io + rules: + - apiGroups: + - apps.kubeblocks.io + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + resources: + - servicedescriptors + sideEffects: None diff --git a/controllers/apps/servicedescriptor_controller.go b/controllers/apps/servicedescriptor_controller.go index 8343ad558f9..c2e087e8b3c 100644 --- a/controllers/apps/servicedescriptor_controller.go +++ b/controllers/apps/servicedescriptor_controller.go @@ -23,7 +23,6 @@ import ( "context" "fmt" - "golang.org/x/exp/slices" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/client-go/tools/record" @@ -31,6 +30,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/log" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" "github.com/apecloud/kubeblocks/pkg/constant" intctrlutil "github.com/apecloud/kubeblocks/pkg/controllerutil" @@ -64,7 +64,7 @@ func (r *ServiceDescriptorReconciler) Reconcile(ctx context.Context, req ctrl.Re Recorder: r.Recorder, } - serviceDescriptor := &appsv1alpha1.ServiceDescriptor{} + serviceDescriptor := &appsv1.ServiceDescriptor{} if err := r.Client.Get(reqCtx.Ctx, reqCtx.Req.NamespacedName, serviceDescriptor); err != nil { return intctrlutil.CheckedRequeueWithError(err, reqCtx.Log, "") } @@ -85,18 +85,18 @@ func (r *ServiceDescriptorReconciler) Reconcile(ctx context.Context, req ctrl.Re } if serviceDescriptor.Status.ObservedGeneration == serviceDescriptor.Generation && - slices.Contains(serviceDescriptor.Status.GetTerminalPhases(), serviceDescriptor.Status.Phase) { + serviceDescriptor.Status.Phase == appsv1.AvailablePhase { return intctrlutil.Reconciled() } if err := r.checkServiceDescriptor(reqCtx, serviceDescriptor); err != nil { - if err := r.updateServiceDescriptorStatus(r.Client, reqCtx, serviceDescriptor, appsv1alpha1.UnavailablePhase); err != nil { + if err := r.updateServiceDescriptorStatus(r.Client, reqCtx, serviceDescriptor, appsv1.UnavailablePhase); err != nil { return intctrlutil.CheckedRequeueWithError(err, reqCtx.Log, "InvalidServiceDescriptor update unavailable status failed") } return intctrlutil.CheckedRequeueWithError(err, reqCtx.Log, "InvalidServiceDescriptor") } - err = r.updateServiceDescriptorStatus(r.Client, reqCtx, serviceDescriptor, appsv1alpha1.AvailablePhase) + err = r.updateServiceDescriptorStatus(r.Client, reqCtx, serviceDescriptor, appsv1.AvailablePhase) if err != nil { return intctrlutil.CheckedRequeueWithError(err, reqCtx.Log, "") } @@ -108,12 +108,12 @@ func (r *ServiceDescriptorReconciler) Reconcile(ctx context.Context, req ctrl.Re // SetupWithManager sets up the controller with the Manager. func (r *ServiceDescriptorReconciler) SetupWithManager(mgr ctrl.Manager) error { return intctrlutil.NewNamespacedControllerManagedBy(mgr). - For(&appsv1alpha1.ServiceDescriptor{}). + For(&appsv1.ServiceDescriptor{}). Complete(r) } // checkServiceDescriptor checks if the service descriptor is valid. -func (r *ServiceDescriptorReconciler) checkServiceDescriptor(reqCtx intctrlutil.RequestCtx, serviceDescriptor *appsv1alpha1.ServiceDescriptor) error { +func (r *ServiceDescriptorReconciler) checkServiceDescriptor(reqCtx intctrlutil.RequestCtx, serviceDescriptor *appsv1.ServiceDescriptor) error { secretRefExistFn := func(envFrom *corev1.EnvVarSource) bool { if envFrom == nil || envFrom.SecretKeyRef == nil { return true @@ -159,7 +159,7 @@ func (r *ServiceDescriptorReconciler) checkServiceDescriptor(reqCtx intctrlutil. } // updateServiceDescriptorStatus updates the status of the service descriptor. -func (r *ServiceDescriptorReconciler) updateServiceDescriptorStatus(cli client.Client, ctx intctrlutil.RequestCtx, serviceDescriptor *appsv1alpha1.ServiceDescriptor, phase appsv1alpha1.Phase) error { +func (r *ServiceDescriptorReconciler) updateServiceDescriptorStatus(cli client.Client, ctx intctrlutil.RequestCtx, serviceDescriptor *appsv1.ServiceDescriptor, phase appsv1.Phase) error { patch := client.MergeFrom(serviceDescriptor.DeepCopy()) serviceDescriptor.Status.Phase = phase serviceDescriptor.Status.ObservedGeneration = serviceDescriptor.Generation diff --git a/controllers/apps/servicedescriptor_controller_test.go b/controllers/apps/servicedescriptor_controller_test.go index 7603fd10c00..81975e963b2 100644 --- a/controllers/apps/servicedescriptor_controller_test.go +++ b/controllers/apps/servicedescriptor_controller_test.go @@ -27,7 +27,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/client" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" testapps "github.com/apecloud/kubeblocks/pkg/testutil/apps" ) @@ -56,17 +56,17 @@ var _ = Describe("test ServiceDescriptor controller", func() { It("test ServiceDescriptor controller", func() { By("create a ServiceDescriptor obj") - endpoint := appsv1alpha1.CredentialVar{ + endpoint := appsv1.CredentialVar{ Value: "mock-endpoint", } - port := appsv1alpha1.CredentialVar{ + port := appsv1.CredentialVar{ Value: "mock-port", } - auth := appsv1alpha1.ConnectionCredentialAuth{ - Username: &appsv1alpha1.CredentialVar{ + auth := appsv1.ConnectionCredentialAuth{ + Username: &appsv1.CredentialVar{ Value: "mock-username", }, - Password: &appsv1alpha1.CredentialVar{ + Password: &appsv1.CredentialVar{ Value: "mock-password", }, } @@ -81,14 +81,14 @@ var _ = Describe("test ServiceDescriptor controller", func() { By("wait for ServiceDescriptor phase is available when serviceDescriptor is valid") Eventually(testapps.CheckObj(&testCtx, client.ObjectKeyFromObject(validServiceDescriptor), - func(g Gomega, tmpSCC *appsv1alpha1.ServiceDescriptor) { - g.Expect(tmpSCC.Status.Phase).Should(Equal(appsv1alpha1.AvailablePhase)) + func(g Gomega, tmpSCC *appsv1.ServiceDescriptor) { + g.Expect(tmpSCC.Status.Phase).Should(Equal(appsv1.AvailablePhase)) })).Should(Succeed()) invalidSDName := "service-descriptor-invalid-" + randomStr mockSecretRefName := "mock-secret-for-scc" + randomStr - authValueFrom := appsv1alpha1.ConnectionCredentialAuth{ - Username: &appsv1alpha1.CredentialVar{ + authValueFrom := appsv1.ConnectionCredentialAuth{ + Username: &appsv1.CredentialVar{ ValueFrom: &corev1.EnvVarSource{ SecretKeyRef: &corev1.SecretKeySelector{ LocalObjectReference: corev1.LocalObjectReference{ @@ -98,7 +98,7 @@ var _ = Describe("test ServiceDescriptor controller", func() { }, }, }, - Password: &appsv1alpha1.CredentialVar{ + Password: &appsv1.CredentialVar{ ValueFrom: &corev1.EnvVarSource{ SecretKeyRef: &corev1.SecretKeySelector{ LocalObjectReference: corev1.LocalObjectReference{ @@ -118,8 +118,8 @@ var _ = Describe("test ServiceDescriptor controller", func() { Create(&testCtx).GetObject() By("wait for ServiceDescriptor phase is Unavailable because serviceDescriptor secretRef not found") Eventually(testapps.CheckObj(&testCtx, client.ObjectKeyFromObject(invalidServiceDescriptor), - func(g Gomega, tmpSCC *appsv1alpha1.ServiceDescriptor) { - g.Expect(tmpSCC.Status.Phase).Should(Equal(appsv1alpha1.UnavailablePhase)) + func(g Gomega, tmpSCC *appsv1.ServiceDescriptor) { + g.Expect(tmpSCC.Status.Phase).Should(Equal(appsv1.UnavailablePhase)) })).Should(Succeed()) secret := &corev1.Secret{ @@ -135,8 +135,8 @@ var _ = Describe("test ServiceDescriptor controller", func() { Expect(testCtx.CheckedCreateObj(ctx, secret)).Should(Succeed()) By("wait for ServiceDescriptor phase is available because serviceDescriptor secretRef found") Eventually(testapps.CheckObj(&testCtx, client.ObjectKeyFromObject(invalidServiceDescriptor), - func(g Gomega, tmpSCC *appsv1alpha1.ServiceDescriptor) { - g.Expect(tmpSCC.Status.Phase).Should(Equal(appsv1alpha1.AvailablePhase)) + func(g Gomega, tmpSCC *appsv1.ServiceDescriptor) { + g.Expect(tmpSCC.Status.Phase).Should(Equal(appsv1.AvailablePhase)) })).Should(Succeed()) }) }) diff --git a/controllers/apps/suite_test.go b/controllers/apps/suite_test.go index 2d7b04cca72..22194f96919 100644 --- a/controllers/apps/suite_test.go +++ b/controllers/apps/suite_test.go @@ -43,6 +43,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/log/zap" "sigs.k8s.io/controller-runtime/pkg/metrics/server" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" appsv1beta1 "github.com/apecloud/kubeblocks/apis/apps/v1beta1" dpv1alpha1 "github.com/apecloud/kubeblocks/apis/dataprotection/v1alpha1" @@ -129,6 +130,10 @@ var _ = BeforeSuite(func() { Expect(err).NotTo(HaveOccurred()) model.AddScheme(appsv1beta1.AddToScheme) + err = appsv1.AddToScheme(scheme.Scheme) + Expect(err).NotTo(HaveOccurred()) + model.AddScheme(appsv1.AddToScheme) + err = dpv1alpha1.AddToScheme(scheme.Scheme) Expect(err).NotTo(HaveOccurred()) model.AddScheme(dpv1alpha1.AddToScheme) diff --git a/deploy/helm/crds/apps.kubeblocks.io_servicedescriptors.yaml b/deploy/helm/crds/apps.kubeblocks.io_servicedescriptors.yaml index 7be8abce397..99d33d9eaff 100644 --- a/deploy/helm/crds/apps.kubeblocks.io_servicedescriptors.yaml +++ b/deploy/helm/crds/apps.kubeblocks.io_servicedescriptors.yaml @@ -20,6 +20,673 @@ spec: singular: servicedescriptor scope: Namespaced versions: + - additionalPrinterColumns: + - description: service kind + jsonPath: .spec.serviceKind + name: SERVICE_KIND + type: string + - description: service version + jsonPath: .spec.serviceVersion + name: SERVICE_VERSION + type: string + - description: status phase + jsonPath: .status.phase + name: STATUS + type: string + - jsonPath: .metadata.creationTimestamp + name: AGE + type: date + name: v1 + schema: + openAPIV3Schema: + description: |- + ServiceDescriptor describes a service provided by external sources. + It contains the necessary details such as the service's address and connection credentials. + To enable a Cluster to access this service, the ServiceDescriptor's name should be specified + in the Cluster configuration under `clusterComponent.serviceRefs[*].serviceDescriptor`. + 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: ServiceDescriptorSpec defines the desired state of ServiceDescriptor + properties: + auth: + description: Specifies the authentication credentials required for + accessing an external service. + properties: + password: + description: Specifies the password for the external service. + properties: + value: + description: |- + Holds a direct string or an expression that can be evaluated to a string. + + + It can include variables denoted by $(VAR_NAME). + These variables are expanded to the value of the environment variables defined in the container. + If a variable cannot be resolved, it remains unchanged in the output. + + + To escape variable expansion and retain the literal value, use double $ characters. + + + For example: + + + - "$(VAR_NAME)" will be expanded to the value of the environment variable VAR_NAME. + - "$$(VAR_NAME)" will result in "$(VAR_NAME)" in the output, without any variable expansion. + + + Default value is an empty string. + type: string + valueFrom: + description: Specifies the source for the variable's value. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the FieldPath is + written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the specified + API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the exposed + resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in the pod's namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + username: + description: Specifies the username for the external service. + properties: + value: + description: |- + Holds a direct string or an expression that can be evaluated to a string. + + + It can include variables denoted by $(VAR_NAME). + These variables are expanded to the value of the environment variables defined in the container. + If a variable cannot be resolved, it remains unchanged in the output. + + + To escape variable expansion and retain the literal value, use double $ characters. + + + For example: + + + - "$(VAR_NAME)" will be expanded to the value of the environment variable VAR_NAME. + - "$$(VAR_NAME)" will result in "$(VAR_NAME)" in the output, without any variable expansion. + + + Default value is an empty string. + type: string + valueFrom: + description: Specifies the source for the variable's value. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the FieldPath is + written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the specified + API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the exposed + resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in the pod's namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + type: object + endpoint: + description: |- + Specifies the endpoint of the external service. + + + If the service is exposed via a cluster, the endpoint will be provided in the format of `host:port`. + properties: + value: + description: |- + Holds a direct string or an expression that can be evaluated to a string. + + + It can include variables denoted by $(VAR_NAME). + These variables are expanded to the value of the environment variables defined in the container. + If a variable cannot be resolved, it remains unchanged in the output. + + + To escape variable expansion and retain the literal value, use double $ characters. + + + For example: + + + - "$(VAR_NAME)" will be expanded to the value of the environment variable VAR_NAME. + - "$$(VAR_NAME)" will result in "$(VAR_NAME)" in the output, without any variable expansion. + + + Default value is an empty string. + type: string + valueFrom: + description: Specifies the source for the variable's value. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the FieldPath is written + in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the specified + API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required for volumes, optional + for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the exposed + resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in the pod's namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must + be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + host: + description: Specifies the service or IP address of the external service. + properties: + value: + description: |- + Holds a direct string or an expression that can be evaluated to a string. + + + It can include variables denoted by $(VAR_NAME). + These variables are expanded to the value of the environment variables defined in the container. + If a variable cannot be resolved, it remains unchanged in the output. + + + To escape variable expansion and retain the literal value, use double $ characters. + + + For example: + + + - "$(VAR_NAME)" will be expanded to the value of the environment variable VAR_NAME. + - "$$(VAR_NAME)" will result in "$(VAR_NAME)" in the output, without any variable expansion. + + + Default value is an empty string. + type: string + valueFrom: + description: Specifies the source for the variable's value. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the FieldPath is written + in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the specified + API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required for volumes, optional + for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the exposed + resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in the pod's namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must + be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + port: + description: Specifies the port of the external service. + properties: + value: + description: |- + Holds a direct string or an expression that can be evaluated to a string. + + + It can include variables denoted by $(VAR_NAME). + These variables are expanded to the value of the environment variables defined in the container. + If a variable cannot be resolved, it remains unchanged in the output. + + + To escape variable expansion and retain the literal value, use double $ characters. + + + For example: + + + - "$(VAR_NAME)" will be expanded to the value of the environment variable VAR_NAME. + - "$$(VAR_NAME)" will result in "$(VAR_NAME)" in the output, without any variable expansion. + + + Default value is an empty string. + type: string + valueFrom: + description: Specifies the source for the variable's value. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the FieldPath is written + in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the specified + API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required for volumes, optional + for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the exposed + resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in the pod's namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must + be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + serviceKind: + description: |- + Describes the type of database service provided by the external service. + For example, "mysql", "redis", "mongodb". + This field categorizes databases by their functionality, protocol and compatibility, facilitating appropriate + service integration based on their unique capabilities. + + + This field is case-insensitive. + + + It also supports abbreviations for some well-known databases: + - "pg", "pgsql", "postgres", "postgresql": PostgreSQL service + - "zk", "zookeeper": ZooKeeper service + - "es", "elasticsearch": Elasticsearch service + - "mongo", "mongodb": MongoDB service + - "ch", "clickhouse": ClickHouse service + type: string + serviceVersion: + description: |- + Describes the version of the service provided by the external service. + This is crucial for ensuring compatibility between different components of the system, + as different versions of a service may have varying features. + type: string + required: + - serviceKind + - serviceVersion + type: object + status: + description: ServiceDescriptorStatus defines the observed state of ServiceDescriptor + properties: + message: + description: Provides a human-readable explanation detailing the reason + for the current phase of the ServiceConnectionCredential. + type: string + observedGeneration: + description: Represents the generation number that has been processed + by the controller. + format: int64 + type: integer + phase: + description: Indicates the current lifecycle phase of the ServiceDescriptor. + This can be either 'Available' or 'Unavailable'. + enum: + - Available + - Unavailable + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} - additionalPrinterColumns: - description: service kind jsonPath: .spec.serviceKind @@ -684,6 +1351,6 @@ spec: type: object type: object served: true - storage: true + storage: false subresources: status: {} diff --git a/docs/developer_docs/api-reference/cluster.md b/docs/developer_docs/api-reference/cluster.md index a023352644a..f18a39eb21a 100644 --- a/docs/developer_docs/api-reference/cluster.md +++ b/docs/developer_docs/api-reference/cluster.md @@ -9,6 +9,9 @@ sidebar_label: Cluster

Packages:

+

apps.kubeblocks.io/v1

+
+
+Resource Types: + +

ServiceDescriptor +

+
+

ServiceDescriptor describes a service provided by external sources. +It contains the necessary details such as the service’s address and connection credentials. +To enable a Cluster to access this service, the ServiceDescriptor’s name should be specified +in the Cluster configuration under clusterComponent.serviceRefs[*].serviceDescriptor.

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+apiVersion
+string
+apps.kubeblocks.io/v1 +
+kind
+string +
ServiceDescriptor
+metadata
+ + +Kubernetes meta/v1.ObjectMeta + + +
+Refer to the Kubernetes API documentation for the fields of the +metadata field. +
+spec
+ + +ServiceDescriptorSpec + + +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+serviceKind
+ +string + +
+

Describes the type of database service provided by the external service. +For example, “mysql”, “redis”, “mongodb”. +This field categorizes databases by their functionality, protocol and compatibility, facilitating appropriate +service integration based on their unique capabilities.

+

This field is case-insensitive.

+

It also supports abbreviations for some well-known databases: +- “pg”, “pgsql”, “postgres”, “postgresql”: PostgreSQL service +- “zk”, “zookeeper”: ZooKeeper service +- “es”, “elasticsearch”: Elasticsearch service +- “mongo”, “mongodb”: MongoDB service +- “ch”, “clickhouse”: ClickHouse service

+
+serviceVersion
+ +string + +
+

Describes the version of the service provided by the external service. +This is crucial for ensuring compatibility between different components of the system, +as different versions of a service may have varying features.

+
+endpoint
+ + +CredentialVar + + +
+(Optional) +

Specifies the endpoint of the external service.

+

If the service is exposed via a cluster, the endpoint will be provided in the format of host:port.

+
+host
+ + +CredentialVar + + +
+(Optional) +

Specifies the service or IP address of the external service.

+
+port
+ + +CredentialVar + + +
+(Optional) +

Specifies the port of the external service.

+
+auth
+ + +ConnectionCredentialAuth + + +
+(Optional) +

Specifies the authentication credentials required for accessing an external service.

+
+
+status
+ + +ServiceDescriptorStatus + + +
+
+

ConnectionCredentialAuth +

+

+(Appears on:ServiceDescriptorSpec) +

+
+

ConnectionCredentialAuth specifies the authentication credentials required for accessing an external service.

+
+ + + + + + + + + + + + + + + + + +
FieldDescription
+username
+ + +CredentialVar + + +
+(Optional) +

Specifies the username for the external service.

+
+password
+ + +CredentialVar + + +
+(Optional) +

Specifies the password for the external service.

+
+

CredentialVar +

+

+(Appears on:ConnectionCredentialAuth, ServiceDescriptorSpec) +

+
+

CredentialVar represents a variable that retrieves its value either directly from a specified expression +or from a source defined in valueFrom. +Only one of these options may be used at a time.

+
+ + + + + + + + + + + + + + + + + +
FieldDescription
+value
+ +string + +
+(Optional) +

Holds a direct string or an expression that can be evaluated to a string.

+

It can include variables denoted by $(VAR_NAME). +These variables are expanded to the value of the environment variables defined in the container. +If a variable cannot be resolved, it remains unchanged in the output.

+

To escape variable expansion and retain the literal value, use double $ characters.

+

For example:

+
    +
  • ”$(VAR_NAME)” will be expanded to the value of the environment variable VAR_NAME.
  • +
  • ”$$(VAR_NAME)” will result in “$(VAR_NAME)” in the output, without any variable expansion.
  • +
+

Default value is an empty string.

+
+valueFrom
+ + +Kubernetes core/v1.EnvVarSource + + +
+(Optional) +

Specifies the source for the variable’s value.

+
+

Phase +(string alias)

+

+(Appears on:ServiceDescriptorStatus) +

+
+

Phase represents the status of a CR.

+
+ + + + + + + + + + + + +
ValueDescription

"Available"

AvailablePhase indicates that a CR is in an available state.

+

"Unavailable"

UnavailablePhase indicates that a CR is in an unavailable state.

+
+

ServiceDescriptorSpec +

+

+(Appears on:ServiceDescriptor) +

+
+

ServiceDescriptorSpec defines the desired state of ServiceDescriptor

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+serviceKind
+ +string + +
+

Describes the type of database service provided by the external service. +For example, “mysql”, “redis”, “mongodb”. +This field categorizes databases by their functionality, protocol and compatibility, facilitating appropriate +service integration based on their unique capabilities.

+

This field is case-insensitive.

+

It also supports abbreviations for some well-known databases: +- “pg”, “pgsql”, “postgres”, “postgresql”: PostgreSQL service +- “zk”, “zookeeper”: ZooKeeper service +- “es”, “elasticsearch”: Elasticsearch service +- “mongo”, “mongodb”: MongoDB service +- “ch”, “clickhouse”: ClickHouse service

+
+serviceVersion
+ +string + +
+

Describes the version of the service provided by the external service. +This is crucial for ensuring compatibility between different components of the system, +as different versions of a service may have varying features.

+
+endpoint
+ + +CredentialVar + + +
+(Optional) +

Specifies the endpoint of the external service.

+

If the service is exposed via a cluster, the endpoint will be provided in the format of host:port.

+
+host
+ + +CredentialVar + + +
+(Optional) +

Specifies the service or IP address of the external service.

+
+port
+ + +CredentialVar + + +
+(Optional) +

Specifies the port of the external service.

+
+auth
+ + +ConnectionCredentialAuth + + +
+(Optional) +

Specifies the authentication credentials required for accessing an external service.

+
+

ServiceDescriptorStatus +

+

+(Appears on:ServiceDescriptor) +

+
+

ServiceDescriptorStatus defines the observed state of ServiceDescriptor

+
+ + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+observedGeneration
+ +int64 + +
+(Optional) +

Represents the generation number that has been processed by the controller.

+
+phase
+ + +Phase + + +
+(Optional) +

Indicates the current lifecycle phase of the ServiceDescriptor. This can be either ‘Available’ or ‘Unavailable’.

+
+message
+ +string + +
+(Optional) +

Provides a human-readable explanation detailing the reason for the current phase of the ServiceConnectionCredential.

+
+

apps.kubeblocks.io/v1alpha1

diff --git a/pkg/controller/builder/builder_service_descriptor.go b/pkg/controller/builder/builder_service_descriptor.go index 9674b0ac029..422fc388a53 100644 --- a/pkg/controller/builder/builder_service_descriptor.go +++ b/pkg/controller/builder/builder_service_descriptor.go @@ -20,16 +20,16 @@ along with this program. If not, see . package builder import ( - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" ) type ServiceDescriptorBuilder struct { - BaseBuilder[appsv1alpha1.ServiceDescriptor, *appsv1alpha1.ServiceDescriptor, ServiceDescriptorBuilder] + BaseBuilder[appsv1.ServiceDescriptor, *appsv1.ServiceDescriptor, ServiceDescriptorBuilder] } func NewServiceDescriptorBuilder(namespace, name string) *ServiceDescriptorBuilder { builder := &ServiceDescriptorBuilder{} - builder.init(namespace, name, &appsv1alpha1.ServiceDescriptor{}, builder) + builder.init(namespace, name, &appsv1.ServiceDescriptor{}, builder) return builder } @@ -43,40 +43,40 @@ func (builder *ServiceDescriptorBuilder) SetServiceVersion(serviceVersion string return builder } -func (builder *ServiceDescriptorBuilder) SetEndpoint(endpoint appsv1alpha1.CredentialVar) *ServiceDescriptorBuilder { +func (builder *ServiceDescriptorBuilder) SetEndpoint(endpoint appsv1.CredentialVar) *ServiceDescriptorBuilder { builder.get().Spec.Endpoint = &endpoint return builder } -func (builder *ServiceDescriptorBuilder) SetHost(host appsv1alpha1.CredentialVar) *ServiceDescriptorBuilder { +func (builder *ServiceDescriptorBuilder) SetHost(host appsv1.CredentialVar) *ServiceDescriptorBuilder { builder.get().Spec.Host = &host return builder } -func (builder *ServiceDescriptorBuilder) SetPort(port appsv1alpha1.CredentialVar) *ServiceDescriptorBuilder { +func (builder *ServiceDescriptorBuilder) SetPort(port appsv1.CredentialVar) *ServiceDescriptorBuilder { builder.get().Spec.Port = &port return builder } -func (builder *ServiceDescriptorBuilder) SetAuth(auth appsv1alpha1.ConnectionCredentialAuth) *ServiceDescriptorBuilder { +func (builder *ServiceDescriptorBuilder) SetAuth(auth appsv1.ConnectionCredentialAuth) *ServiceDescriptorBuilder { builder.get().Spec.Auth = &auth return builder } -func (builder *ServiceDescriptorBuilder) SetAuthUsername(username appsv1alpha1.CredentialVar) *ServiceDescriptorBuilder { +func (builder *ServiceDescriptorBuilder) SetAuthUsername(username appsv1.CredentialVar) *ServiceDescriptorBuilder { auth := builder.get().Spec.Auth if auth == nil { - auth = &appsv1alpha1.ConnectionCredentialAuth{} + auth = &appsv1.ConnectionCredentialAuth{} } auth.Username = &username builder.get().Spec.Auth = auth return builder } -func (builder *ServiceDescriptorBuilder) SetAuthPassword(password appsv1alpha1.CredentialVar) *ServiceDescriptorBuilder { +func (builder *ServiceDescriptorBuilder) SetAuthPassword(password appsv1.CredentialVar) *ServiceDescriptorBuilder { auth := builder.get().Spec.Auth if auth == nil { - auth = &appsv1alpha1.ConnectionCredentialAuth{} + auth = &appsv1.ConnectionCredentialAuth{} } auth.Password = &password builder.get().Spec.Auth = auth diff --git a/pkg/controller/builder/builder_service_descriptor_test.go b/pkg/controller/builder/builder_service_descriptor_test.go index 7f97e0b691f..4a400b67eb2 100644 --- a/pkg/controller/builder/builder_service_descriptor_test.go +++ b/pkg/controller/builder/builder_service_descriptor_test.go @@ -25,7 +25,7 @@ import ( corev1 "k8s.io/api/core/v1" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" "github.com/apecloud/kubeblocks/pkg/constant" ) @@ -40,13 +40,13 @@ var _ = Describe("service descriptor builder", func() { hostName = "mock-host" secretRefName = "foo" ) - endpoint := appsv1alpha1.CredentialVar{ + endpoint := appsv1.CredentialVar{ Value: endpointName, } - host := appsv1alpha1.CredentialVar{ + host := appsv1.CredentialVar{ Value: hostName, } - port := appsv1alpha1.CredentialVar{ + port := appsv1.CredentialVar{ ValueFrom: &corev1.EnvVarSource{ SecretKeyRef: &corev1.SecretKeySelector{ LocalObjectReference: corev1.LocalObjectReference{Name: secretRefName}, @@ -54,7 +54,7 @@ var _ = Describe("service descriptor builder", func() { }, }, } - username := &appsv1alpha1.CredentialVar{ + username := &appsv1.CredentialVar{ ValueFrom: &corev1.EnvVarSource{ SecretKeyRef: &corev1.SecretKeySelector{ LocalObjectReference: corev1.LocalObjectReference{Name: secretRefName}, @@ -62,7 +62,7 @@ var _ = Describe("service descriptor builder", func() { }, }, } - password := &appsv1alpha1.CredentialVar{ + password := &appsv1.CredentialVar{ ValueFrom: &corev1.EnvVarSource{ SecretKeyRef: &corev1.SecretKeySelector{ LocalObjectReference: corev1.LocalObjectReference{Name: secretRefName}, @@ -71,7 +71,7 @@ var _ = Describe("service descriptor builder", func() { }, } - auth := appsv1alpha1.ConnectionCredentialAuth{ + auth := appsv1.ConnectionCredentialAuth{ Username: username, Password: password, } diff --git a/pkg/controller/component/component_test.go b/pkg/controller/component/component_test.go index 4cc13ce42f5..524431bd018 100644 --- a/pkg/controller/component/component_test.go +++ b/pkg/controller/component/component_test.go @@ -30,6 +30,7 @@ import ( "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" intctrlutil "github.com/apecloud/kubeblocks/pkg/controllerutil" testapps "github.com/apecloud/kubeblocks/pkg/testutil/apps" @@ -78,17 +79,17 @@ var _ = Describe("Component", func() { version = "mock-version" ) By("generate serviceReference") - serviceDescriptor := &appsv1alpha1.ServiceDescriptor{ + serviceDescriptor := &appsv1.ServiceDescriptor{ ObjectMeta: metav1.ObjectMeta{ Name: name, Namespace: ns, }, - Spec: appsv1alpha1.ServiceDescriptorSpec{ + Spec: appsv1.ServiceDescriptorSpec{ ServiceKind: kind, ServiceVersion: version, }, } - serviceReferenceMap := map[string]*appsv1alpha1.ServiceDescriptor{ + serviceReferenceMap := map[string]*appsv1.ServiceDescriptor{ testapps.NginxImage: serviceDescriptor, } By("call build") diff --git a/pkg/controller/component/service_descriptor_utils.go b/pkg/controller/component/service_descriptor_utils.go index ff6db397a73..dcd59b7c258 100644 --- a/pkg/controller/component/service_descriptor_utils.go +++ b/pkg/controller/component/service_descriptor_utils.go @@ -30,6 +30,7 @@ import ( "k8s.io/apimachinery/pkg/types" "sigs.k8s.io/controller-runtime/pkg/client" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" "github.com/apecloud/kubeblocks/pkg/constant" "github.com/apecloud/kubeblocks/pkg/controller/builder" @@ -54,7 +55,7 @@ func buildServiceReferencesWithoutResolve(ctx context.Context, cli client.Reader serviceRefs[serviceRef.Name] = &comp.Spec.ServiceRefs[i] } - serviceReferences := make(map[string]*appsv1alpha1.ServiceDescriptor, len(compDef.Spec.ServiceRefDeclarations)) + serviceReferences := make(map[string]*appsv1.ServiceDescriptor, len(compDef.Spec.ServiceRefDeclarations)) for _, serviceRefDecl := range compDef.Spec.ServiceRefDeclarations { serviceRef, ok := serviceRefs[serviceRefDecl.Name] if !ok { @@ -66,7 +67,7 @@ func buildServiceReferencesWithoutResolve(ctx context.Context, cli client.Reader var ( namespace = synthesizedComp.Namespace - sd *appsv1alpha1.ServiceDescriptor + sd *appsv1.ServiceDescriptor err error ) switch { @@ -90,7 +91,7 @@ func buildServiceReferencesWithoutResolve(ctx context.Context, cli client.Reader } func handleServiceRefFromCluster(ctx context.Context, cli client.Reader, namespace string, - serviceRef appsv1alpha1.ServiceRef, serviceRefDecl appsv1alpha1.ServiceRefDeclaration, legacy bool) (*appsv1alpha1.ServiceDescriptor, error) { + serviceRef appsv1alpha1.ServiceRef, serviceRefDecl appsv1alpha1.ServiceRefDeclaration, legacy bool) (*appsv1.ServiceDescriptor, error) { resolver := referencedVars if legacy { resolver = referencedVars4Legacy @@ -104,7 +105,7 @@ func handleServiceRefFromCluster(ctx context.Context, cli client.Reader, namespa b := builder.NewServiceDescriptorBuilder(namespace, serviceRefDecl.Name). SetServiceVersion(""). SetServiceKind("") - for i, s := range []func(appsv1alpha1.CredentialVar) *builder.ServiceDescriptorBuilder{b.SetEndpoint, b.SetHost, b.SetPort, b.SetAuthUsername, b.SetAuthPassword} { + for i, s := range []func(appsv1.CredentialVar) *builder.ServiceDescriptorBuilder{b.SetEndpoint, b.SetHost, b.SetPort, b.SetAuthUsername, b.SetAuthPassword} { if vars[i] != nil { s(*vars[i]) } @@ -112,9 +113,9 @@ func handleServiceRefFromCluster(ctx context.Context, cli client.Reader, namespa return b.GetObject(), nil } -func referencedVars(ctx context.Context, cli client.Reader, namespace string, serviceRef appsv1alpha1.ServiceRef) ([]*appsv1alpha1.CredentialVar, error) { +func referencedVars(ctx context.Context, cli client.Reader, namespace string, serviceRef appsv1alpha1.ServiceRef) ([]*appsv1.CredentialVar, error) { var ( - vars = []*appsv1alpha1.CredentialVar{nil, nil, nil, nil, nil} + vars = []*appsv1.CredentialVar{nil, nil, nil, nil, nil} err error ) vars[0], vars[1], vars[2], err = referencedServiceVars(ctx, cli, namespace, serviceRef) @@ -129,10 +130,10 @@ func referencedVars(ctx context.Context, cli client.Reader, namespace string, se } func referencedServiceVars(ctx context.Context, cli client.Reader, namespace string, - serviceRef appsv1alpha1.ServiceRef) (*appsv1alpha1.CredentialVar, *appsv1alpha1.CredentialVar, *appsv1alpha1.CredentialVar, error) { + serviceRef appsv1alpha1.ServiceRef) (*appsv1.CredentialVar, *appsv1.CredentialVar, *appsv1.CredentialVar, error) { var ( selector = serviceRef.ClusterServiceSelector - host, port *appsv1alpha1.CredentialVar + host, port *appsv1.CredentialVar obj any err error ) @@ -156,30 +157,30 @@ func referencedServiceVars(ctx context.Context, cli client.Reader, namespace str return nil, nil, nil, err } - host = &appsv1alpha1.CredentialVar{Value: composeHostValueFromServices(obj)} + host = &appsv1.CredentialVar{Value: composeHostValueFromServices(obj)} if p := composePortValueFromServices(obj, selector.Service.Port); p != nil { - port = &appsv1alpha1.CredentialVar{Value: *p} + port = &appsv1.CredentialVar{Value: *p} } - endpoint := func() *appsv1alpha1.CredentialVar { + endpoint := func() *appsv1.CredentialVar { hval := host.Value if port == nil { - return &appsv1alpha1.CredentialVar{Value: hval} + return &appsv1.CredentialVar{Value: hval} } if strings.Contains(hval, ",") { // pod-service, the port value has format: host1:port1,host2,port2,... - return &appsv1alpha1.CredentialVar{Value: port.Value} + return &appsv1.CredentialVar{Value: port.Value} } - return &appsv1alpha1.CredentialVar{Value: fmt.Sprintf("%s:%s", hval, port.Value)} + return &appsv1.CredentialVar{Value: fmt.Sprintf("%s:%s", hval, port.Value)} } return endpoint(), host, port, nil } func referencedCredentialVars(ctx context.Context, cli client.Reader, namespace string, - serviceRef appsv1alpha1.ServiceRef) (*appsv1alpha1.CredentialVar, *appsv1alpha1.CredentialVar, error) { + serviceRef appsv1alpha1.ServiceRef) (*appsv1.CredentialVar, *appsv1.CredentialVar, error) { var ( selector = serviceRef.ClusterServiceSelector - vars = []*appsv1alpha1.CredentialVar{nil, nil} + vars = []*appsv1.CredentialVar{nil, nil} ) if selector.Credential == nil { @@ -201,7 +202,7 @@ func referencedCredentialVars(ctx context.Context, cli client.Reader, namespace for idx, key := range []string{constant.AccountNameForSecret, constant.AccountPasswdForSecret} { if _, ok := secret.Data[key]; ok { if secret.Namespace == namespace { - vars[idx] = &appsv1alpha1.CredentialVar{ + vars[idx] = &appsv1.CredentialVar{ ValueFrom: &corev1.EnvVarSource{ SecretKeyRef: &corev1.SecretKeySelector{ LocalObjectReference: corev1.LocalObjectReference{Name: secret.Name}, @@ -210,7 +211,7 @@ func referencedCredentialVars(ctx context.Context, cli client.Reader, namespace }, } } else { - vars[idx] = &appsv1alpha1.CredentialVar{ + vars[idx] = &appsv1.CredentialVar{ Value: string(secret.Data[key]), } } @@ -219,7 +220,7 @@ func referencedCredentialVars(ctx context.Context, cli client.Reader, namespace return vars[0], vars[1], nil } -func referencedVars4Legacy(ctx context.Context, cli client.Reader, namespace string, serviceRef appsv1alpha1.ServiceRef) ([]*appsv1alpha1.CredentialVar, error) { +func referencedVars4Legacy(ctx context.Context, cli client.Reader, namespace string, serviceRef appsv1alpha1.ServiceRef) ([]*appsv1.CredentialVar, error) { secret := &corev1.Secret{} secretKey := types.NamespacedName{ Namespace: func() string { @@ -235,7 +236,7 @@ func referencedVars4Legacy(ctx context.Context, cli client.Reader, namespace str return nil, err } - vars := []*appsv1alpha1.CredentialVar{nil, nil, nil, nil, nil} + vars := []*appsv1.CredentialVar{nil, nil, nil, nil, nil} keys := []string{ constant.ServiceDescriptorEndpointKey, constant.ServiceDescriptorHostKey, @@ -249,7 +250,7 @@ func referencedVars4Legacy(ctx context.Context, cli client.Reader, namespace str continue } if _, ok := secret.Data[key]; ok { - vars[idx] = &appsv1alpha1.CredentialVar{ + vars[idx] = &appsv1.CredentialVar{ ValueFrom: &corev1.EnvVarSource{ SecretKeyRef: &corev1.SecretKeySelector{ LocalObjectReference: corev1.LocalObjectReference{Name: secret.Name}, @@ -264,9 +265,9 @@ func referencedVars4Legacy(ctx context.Context, cli client.Reader, namespace str // handleServiceRefFromServiceDescriptor handles the service reference is provided by external ServiceDescriptor object. func handleServiceRefFromServiceDescriptor(ctx context.Context, cli client.Reader, namespace string, - serviceRef appsv1alpha1.ServiceRef, serviceRefDecl appsv1alpha1.ServiceRefDeclaration) (*appsv1alpha1.ServiceDescriptor, error) { + serviceRef appsv1alpha1.ServiceRef, serviceRefDecl appsv1alpha1.ServiceRefDeclaration) (*appsv1.ServiceDescriptor, error) { // verify service kind and version - verifyServiceKindAndVersion := func(serviceDescriptor appsv1alpha1.ServiceDescriptor, _ ...appsv1alpha1.ServiceRefDeclarationSpec) bool { + verifyServiceKindAndVersion := func(serviceDescriptor appsv1.ServiceDescriptor, _ ...appsv1alpha1.ServiceRefDeclarationSpec) bool { for _, serviceRefDeclSpec := range serviceRefDecl.ServiceRefDeclarationSpecs { if getWellKnownServiceKindAliasMapping(serviceRefDeclSpec.ServiceKind) != getWellKnownServiceKindAliasMapping(serviceDescriptor.Spec.ServiceKind) { continue @@ -286,11 +287,11 @@ func handleServiceRefFromServiceDescriptor(ctx context.Context, cli client.Reade Namespace: namespace, Name: serviceRef.ServiceDescriptor, } - serviceDescriptor := &appsv1alpha1.ServiceDescriptor{} + serviceDescriptor := &appsv1.ServiceDescriptor{} if err := cli.Get(ctx, serviceDescriptorKey, serviceDescriptor); err != nil { return nil, err } - if serviceDescriptor.Status.Phase != appsv1alpha1.AvailablePhase { + if serviceDescriptor.Status.Phase != appsv1.AvailablePhase { return nil, fmt.Errorf("service descriptor %s status is not available", serviceDescriptor.Name) } diff --git a/pkg/controller/component/service_reference.go b/pkg/controller/component/service_reference.go index bf8be66971f..c1c945e6978 100644 --- a/pkg/controller/component/service_reference.go +++ b/pkg/controller/component/service_reference.go @@ -26,7 +26,7 @@ import ( "k8s.io/apimachinery/pkg/types" "sigs.k8s.io/controller-runtime/pkg/client" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" ) func resolveServiceReferences(ctx context.Context, cli client.Reader, synthesizedComp *SynthesizedComponent) error { @@ -36,7 +36,7 @@ func resolveServiceReferences(ctx context.Context, cli client.Reader, synthesize continue } // Only support referencing endpoint and port in configuration - credentialVars := []*appsv1alpha1.CredentialVar{ + credentialVars := []*appsv1.CredentialVar{ serviceDescriptor.Spec.Endpoint, serviceDescriptor.Spec.Host, serviceDescriptor.Spec.Port, @@ -51,7 +51,7 @@ func resolveServiceReferences(ctx context.Context, cli client.Reader, synthesize // resolveServiceRefCredentialVars resolves the credentialVar.ValueFrom to the real value // TODO: currently, we set the valueFrom to the value, which need to be refactored func resolveServiceRefCredentialVars(ctx context.Context, cli client.Reader, - namespace string, credentialVars ...*appsv1alpha1.CredentialVar) error { + namespace string, credentialVars ...*appsv1.CredentialVar) error { for _, credentialVar := range credentialVars { // TODO: replace the build-in placeholder with the real value if credentialVar == nil || credentialVar.Value != "" { @@ -71,7 +71,7 @@ func resolveServiceRefCredentialVars(ctx context.Context, cli client.Reader, } func resolveSecretRefCredentialVar(ctx context.Context, cli client.Reader, - namespace string, credentialVar *appsv1alpha1.CredentialVar) error { + namespace string, credentialVar *appsv1.CredentialVar) error { if credentialVar.ValueFrom == nil || credentialVar.ValueFrom.SecretKeyRef == nil { return nil } @@ -93,7 +93,7 @@ func resolveSecretRefCredentialVar(ctx context.Context, cli client.Reader, } func resolveConfigMapRefCredentialVar(ctx context.Context, cli client.Reader, - namespace string, credentialVar *appsv1alpha1.CredentialVar) error { + namespace string, credentialVar *appsv1.CredentialVar) error { if credentialVar.ValueFrom == nil || credentialVar.ValueFrom.ConfigMapKeyRef == nil { return nil } diff --git a/pkg/controller/component/suite_test.go b/pkg/controller/component/suite_test.go index e48d0f23fca..a9dae07f2ce 100644 --- a/pkg/controller/component/suite_test.go +++ b/pkg/controller/component/suite_test.go @@ -39,6 +39,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/log/zap" "sigs.k8s.io/controller-runtime/pkg/metrics/server" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" appsv1beta1 "github.com/apecloud/kubeblocks/apis/apps/v1beta1" dpv1alpha1 "github.com/apecloud/kubeblocks/apis/dataprotection/v1alpha1" @@ -65,6 +66,7 @@ func init() { viper.AutomaticEnv() model.AddScheme(appsv1alpha1.AddToScheme) model.AddScheme(appsv1beta1.AddToScheme) + model.AddScheme(appsv1.AddToScheme) // viper.Set("ENABLE_DEBUG_LOG", "true") viper.SetDefault(constant.KubernetesClusterDomainEnv, constant.DefaultDNSDomain) @@ -111,6 +113,9 @@ var _ = BeforeSuite(func() { err = appsv1beta1.AddToScheme(scheme.Scheme) Expect(err).NotTo(HaveOccurred()) + err = appsv1.AddToScheme(scheme.Scheme) + Expect(err).NotTo(HaveOccurred()) + err = dpv1alpha1.AddToScheme(scheme.Scheme) Expect(err).NotTo(HaveOccurred()) diff --git a/pkg/controller/component/type.go b/pkg/controller/component/type.go index 32e8a957230..1c99de3dd78 100644 --- a/pkg/controller/component/type.go +++ b/pkg/controller/component/type.go @@ -25,7 +25,8 @@ import ( rbacv1 "k8s.io/api/rbac/v1" "k8s.io/apimachinery/pkg/util/intstr" - "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" + kbappsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" + appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" ) @@ -44,35 +45,35 @@ type SynthesizedComponent struct { Resources corev1.ResourceRequirements `json:"resources,omitempty"` PodSpec *corev1.PodSpec `json:"podSpec,omitempty"` VolumeClaimTemplates []corev1.PersistentVolumeClaimTemplate `json:"volumeClaimTemplates,omitempty"` - LogConfigs []v1alpha1.LogConfig `json:"logConfigs,omitempty"` - ConfigTemplates []v1alpha1.ComponentConfigSpec `json:"configTemplates,omitempty"` - ScriptTemplates []v1alpha1.ComponentTemplateSpec `json:"scriptTemplates,omitempty"` - TLSConfig *v1alpha1.TLSConfig `json:"tlsConfig"` + LogConfigs []appsv1alpha1.LogConfig `json:"logConfigs,omitempty"` + ConfigTemplates []appsv1alpha1.ComponentConfigSpec `json:"configTemplates,omitempty"` + ScriptTemplates []appsv1alpha1.ComponentTemplateSpec `json:"scriptTemplates,omitempty"` + TLSConfig *appsv1alpha1.TLSConfig `json:"tlsConfig"` ServiceAccountName string `json:"serviceAccountName,omitempty"` - ServiceReferences map[string]*v1alpha1.ServiceDescriptor `json:"serviceReferences,omitempty"` + ServiceReferences map[string]*kbappsv1.ServiceDescriptor `json:"serviceReferences,omitempty"` UserDefinedLabels map[string]string UserDefinedAnnotations map[string]string - TemplateVars map[string]any `json:"templateVars,omitempty"` - EnvVars []corev1.EnvVar `json:"envVars,omitempty"` - EnvFromSources []corev1.EnvFromSource `json:"envFromSources,omitempty"` - Instances []v1alpha1.InstanceTemplate `json:"instances,omitempty"` - OfflineInstances []string `json:"offlineInstances,omitempty"` - Roles []v1alpha1.ReplicaRole `json:"roles,omitempty"` - Labels map[string]string `json:"labels,omitempty"` - Annotations map[string]string `json:"annotations,omitempty"` - UpdateStrategy *v1alpha1.UpdateStrategy `json:"updateStrategy,omitempty"` - PodManagementPolicy *appsv1.PodManagementPolicyType `json:"podManagementPolicy,omitempty"` - ParallelPodManagementConcurrency *intstr.IntOrString `json:"parallelPodManagementConcurrency,omitempty"` - PodUpdatePolicy *workloads.PodUpdatePolicyType `json:"podUpdatePolicy,omitempty"` - PolicyRules []rbacv1.PolicyRule `json:"policyRules,omitempty"` - LifecycleActions *v1alpha1.ComponentLifecycleActions `json:"lifecycleActions,omitempty"` - SystemAccounts []v1alpha1.SystemAccount `json:"systemAccounts,omitempty"` - Volumes []v1alpha1.ComponentVolume `json:"volumes,omitempty"` - HostNetwork *v1alpha1.HostNetwork `json:"hostNetwork,omitempty"` - ComponentServices []v1alpha1.ComponentService `json:"componentServices,omitempty"` - MinReadySeconds int32 `json:"minReadySeconds,omitempty"` - Sidecars []string `json:"sidecars,omitempty"` - DisableExporter *bool `json:"disableExporter,omitempty"` + TemplateVars map[string]any `json:"templateVars,omitempty"` + EnvVars []corev1.EnvVar `json:"envVars,omitempty"` + EnvFromSources []corev1.EnvFromSource `json:"envFromSources,omitempty"` + Instances []appsv1alpha1.InstanceTemplate `json:"instances,omitempty"` + OfflineInstances []string `json:"offlineInstances,omitempty"` + Roles []appsv1alpha1.ReplicaRole `json:"roles,omitempty"` + Labels map[string]string `json:"labels,omitempty"` + Annotations map[string]string `json:"annotations,omitempty"` + UpdateStrategy *appsv1alpha1.UpdateStrategy `json:"updateStrategy,omitempty"` + PodManagementPolicy *appsv1.PodManagementPolicyType `json:"podManagementPolicy,omitempty"` + ParallelPodManagementConcurrency *intstr.IntOrString `json:"parallelPodManagementConcurrency,omitempty"` + PodUpdatePolicy *workloads.PodUpdatePolicyType `json:"podUpdatePolicy,omitempty"` + PolicyRules []rbacv1.PolicyRule `json:"policyRules,omitempty"` + LifecycleActions *appsv1alpha1.ComponentLifecycleActions `json:"lifecycleActions,omitempty"` + SystemAccounts []appsv1alpha1.SystemAccount `json:"systemAccounts,omitempty"` + Volumes []appsv1alpha1.ComponentVolume `json:"volumes,omitempty"` + HostNetwork *appsv1alpha1.HostNetwork `json:"hostNetwork,omitempty"` + ComponentServices []appsv1alpha1.ComponentService `json:"componentServices,omitempty"` + MinReadySeconds int32 `json:"minReadySeconds,omitempty"` + Sidecars []string `json:"sidecars,omitempty"` + DisableExporter *bool `json:"disableExporter,omitempty"` Stop *bool // TODO(xingran): The following fields will be deprecated after KubeBlocks version 0.8.0 diff --git a/pkg/controller/component/vars.go b/pkg/controller/component/vars.go index 20a16cab2d2..644404e300f 100644 --- a/pkg/controller/component/vars.go +++ b/pkg/controller/component/vars.go @@ -39,6 +39,7 @@ import ( "k8s.io/apimachinery/pkg/util/sets" "sigs.k8s.io/controller-runtime/pkg/client" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" "github.com/apecloud/kubeblocks/pkg/common" @@ -932,7 +933,7 @@ func resolveServiceRefVarRef(ctx context.Context, cli client.Reader, synthesized func resolveServiceRefEndpointRef(ctx context.Context, cli client.Reader, synthesizedComp *SynthesizedComponent, defineKey string, selector appsv1alpha1.ServiceRefVarSelector) ([]*corev1.EnvVar, []*corev1.EnvVar, error) { resolveEndpoint := func(obj any) (*corev1.EnvVar, *corev1.EnvVar, error) { - sd := obj.(*appsv1alpha1.ServiceDescriptor) + sd := obj.(*appsv1.ServiceDescriptor) if sd.Spec.Endpoint == nil { return nil, nil, nil } @@ -947,7 +948,7 @@ func resolveServiceRefEndpointRef(ctx context.Context, cli client.Reader, synthe func resolveServiceRefHostRef(ctx context.Context, cli client.Reader, synthesizedComp *SynthesizedComponent, defineKey string, selector appsv1alpha1.ServiceRefVarSelector) ([]*corev1.EnvVar, []*corev1.EnvVar, error) { resolveHost := func(obj any) (*corev1.EnvVar, *corev1.EnvVar, error) { - sd := obj.(*appsv1alpha1.ServiceDescriptor) + sd := obj.(*appsv1.ServiceDescriptor) if sd.Spec.Host == nil { return nil, nil, nil } @@ -962,7 +963,7 @@ func resolveServiceRefHostRef(ctx context.Context, cli client.Reader, synthesize func resolveServiceRefPortRef(ctx context.Context, cli client.Reader, synthesizedComp *SynthesizedComponent, defineKey string, selector appsv1alpha1.ServiceRefVarSelector) ([]*corev1.EnvVar, []*corev1.EnvVar, error) { resolvePort := func(obj any) (*corev1.EnvVar, *corev1.EnvVar, error) { - sd := obj.(*appsv1alpha1.ServiceDescriptor) + sd := obj.(*appsv1.ServiceDescriptor) if sd.Spec.Port == nil { return nil, nil, nil } @@ -977,7 +978,7 @@ func resolveServiceRefPortRef(ctx context.Context, cli client.Reader, synthesize func resolveServiceRefUsernameRef(ctx context.Context, cli client.Reader, synthesizedComp *SynthesizedComponent, defineKey string, selector appsv1alpha1.ServiceRefVarSelector) ([]*corev1.EnvVar, []*corev1.EnvVar, error) { resolveUsername := func(obj any) (*corev1.EnvVar, *corev1.EnvVar, error) { - sd := obj.(*appsv1alpha1.ServiceDescriptor) + sd := obj.(*appsv1.ServiceDescriptor) if sd.Spec.Auth == nil || sd.Spec.Auth.Username == nil { return nil, nil, nil } @@ -994,7 +995,7 @@ func resolveServiceRefUsernameRef(ctx context.Context, cli client.Reader, synthe func resolveServiceRefPasswordRef(ctx context.Context, cli client.Reader, synthesizedComp *SynthesizedComponent, defineKey string, selector appsv1alpha1.ServiceRefVarSelector) ([]*corev1.EnvVar, []*corev1.EnvVar, error) { resolvePassword := func(obj any) (*corev1.EnvVar, *corev1.EnvVar, error) { - sd := obj.(*appsv1alpha1.ServiceDescriptor) + sd := obj.(*appsv1.ServiceDescriptor) if sd.Spec.Auth == nil || sd.Spec.Auth.Password == nil { return nil, nil, nil } diff --git a/pkg/controller/component/vars_test.go b/pkg/controller/component/vars_test.go index e6837d21616..4d98b153dcb 100644 --- a/pkg/controller/component/vars_test.go +++ b/pkg/controller/component/vars_test.go @@ -33,6 +33,7 @@ import ( "k8s.io/apimachinery/pkg/util/uuid" "sigs.k8s.io/controller-runtime/pkg/client" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" "github.com/apecloud/kubeblocks/pkg/constant" ) @@ -1573,29 +1574,29 @@ var _ = Describe("vars", func() { }, }, } - synthesizedComp.ServiceReferences = map[string]*appsv1alpha1.ServiceDescriptor{ + synthesizedComp.ServiceReferences = map[string]*appsv1.ServiceDescriptor{ "serviceref": { ObjectMeta: metav1.ObjectMeta{ Namespace: testCtx.DefaultNamespace, Name: "serviceref", }, - Spec: appsv1alpha1.ServiceDescriptorSpec{ + Spec: appsv1.ServiceDescriptorSpec{ ServiceKind: "", ServiceVersion: "", - Endpoint: &appsv1alpha1.CredentialVar{ + Endpoint: &appsv1.CredentialVar{ Value: "endpoint", }, - Host: &appsv1alpha1.CredentialVar{ + Host: &appsv1.CredentialVar{ Value: "host", }, - Port: &appsv1alpha1.CredentialVar{ + Port: &appsv1.CredentialVar{ Value: "port", }, - Auth: &appsv1alpha1.ConnectionCredentialAuth{ - Username: &appsv1alpha1.CredentialVar{ + Auth: &appsv1.ConnectionCredentialAuth{ + Username: &appsv1.CredentialVar{ Value: "username", }, - Password: &appsv1alpha1.CredentialVar{ + Password: &appsv1.CredentialVar{ Value: "password", }, }, diff --git a/pkg/testutil/apps/servicedescriptor_factory.go b/pkg/testutil/apps/servicedescriptor_factory.go index 40edaa17bfc..879061b24c3 100644 --- a/pkg/testutil/apps/servicedescriptor_factory.go +++ b/pkg/testutil/apps/servicedescriptor_factory.go @@ -22,25 +22,25 @@ package apps import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" "github.com/apecloud/kubeblocks/pkg/constant" ) type MockServiceDescriptorFactory struct { - BaseFactory[appsv1alpha1.ServiceDescriptor, *appsv1alpha1.ServiceDescriptor, MockServiceDescriptorFactory] + BaseFactory[appsv1.ServiceDescriptor, *appsv1.ServiceDescriptor, MockServiceDescriptorFactory] } func NewServiceDescriptorFactory(namespace, name string) *MockServiceDescriptorFactory { f := &MockServiceDescriptorFactory{} f.Init(namespace, name, - &appsv1alpha1.ServiceDescriptor{ + &appsv1.ServiceDescriptor{ ObjectMeta: metav1.ObjectMeta{ Name: name, Labels: map[string]string{ constant.AppManagedByLabelKey: constant.AppName, }, }, - Spec: appsv1alpha1.ServiceDescriptorSpec{}, + Spec: appsv1.ServiceDescriptorSpec{}, }, f) return f } @@ -55,22 +55,22 @@ func (factory *MockServiceDescriptorFactory) SetServiceVersion(serviceVersion st return factory } -func (factory *MockServiceDescriptorFactory) SetEndpoint(endpoint appsv1alpha1.CredentialVar) *MockServiceDescriptorFactory { +func (factory *MockServiceDescriptorFactory) SetEndpoint(endpoint appsv1.CredentialVar) *MockServiceDescriptorFactory { factory.Get().Spec.Endpoint = &endpoint return factory } -func (factory *MockServiceDescriptorFactory) SetHost(host appsv1alpha1.CredentialVar) *MockServiceDescriptorFactory { +func (factory *MockServiceDescriptorFactory) SetHost(host appsv1.CredentialVar) *MockServiceDescriptorFactory { factory.Get().Spec.Host = &host return factory } -func (factory *MockServiceDescriptorFactory) SetPort(port appsv1alpha1.CredentialVar) *MockServiceDescriptorFactory { +func (factory *MockServiceDescriptorFactory) SetPort(port appsv1.CredentialVar) *MockServiceDescriptorFactory { factory.Get().Spec.Port = &port return factory } -func (factory *MockServiceDescriptorFactory) SetAuth(auth appsv1alpha1.ConnectionCredentialAuth) *MockServiceDescriptorFactory { +func (factory *MockServiceDescriptorFactory) SetAuth(auth appsv1.ConnectionCredentialAuth) *MockServiceDescriptorFactory { factory.Get().Spec.Auth = &auth return factory } From 770afaf5c505a6c5c1c17f1b256c17f656751446 Mon Sep 17 00:00:00 2001 From: Leon Date: Thu, 29 Aug 2024 15:15:27 +0800 Subject: [PATCH 02/15] cluster definition v1 --- PROJECT | 16 + apis/apps/v1/clusterdefinition_conversion.go | 22 + apis/apps/v1/clusterdefinition_types.go | 191 +++++++++ apis/apps/v1/clusterdefinition_webhook.go | 79 ++++ apis/apps/v1/register.go | 29 ++ apis/apps/v1/webhook_suite_test.go | 5 +- apis/apps/v1/zz_generated.deepcopy.go | 166 ++++++++ .../v1alpha1/clusterdefinition_conversion.go | 148 +++++++ .../v1alpha1/clusterdefinition_webhook.go | 79 ++++ .../v1alpha1/servicedescriptor_conversion.go | 3 +- apis/apps/v1alpha1/webhook_suite_test.go | 5 +- cmd/manager/main.go | 8 + ...apps.kubeblocks.io_clusterdefinitions.yaml | 186 ++++++++- config/samples/apps_v1_clusterdefinition.yaml | 12 + config/webhook/manifests.yaml | 80 ++++ controllers/apps/cluster_controller_test.go | 11 +- controllers/apps/cluster_plan_builder.go | 3 +- .../apps/clusterdefinition_controller.go | 42 +- .../apps/clusterdefinition_controller_test.go | 53 +-- .../transformer_cluster_api_normalization.go | 7 +- .../transformer_cluster_component_test.go | 27 +- .../apps/transformer_cluster_deletion_test.go | 11 +- .../transformer_cluster_load_resources.go | 9 +- ...apps.kubeblocks.io_clusterdefinitions.yaml | 186 ++++++++- docs/developer_docs/api-reference/cluster.md | 387 +++++++++++++++++- hack/client-sdk-gen.sh | 3 +- pkg/client/clientset/versioned/clientset.go | 13 + .../versioned/fake/clientset_generated.go | 7 + .../clientset/versioned/fake/register.go | 2 + .../clientset/versioned/scheme/register.go | 2 + .../versioned/typed/apps/v1/apps_client.go | 112 +++++ .../typed/apps/v1/clusterdefinition.go | 184 +++++++++ .../clientset/versioned/typed/apps/v1/doc.go | 20 + .../versioned/typed/apps/v1/fake/doc.go | 20 + .../typed/apps/v1/fake/fake_apps_client.go | 44 ++ .../apps/v1/fake/fake_clusterdefinition.go | 132 ++++++ .../apps/v1/fake/fake_servicedescriptor.go | 141 +++++++ .../typed/apps/v1/generated_expansion.go | 23 ++ .../typed/apps/v1/servicedescriptor.go | 195 +++++++++ .../externalversions/apps/interface.go | 8 + .../apps/v1/clusterdefinition.go | 89 ++++ .../externalversions/apps/v1/interface.go | 52 +++ .../apps/v1/servicedescriptor.go | 90 ++++ .../informers/externalversions/generic.go | 9 +- .../listers/apps/v1/clusterdefinition.go | 68 +++ .../listers/apps/v1/expansion_generated.go | 31 ++ .../listers/apps/v1/servicedescriptor.go | 99 +++++ pkg/testutil/apps/clusterdef_factory.go | 10 +- 48 files changed, 3025 insertions(+), 94 deletions(-) create mode 100644 apis/apps/v1/clusterdefinition_conversion.go create mode 100644 apis/apps/v1/clusterdefinition_types.go create mode 100644 apis/apps/v1/clusterdefinition_webhook.go create mode 100644 apis/apps/v1/register.go create mode 100644 apis/apps/v1alpha1/clusterdefinition_conversion.go create mode 100644 apis/apps/v1alpha1/clusterdefinition_webhook.go create mode 100644 config/samples/apps_v1_clusterdefinition.yaml create mode 100644 pkg/client/clientset/versioned/typed/apps/v1/apps_client.go create mode 100644 pkg/client/clientset/versioned/typed/apps/v1/clusterdefinition.go create mode 100644 pkg/client/clientset/versioned/typed/apps/v1/doc.go create mode 100644 pkg/client/clientset/versioned/typed/apps/v1/fake/doc.go create mode 100644 pkg/client/clientset/versioned/typed/apps/v1/fake/fake_apps_client.go create mode 100644 pkg/client/clientset/versioned/typed/apps/v1/fake/fake_clusterdefinition.go create mode 100644 pkg/client/clientset/versioned/typed/apps/v1/fake/fake_servicedescriptor.go create mode 100644 pkg/client/clientset/versioned/typed/apps/v1/generated_expansion.go create mode 100644 pkg/client/clientset/versioned/typed/apps/v1/servicedescriptor.go create mode 100644 pkg/client/informers/externalversions/apps/v1/clusterdefinition.go create mode 100644 pkg/client/informers/externalversions/apps/v1/interface.go create mode 100644 pkg/client/informers/externalversions/apps/v1/servicedescriptor.go create mode 100644 pkg/client/listers/apps/v1/clusterdefinition.go create mode 100644 pkg/client/listers/apps/v1/expansion_generated.go create mode 100644 pkg/client/listers/apps/v1/servicedescriptor.go diff --git a/PROJECT b/PROJECT index fcb8e454948..75b844345e6 100644 --- a/PROJECT +++ b/PROJECT @@ -26,6 +26,22 @@ resources: kind: ClusterDefinition path: github.com/apecloud/kubeblocks/apis/apps/v1alpha1 version: v1alpha1 + webhooks: + defaulting: true + validation: true + webhookVersion: v1 +- api: + crdVersion: v1 + controller: true + domain: kubeblocks.io + group: apps + kind: ClusterDefinition + path: github.com/apecloud/kubeblocks/apis/apps/v1 + version: v1 + webhooks: + defaulting: true + validation: true + webhookVersion: v1 - api: crdVersion: v1 controller: true diff --git a/apis/apps/v1/clusterdefinition_conversion.go b/apis/apps/v1/clusterdefinition_conversion.go new file mode 100644 index 00000000000..78dc5ad0729 --- /dev/null +++ b/apis/apps/v1/clusterdefinition_conversion.go @@ -0,0 +1,22 @@ +/* +Copyright (C) 2022-2024 ApeCloud Co., Ltd + +This file is part of KubeBlocks project + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ + +package v1 + +func (r *ClusterDefinition) Hub() {} diff --git a/apis/apps/v1/clusterdefinition_types.go b/apis/apps/v1/clusterdefinition_types.go new file mode 100644 index 00000000000..3ba4ac1bbbf --- /dev/null +++ b/apis/apps/v1/clusterdefinition_types.go @@ -0,0 +1,191 @@ +/* +Copyright (C) 2022-2024 ApeCloud Co., Ltd + +This file is part of KubeBlocks project + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ + +package v1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// +genclient +// +genclient:nonNamespaced +// +k8s:openapi-gen=true +// +kubebuilder:object:root=true +// +kubebuilder:subresource:status +// +kubebuilder:storageversion +// +kubebuilder:resource:categories={kubeblocks},scope=Cluster,shortName=cd +// +kubebuilder:printcolumn:name="Topologies",type="string",JSONPath=".status.topologies",description="topologies" +// +kubebuilder:printcolumn:name="STATUS",type="string",JSONPath=".status.phase",description="status phase" +// +kubebuilder:printcolumn:name="AGE",type="date",JSONPath=".metadata.creationTimestamp" + +// ClusterDefinition defines the topology for databases or storage systems, +// offering a variety of topological configurations to meet diverse deployment needs and scenarios. +// +// It includes a list of Components, each linked to a ComponentDefinition, which enhances reusability and reduce redundancy. +// For example, widely used components such as etcd and Zookeeper can be defined once and reused across multiple ClusterDefinitions, +// simplifying the setup of new systems. +// +// Additionally, ClusterDefinition also specifies the sequence of startup, upgrade, and shutdown for Components, +// ensuring a controlled and predictable management of component lifecycles. +type ClusterDefinition struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec ClusterDefinitionSpec `json:"spec,omitempty"` + Status ClusterDefinitionStatus `json:"status,omitempty"` +} + +// +kubebuilder:object:root=true + +// ClusterDefinitionList contains a list of ClusterDefinition +type ClusterDefinitionList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []ClusterDefinition `json:"items"` +} + +func init() { + SchemeBuilder.Register(&ClusterDefinition{}, &ClusterDefinitionList{}) +} + +// ClusterDefinitionSpec defines the desired state of ClusterDefinition. +type ClusterDefinitionSpec struct { + // Topologies defines all possible topologies within the cluster. + // + // +kubebuilder:validation:MinItems=1 + // +kubebuilder:validation:MaxItems=128 + // +optional + Topologies []ClusterTopology `json:"topologies,omitempty"` +} + +// ClusterDefinitionStatus defines the observed state of ClusterDefinition +type ClusterDefinitionStatus struct { + // Represents the most recent generation observed for this ClusterDefinition. + // + // +optional + ObservedGeneration int64 `json:"observedGeneration,omitempty"` + + // Specifies the current phase of the ClusterDefinition. Valid values are `empty`, `Available`, `Unavailable`. + // When `Available`, the ClusterDefinition is ready and can be referenced by related objects. + Phase Phase `json:"phase,omitempty"` + + // Provides additional information about the current phase. + // + // +optional + Message string `json:"message,omitempty"` + + // Topologies this ClusterDefinition supported. + // + // +optional + Topologies string `json:"topologies,omitempty"` +} + +// ClusterTopology represents the definition for a specific cluster topology. +type ClusterTopology struct { + // Name is the unique identifier for the cluster topology. + // Cannot be updated. + // + // +kubebuilder:validation:Required + // +kubebuilder:validation:MaxLength=32 + Name string `json:"name"` + + // Components specifies the components in the topology. + // + // +kubebuilder:validation:Required + // +kubebuilder:validation:MinItems=1 + // +kubebuilder:validation:MaxItems=128 + Components []ClusterTopologyComponent `json:"components"` + + // Specifies the sequence in which components within a cluster topology are + // started, stopped, and upgraded. + // This ordering is crucial for maintaining the correct dependencies and operational flow across components. + // + // +optional + Orders *ClusterTopologyOrders `json:"orders,omitempty"` + + // Default indicates whether this topology serves as the default configuration. + // When set to true, this topology is automatically used unless another is explicitly specified. + // + // +optional + Default bool `json:"default,omitempty"` +} + +// ClusterTopologyComponent defines a Component within a ClusterTopology. +type ClusterTopologyComponent struct { + // Defines the unique identifier of the component within the cluster topology. + // It follows IANA Service naming rules and is used as part of the Service's DNS name. + // The name must start with a lowercase letter, can contain lowercase letters, numbers, + // and hyphens, and must end with a lowercase letter or number. + // + // Cannot be updated once set. + // + // +kubebuilder:validation:Required + // +kubebuilder:validation:MaxLength=16 + // +kubebuilder:validation:Pattern:=`^[a-z]([a-z0-9\-]*[a-z0-9])?$` + Name string `json:"name"` + + // Specifies the name or prefix of the ComponentDefinition custom resource(CR) that + // defines the Component's characteristics and behavior. + // + // When a prefix is used, the system selects the ComponentDefinition CR with the latest version that matches the prefix. + // This approach allows: + // + // 1. Precise selection by providing the exact name of a ComponentDefinition CR. + // 2. Flexible and automatic selection of the most up-to-date ComponentDefinition CR by specifying a prefix. + // + // Once set, this field cannot be updated. + // + // +kubebuilder:validation:Required + // +kubebuilder:validation:MaxLength=64 + CompDef string `json:"compDef"` +} + +// ClusterTopologyOrders manages the lifecycle of components within a cluster by defining their provisioning, +// terminating, and updating sequences. +// It organizes components into stages or groups, where each group indicates a set of components +// that can be managed concurrently. +// These groups are processed sequentially, allowing precise control based on component dependencies and requirements. +type ClusterTopologyOrders struct { + // Specifies the order for creating and initializing components. + // This is designed for components that depend on one another. Components without dependencies can be grouped together. + // + // Components that can be provisioned independently or have no dependencies can be listed together in the same stage, + // separated by commas. + // + // +optional + Provision []string `json:"provision,omitempty"` + + // Outlines the order for stopping and deleting components. + // This sequence is designed for components that require a graceful shutdown or have interdependencies. + // + // Components that can be terminated independently or have no dependencies can be listed together in the same stage, + // separated by commas. + // + // +optional + Terminate []string `json:"terminate,omitempty"` + + // Update determines the order for updating components' specifications, such as image upgrades or resource scaling. + // This sequence is designed for components that have dependencies or require specific update procedures. + // + // Components that can be updated independently or have no dependencies can be listed together in the same stage, + // separated by commas. + // + // +optional + Update []string `json:"update,omitempty"` +} diff --git a/apis/apps/v1/clusterdefinition_webhook.go b/apis/apps/v1/clusterdefinition_webhook.go new file mode 100644 index 00000000000..8161066c2ba --- /dev/null +++ b/apis/apps/v1/clusterdefinition_webhook.go @@ -0,0 +1,79 @@ +/* +Copyright (C) 2022-2024 ApeCloud Co., Ltd + +This file is part of KubeBlocks project + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ + +package v1 + +import ( + "k8s.io/apimachinery/pkg/runtime" + ctrl "sigs.k8s.io/controller-runtime" + logf "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/webhook" + "sigs.k8s.io/controller-runtime/pkg/webhook/admission" +) + +// log is for logging in this package. +var clusterdefinitionlog = logf.Log.WithName("clusterdefinition-resource") + +func (r *ClusterDefinition) SetupWebhookWithManager(mgr ctrl.Manager) error { + return ctrl.NewWebhookManagedBy(mgr). + For(r). + Complete() +} + +// TODO(user): EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! + +//+kubebuilder:webhook:path=/mutate-apps-kubeblocks-io-v1-clusterdefinition,mutating=true,failurePolicy=fail,sideEffects=None,groups=apps.kubeblocks.io,resources=clusterdefinitions,verbs=create;update,versions=v1,name=mclusterdefinition.kb.io,admissionReviewVersions=v1 + +var _ webhook.Defaulter = &ClusterDefinition{} + +// Default implements webhook.Defaulter so a webhook will be registered for the type +func (r *ClusterDefinition) Default() { + clusterdefinitionlog.Info("default", "name", r.Name) + + // TODO(user): fill in your defaulting logic. +} + +// TODO(user): change verbs to "verbs=create;update;delete" if you want to enable deletion validation. +//+kubebuilder:webhook:path=/validate-apps-kubeblocks-io-v1-clusterdefinition,mutating=false,failurePolicy=fail,sideEffects=None,groups=apps.kubeblocks.io,resources=clusterdefinitions,verbs=create;update,versions=v1,name=vclusterdefinition.kb.io,admissionReviewVersions=v1 + +var _ webhook.Validator = &ClusterDefinition{} + +// ValidateCreate implements webhook.Validator so a webhook will be registered for the type +func (r *ClusterDefinition) ValidateCreate() (warnings admission.Warnings, err error) { + clusterdefinitionlog.Info("validate create", "name", r.Name) + + // TODO(user): fill in your validation logic upon object creation. + return nil, nil +} + +// ValidateUpdate implements webhook.Validator so a webhook will be registered for the type +func (r *ClusterDefinition) ValidateUpdate(old runtime.Object) (warnings admission.Warnings, err error) { + clusterdefinitionlog.Info("validate update", "name", r.Name) + + // TODO(user): fill in your validation logic upon object update. + return nil, nil +} + +// ValidateDelete implements webhook.Validator so a webhook will be registered for the type +func (r *ClusterDefinition) ValidateDelete() (warnings admission.Warnings, err error) { + clusterdefinitionlog.Info("validate delete", "name", r.Name) + + // TODO(user): fill in your validation logic upon object deletion. + return nil, nil +} diff --git a/apis/apps/v1/register.go b/apis/apps/v1/register.go new file mode 100644 index 00000000000..93633c70d4a --- /dev/null +++ b/apis/apps/v1/register.go @@ -0,0 +1,29 @@ +/* +Copyright (C) 2022-2024 ApeCloud Co., Ltd + +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 v1 + +import ( + "k8s.io/apimachinery/pkg/runtime/schema" +) + +// SchemeGroupVersion is group version used to register these objects. +var SchemeGroupVersion = GroupVersion + +// Resource takes an unqualified resource and returns a Group qualified GroupResource +func Resource(resource string) schema.GroupResource { + return SchemeGroupVersion.WithResource(resource).GroupResource() +} diff --git a/apis/apps/v1/webhook_suite_test.go b/apis/apps/v1/webhook_suite_test.go index f55e5a8e905..0c555fbe000 100644 --- a/apis/apps/v1/webhook_suite_test.go +++ b/apis/apps/v1/webhook_suite_test.go @@ -31,8 +31,8 @@ import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" - admissionv1beta1 "k8s.io/api/admission/v1beta1" //+kubebuilder:scaffold:imports + admissionv1beta1 "k8s.io/api/admission/v1beta1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/client-go/rest" ctrl "sigs.k8s.io/controller-runtime" @@ -102,6 +102,9 @@ var _ = BeforeSuite(func() { }) Expect(err).NotTo(HaveOccurred()) + err = (&ClusterDefinition{}).SetupWebhookWithManager(mgr) + Expect(err).NotTo(HaveOccurred()) + err = (&ServiceDescriptor{}).SetupWebhookWithManager(mgr) Expect(err).NotTo(HaveOccurred()) diff --git a/apis/apps/v1/zz_generated.deepcopy.go b/apis/apps/v1/zz_generated.deepcopy.go index 2decbe435dc..8807748259e 100644 --- a/apis/apps/v1/zz_generated.deepcopy.go +++ b/apis/apps/v1/zz_generated.deepcopy.go @@ -28,6 +28,172 @@ import ( "k8s.io/apimachinery/pkg/runtime" ) +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterDefinition) DeepCopyInto(out *ClusterDefinition) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + out.Status = in.Status +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterDefinition. +func (in *ClusterDefinition) DeepCopy() *ClusterDefinition { + if in == nil { + return nil + } + out := new(ClusterDefinition) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ClusterDefinition) 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 *ClusterDefinitionList) DeepCopyInto(out *ClusterDefinitionList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]ClusterDefinition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterDefinitionList. +func (in *ClusterDefinitionList) DeepCopy() *ClusterDefinitionList { + if in == nil { + return nil + } + out := new(ClusterDefinitionList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ClusterDefinitionList) 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 *ClusterDefinitionSpec) DeepCopyInto(out *ClusterDefinitionSpec) { + *out = *in + if in.Topologies != nil { + in, out := &in.Topologies, &out.Topologies + *out = make([]ClusterTopology, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterDefinitionSpec. +func (in *ClusterDefinitionSpec) DeepCopy() *ClusterDefinitionSpec { + if in == nil { + return nil + } + out := new(ClusterDefinitionSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterDefinitionStatus) DeepCopyInto(out *ClusterDefinitionStatus) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterDefinitionStatus. +func (in *ClusterDefinitionStatus) DeepCopy() *ClusterDefinitionStatus { + if in == nil { + return nil + } + out := new(ClusterDefinitionStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterTopology) DeepCopyInto(out *ClusterTopology) { + *out = *in + if in.Components != nil { + in, out := &in.Components, &out.Components + *out = make([]ClusterTopologyComponent, len(*in)) + copy(*out, *in) + } + if in.Orders != nil { + in, out := &in.Orders, &out.Orders + *out = new(ClusterTopologyOrders) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterTopology. +func (in *ClusterTopology) DeepCopy() *ClusterTopology { + if in == nil { + return nil + } + out := new(ClusterTopology) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterTopologyComponent) DeepCopyInto(out *ClusterTopologyComponent) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterTopologyComponent. +func (in *ClusterTopologyComponent) DeepCopy() *ClusterTopologyComponent { + if in == nil { + return nil + } + out := new(ClusterTopologyComponent) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterTopologyOrders) DeepCopyInto(out *ClusterTopologyOrders) { + *out = *in + if in.Provision != nil { + in, out := &in.Provision, &out.Provision + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.Terminate != nil { + in, out := &in.Terminate, &out.Terminate + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.Update != nil { + in, out := &in.Update, &out.Update + *out = make([]string, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterTopologyOrders. +func (in *ClusterTopologyOrders) DeepCopy() *ClusterTopologyOrders { + if in == nil { + return nil + } + out := new(ClusterTopologyOrders) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ConnectionCredentialAuth) DeepCopyInto(out *ConnectionCredentialAuth) { *out = *in diff --git a/apis/apps/v1alpha1/clusterdefinition_conversion.go b/apis/apps/v1alpha1/clusterdefinition_conversion.go new file mode 100644 index 00000000000..b626dab9de0 --- /dev/null +++ b/apis/apps/v1alpha1/clusterdefinition_conversion.go @@ -0,0 +1,148 @@ +/* +Copyright (C) 2022-2024 ApeCloud Co., Ltd + +This file is part of KubeBlocks project + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ + +package v1alpha1 + +import ( + "sigs.k8s.io/controller-runtime/pkg/conversion" + + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" +) + +// ConvertTo converts this ClusterDefinition to the Hub version (v1). +func (r *ClusterDefinition) ConvertTo(dstRaw conversion.Hub) error { + dst := dstRaw.(*appsv1.ClusterDefinition) + + // objectMeta + dst.ObjectMeta = r.ObjectMeta + + // spec + dst.Spec.Topologies = r.topologiesTo(r.Spec.Topologies) + + // status + dst.Status.ObservedGeneration = r.Status.ObservedGeneration + dst.Status.Phase = appsv1.Phase(r.Status.Phase) + dst.Status.Message = r.Status.Message + dst.Status.Topologies = r.Status.Topologies + + return nil +} + +// ConvertFrom converts from the Hub version (v1) to this version. +func (r *ClusterDefinition) ConvertFrom(srcRaw conversion.Hub) error { + src := srcRaw.(*appsv1.ClusterDefinition) + + // objectMeta + r.ObjectMeta = src.ObjectMeta + + // spec + r.Spec.Topologies = r.topologiesFrom(src.Spec.Topologies) + + // status + r.Status.ObservedGeneration = src.Status.ObservedGeneration + r.Status.Phase = Phase(src.Status.Phase) + r.Status.Message = src.Status.Message + r.Status.Topologies = src.Status.Topologies + + return nil +} + +func (r *ClusterDefinition) topologiesTo(src []ClusterTopology) []appsv1.ClusterTopology { + if src != nil { + topologies := make([]appsv1.ClusterTopology, 0) + for _, topology := range src { + topologies = append(topologies, appsv1.ClusterTopology{ + Name: topology.Name, + Components: r.topologyComponentTo(topology.Components), + Orders: r.topologyOrdersTo(topology.Orders), + Default: topology.Default, + }) + } + return topologies + } + return nil +} + +func (r *ClusterDefinition) topologyComponentTo(src []ClusterTopologyComponent) []appsv1.ClusterTopologyComponent { + if src != nil { + comps := make([]appsv1.ClusterTopologyComponent, 0) + for _, comp := range src { + comps = append(comps, appsv1.ClusterTopologyComponent{ + Name: comp.Name, + CompDef: comp.CompDef, + }) + } + return comps + } + return nil +} + +func (r *ClusterDefinition) topologyOrdersTo(src *ClusterTopologyOrders) *appsv1.ClusterTopologyOrders { + if src != nil { + return &appsv1.ClusterTopologyOrders{ + Provision: src.Provision, + Terminate: src.Terminate, + Update: src.Update, + } + } + return nil +} + +func (r *ClusterDefinition) topologiesFrom(src []appsv1.ClusterTopology) []ClusterTopology { + if src != nil { + topologies := make([]ClusterTopology, 0) + for _, topology := range src { + topologies = append(topologies, ClusterTopology{ + Name: topology.Name, + Components: r.topologyComponentFrom(topology.Components), + Orders: r.topologyOrdersFrom(topology.Orders), + Default: topology.Default, + }) + } + return topologies + } + return nil +} + +func (r *ClusterDefinition) topologyComponentFrom(src []appsv1.ClusterTopologyComponent) []ClusterTopologyComponent { + if src != nil { + comps := make([]ClusterTopologyComponent, 0) + for _, comp := range src { + comps = append(comps, ClusterTopologyComponent{ + Name: comp.Name, + CompDef: comp.CompDef, + }) + } + return comps + } + return nil +} + +func (r *ClusterDefinition) topologyOrdersFrom(src *appsv1.ClusterTopologyOrders) *ClusterTopologyOrders { + if src != nil { + if src != nil { + return &ClusterTopologyOrders{ + Provision: src.Provision, + Terminate: src.Terminate, + Update: src.Update, + } + } + } + return nil +} diff --git a/apis/apps/v1alpha1/clusterdefinition_webhook.go b/apis/apps/v1alpha1/clusterdefinition_webhook.go new file mode 100644 index 00000000000..13e161adc24 --- /dev/null +++ b/apis/apps/v1alpha1/clusterdefinition_webhook.go @@ -0,0 +1,79 @@ +/* +Copyright (C) 2022-2024 ApeCloud Co., Ltd + +This file is part of KubeBlocks project + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ + +package v1alpha1 + +import ( + "k8s.io/apimachinery/pkg/runtime" + ctrl "sigs.k8s.io/controller-runtime" + logf "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/webhook" + "sigs.k8s.io/controller-runtime/pkg/webhook/admission" +) + +// log is for logging in this package. +var clusterdefinitionlog = logf.Log.WithName("clusterdefinition-resource") + +func (r *ClusterDefinition) SetupWebhookWithManager(mgr ctrl.Manager) error { + return ctrl.NewWebhookManagedBy(mgr). + For(r). + Complete() +} + +// TODO(user): EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! + +//+kubebuilder:webhook:path=/mutate-apps-kubeblocks-io-v1alpha1-clusterdefinition,mutating=true,failurePolicy=fail,sideEffects=None,groups=apps.kubeblocks.io,resources=clusterdefinitions,verbs=create;update,versions=v1alpha1,name=mclusterdefinition.kb.io,admissionReviewVersions=v1 + +var _ webhook.Defaulter = &ClusterDefinition{} + +// Default implements webhook.Defaulter so a webhook will be registered for the type +func (r *ClusterDefinition) Default() { + clusterdefinitionlog.Info("default", "name", r.Name) + + // TODO(user): fill in your defaulting logic. +} + +// TODO(user): change verbs to "verbs=create;update;delete" if you want to enable deletion validation. +//+kubebuilder:webhook:path=/validate-apps-kubeblocks-io-v1alpha1-clusterdefinition,mutating=false,failurePolicy=fail,sideEffects=None,groups=apps.kubeblocks.io,resources=clusterdefinitions,verbs=create;update,versions=v1alpha1,name=vclusterdefinition.kb.io,admissionReviewVersions=v1 + +var _ webhook.Validator = &ClusterDefinition{} + +// ValidateCreate implements webhook.Validator so a webhook will be registered for the type +func (r *ClusterDefinition) ValidateCreate() (warnings admission.Warnings, err error) { + clusterdefinitionlog.Info("validate create", "name", r.Name) + + // TODO(user): fill in your validation logic upon object creation. + return nil, nil +} + +// ValidateUpdate implements webhook.Validator so a webhook will be registered for the type +func (r *ClusterDefinition) ValidateUpdate(old runtime.Object) (warnings admission.Warnings, err error) { + clusterdefinitionlog.Info("validate update", "name", r.Name) + + // TODO(user): fill in your validation logic upon object update. + return nil, nil +} + +// ValidateDelete implements webhook.Validator so a webhook will be registered for the type +func (r *ClusterDefinition) ValidateDelete() (warnings admission.Warnings, err error) { + clusterdefinitionlog.Info("validate delete", "name", r.Name) + + // TODO(user): fill in your validation logic upon object deletion. + return nil, nil +} diff --git a/apis/apps/v1alpha1/servicedescriptor_conversion.go b/apis/apps/v1alpha1/servicedescriptor_conversion.go index 97ba8deec72..140d69d12e2 100644 --- a/apis/apps/v1alpha1/servicedescriptor_conversion.go +++ b/apis/apps/v1alpha1/servicedescriptor_conversion.go @@ -25,7 +25,7 @@ import ( appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" ) -// ConvertTo converts this Demo to the Hub version (v2). +// ConvertTo converts this ServiceDescriptor to the Hub version (v1). func (r *ServiceDescriptor) ConvertTo(dstRaw conversion.Hub) error { dst := dstRaw.(*appsv1.ServiceDescriptor) @@ -55,6 +55,7 @@ func (r *ServiceDescriptor) ConvertTo(dstRaw conversion.Hub) error { return nil } +// ConvertFrom converts from the Hub version (v1) to this version. func (r *ServiceDescriptor) ConvertFrom(srcRaw conversion.Hub) error { src := srcRaw.(*appsv1.ServiceDescriptor) diff --git a/apis/apps/v1alpha1/webhook_suite_test.go b/apis/apps/v1alpha1/webhook_suite_test.go index 3dbd11ff519..c30f570e0cd 100644 --- a/apis/apps/v1alpha1/webhook_suite_test.go +++ b/apis/apps/v1alpha1/webhook_suite_test.go @@ -31,8 +31,8 @@ import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" - admissionv1beta1 "k8s.io/api/admission/v1beta1" //+kubebuilder:scaffold:imports + admissionv1beta1 "k8s.io/api/admission/v1beta1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/client-go/rest" ctrl "sigs.k8s.io/controller-runtime" @@ -102,6 +102,9 @@ var _ = BeforeSuite(func() { }) Expect(err).NotTo(HaveOccurred()) + err = (&ClusterDefinition{}).SetupWebhookWithManager(mgr) + Expect(err).NotTo(HaveOccurred()) + err = (&ServiceDescriptor{}).SetupWebhookWithManager(mgr) Expect(err).NotTo(HaveOccurred()) diff --git a/cmd/manager/main.go b/cmd/manager/main.go index 03e404f79a2..0d3bdd754a5 100644 --- a/cmd/manager/main.go +++ b/cmd/manager/main.go @@ -524,6 +524,14 @@ func main() { } if os.Getenv("ENABLE_WEBHOOKS") == "true" { + if err = (&appsv1alpha1.ClusterDefinition{}).SetupWebhookWithManager(mgr); err != nil { + setupLog.Error(err, "unable to create webhook", "webhook", "ClusterDefinition") + os.Exit(1) + } + if err = (&appsv1.ClusterDefinition{}).SetupWebhookWithManager(mgr); err != nil { + setupLog.Error(err, "unable to create webhook", "webhook", "ClusterDefinition") + os.Exit(1) + } if err = (&appsv1alpha1.ServiceDescriptor{}).SetupWebhookWithManager(mgr); err != nil { setupLog.Error(err, "unable to create webhook", "webhook", "ServiceDescriptor") os.Exit(1) diff --git a/config/crd/bases/apps.kubeblocks.io_clusterdefinitions.yaml b/config/crd/bases/apps.kubeblocks.io_clusterdefinitions.yaml index a626e4fb376..133edfc7b7d 100644 --- a/config/crd/bases/apps.kubeblocks.io_clusterdefinitions.yaml +++ b/config/crd/bases/apps.kubeblocks.io_clusterdefinitions.yaml @@ -19,6 +19,190 @@ spec: singular: clusterdefinition scope: Cluster versions: + - additionalPrinterColumns: + - description: topologies + jsonPath: .status.topologies + name: Topologies + type: string + - description: status phase + jsonPath: .status.phase + name: STATUS + type: string + - jsonPath: .metadata.creationTimestamp + name: AGE + type: date + name: v1 + schema: + openAPIV3Schema: + description: |- + ClusterDefinition defines the topology for databases or storage systems, + offering a variety of topological configurations to meet diverse deployment needs and scenarios. + + + It includes a list of Components, each linked to a ComponentDefinition, which enhances reusability and reduce redundancy. + For example, widely used components such as etcd and Zookeeper can be defined once and reused across multiple ClusterDefinitions, + simplifying the setup of new systems. + + + Additionally, ClusterDefinition also specifies the sequence of startup, upgrade, and shutdown for Components, + ensuring a controlled and predictable management of component lifecycles. + 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: ClusterDefinitionSpec defines the desired state of ClusterDefinition. + properties: + topologies: + description: Topologies defines all possible topologies within the + cluster. + items: + description: ClusterTopology represents the definition for a specific + cluster topology. + properties: + components: + description: Components specifies the components in the topology. + items: + description: ClusterTopologyComponent defines a Component + within a ClusterTopology. + properties: + compDef: + description: |- + Specifies the name or prefix of the ComponentDefinition custom resource(CR) that + defines the Component's characteristics and behavior. + + + When a prefix is used, the system selects the ComponentDefinition CR with the latest version that matches the prefix. + This approach allows: + + + 1. Precise selection by providing the exact name of a ComponentDefinition CR. + 2. Flexible and automatic selection of the most up-to-date ComponentDefinition CR by specifying a prefix. + + + Once set, this field cannot be updated. + maxLength: 64 + type: string + name: + description: |- + Defines the unique identifier of the component within the cluster topology. + It follows IANA Service naming rules and is used as part of the Service's DNS name. + The name must start with a lowercase letter, can contain lowercase letters, numbers, + and hyphens, and must end with a lowercase letter or number. + + + Cannot be updated once set. + maxLength: 16 + pattern: ^[a-z]([a-z0-9\-]*[a-z0-9])?$ + type: string + required: + - compDef + - name + type: object + maxItems: 128 + minItems: 1 + type: array + default: + description: |- + Default indicates whether this topology serves as the default configuration. + When set to true, this topology is automatically used unless another is explicitly specified. + type: boolean + name: + description: |- + Name is the unique identifier for the cluster topology. + Cannot be updated. + maxLength: 32 + type: string + orders: + description: |- + Specifies the sequence in which components within a cluster topology are + started, stopped, and upgraded. + This ordering is crucial for maintaining the correct dependencies and operational flow across components. + properties: + provision: + description: |- + Specifies the order for creating and initializing components. + This is designed for components that depend on one another. Components without dependencies can be grouped together. + + + Components that can be provisioned independently or have no dependencies can be listed together in the same stage, + separated by commas. + items: + type: string + type: array + terminate: + description: |- + Outlines the order for stopping and deleting components. + This sequence is designed for components that require a graceful shutdown or have interdependencies. + + + Components that can be terminated independently or have no dependencies can be listed together in the same stage, + separated by commas. + items: + type: string + type: array + update: + description: |- + Update determines the order for updating components' specifications, such as image upgrades or resource scaling. + This sequence is designed for components that have dependencies or require specific update procedures. + + + Components that can be updated independently or have no dependencies can be listed together in the same stage, + separated by commas. + items: + type: string + type: array + type: object + required: + - components + - name + type: object + maxItems: 128 + minItems: 1 + type: array + type: object + status: + description: ClusterDefinitionStatus defines the observed state of ClusterDefinition + properties: + message: + description: Provides additional information about the current phase. + type: string + observedGeneration: + description: Represents the most recent generation observed for this + ClusterDefinition. + format: int64 + type: integer + phase: + description: |- + Specifies the current phase of the ClusterDefinition. Valid values are `empty`, `Available`, `Unavailable`. + When `Available`, the ClusterDefinition is ready and can be referenced by related objects. + enum: + - Available + - Unavailable + type: string + topologies: + description: Topologies this ClusterDefinition supported. + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} - additionalPrinterColumns: - description: topologies jsonPath: .status.topologies @@ -207,6 +391,6 @@ spec: type: object type: object served: true - storage: true + storage: false subresources: status: {} diff --git a/config/samples/apps_v1_clusterdefinition.yaml b/config/samples/apps_v1_clusterdefinition.yaml new file mode 100644 index 00000000000..adf57b1f501 --- /dev/null +++ b/config/samples/apps_v1_clusterdefinition.yaml @@ -0,0 +1,12 @@ +apiVersion: apps.kubeblocks.io/v1 +kind: ClusterDefinition +metadata: + labels: + app.kubernetes.io/name: clusterdefinition + app.kubernetes.io/instance: clusterdefinition-sample + app.kubernetes.io/part-of: kubeblocks + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/created-by: kubeblocks + name: clusterdefinition-sample +spec: + # TODO(user): Add fields here diff --git a/config/webhook/manifests.yaml b/config/webhook/manifests.yaml index aa99856da03..c0bdfd18fe2 100644 --- a/config/webhook/manifests.yaml +++ b/config/webhook/manifests.yaml @@ -4,6 +4,26 @@ kind: MutatingWebhookConfiguration metadata: name: mutating-webhook-configuration webhooks: +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: webhook-service + namespace: system + path: /mutate-apps-kubeblocks-io-v1-clusterdefinition + failurePolicy: Fail + name: mclusterdefinition.kb.io + rules: + - apiGroups: + - apps.kubeblocks.io + apiVersions: + - v1 + operations: + - CREATE + - UPDATE + resources: + - clusterdefinitions + sideEffects: None - admissionReviewVersions: - v1 clientConfig: @@ -24,6 +44,26 @@ webhooks: resources: - servicedescriptors sideEffects: None +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: webhook-service + namespace: system + path: /mutate-apps-kubeblocks-io-v1alpha1-clusterdefinition + failurePolicy: Fail + name: mclusterdefinition.kb.io + rules: + - apiGroups: + - apps.kubeblocks.io + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + resources: + - clusterdefinitions + sideEffects: None - admissionReviewVersions: - v1 clientConfig: @@ -50,6 +90,26 @@ kind: ValidatingWebhookConfiguration metadata: name: validating-webhook-configuration webhooks: +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: webhook-service + namespace: system + path: /validate-apps-kubeblocks-io-v1-clusterdefinition + failurePolicy: Fail + name: vclusterdefinition.kb.io + rules: + - apiGroups: + - apps.kubeblocks.io + apiVersions: + - v1 + operations: + - CREATE + - UPDATE + resources: + - clusterdefinitions + sideEffects: None - admissionReviewVersions: - v1 clientConfig: @@ -70,6 +130,26 @@ webhooks: resources: - servicedescriptors sideEffects: None +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: webhook-service + namespace: system + path: /validate-apps-kubeblocks-io-v1alpha1-clusterdefinition + failurePolicy: Fail + name: vclusterdefinition.kb.io + rules: + - apiGroups: + - apps.kubeblocks.io + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + resources: + - clusterdefinitions + sideEffects: None - admissionReviewVersions: - v1 clientConfig: diff --git a/controllers/apps/cluster_controller_test.go b/controllers/apps/cluster_controller_test.go index 6c093ac7c37..fe401fcc9f5 100644 --- a/controllers/apps/cluster_controller_test.go +++ b/controllers/apps/cluster_controller_test.go @@ -34,6 +34,7 @@ import ( "k8s.io/apimachinery/pkg/types" "sigs.k8s.io/controller-runtime/pkg/client" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" dpv1alpha1 "github.com/apecloud/kubeblocks/apis/dataprotection/v1alpha1" "github.com/apecloud/kubeblocks/pkg/constant" @@ -59,16 +60,16 @@ var _ = Describe("Cluster Controller", func() { ) var ( - clusterDefObj *appsv1alpha1.ClusterDefinition + clusterDefObj *appsv1.ClusterDefinition compDefObj *appsv1alpha1.ComponentDefinition compVersionObj *appsv1alpha1.ComponentVersion clusterObj *appsv1alpha1.Cluster clusterKey types.NamespacedName allSettings map[string]interface{} - defaultTopology = appsv1alpha1.ClusterTopology{ + defaultTopology = appsv1.ClusterTopology{ Name: "default", Default: true, - Components: []appsv1alpha1.ClusterTopologyComponent{ + Components: []appsv1.ClusterTopologyComponent{ { Name: defaultCompName, CompDef: compDefName, // prefix @@ -191,9 +192,9 @@ var _ = Describe("Cluster Controller", func() { g.Expect(compVersion.Status.Phase).Should(Equal(appsv1alpha1.AvailablePhase)) })).Should(Succeed()) Eventually(testapps.CheckObj(&testCtx, client.ObjectKeyFromObject(clusterDefObj), - func(g Gomega, clusterDef *appsv1alpha1.ClusterDefinition) { + func(g Gomega, clusterDef *appsv1.ClusterDefinition) { g.Expect(clusterDef.Status.ObservedGeneration).Should(Equal(clusterDef.Generation)) - g.Expect(clusterDef.Status.Phase).Should(Equal(appsv1alpha1.AvailablePhase)) + g.Expect(clusterDef.Status.Phase).Should(Equal(appsv1.AvailablePhase)) })).Should(Succeed()) } diff --git a/controllers/apps/cluster_plan_builder.go b/controllers/apps/cluster_plan_builder.go index 6d35f26204b..fbc26220329 100644 --- a/controllers/apps/cluster_plan_builder.go +++ b/controllers/apps/cluster_plan_builder.go @@ -37,6 +37,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" + kbappsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" appsv1beta1 "github.com/apecloud/kubeblocks/apis/apps/v1beta1" dpv1alpha1 "github.com/apecloud/kubeblocks/apis/dataprotection/v1alpha1" @@ -62,7 +63,7 @@ type clusterTransformContext struct { logr.Logger Cluster *appsv1alpha1.Cluster OrigCluster *appsv1alpha1.Cluster - ClusterDef *appsv1alpha1.ClusterDefinition + ClusterDef *kbappsv1.ClusterDefinition ComponentDefs map[string]*appsv1alpha1.ComponentDefinition // ComponentSpecs includes all cluster component specs generated from ComponentSpecs and ShardingSpecs ComponentSpecs []*appsv1alpha1.ClusterComponentSpec diff --git a/controllers/apps/clusterdefinition_controller.go b/controllers/apps/clusterdefinition_controller.go index 7c604ec77da..40eac709ec6 100644 --- a/controllers/apps/clusterdefinition_controller.go +++ b/controllers/apps/clusterdefinition_controller.go @@ -32,6 +32,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/log" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" appsconfig "github.com/apecloud/kubeblocks/controllers/apps/configuration" "github.com/apecloud/kubeblocks/pkg/constant" @@ -62,7 +63,7 @@ func (r *ClusterDefinitionReconciler) Reconcile(ctx context.Context, req ctrl.Re Recorder: r.Recorder, } - clusterDef := &appsv1alpha1.ClusterDefinition{} + clusterDef := &appsv1.ClusterDefinition{} if err := r.Client.Get(reqCtx.Ctx, reqCtx.Req.NamespacedName, clusterDef); err != nil { return intctrlutil.CheckedRequeueWithError(err, reqCtx.Log, "") } @@ -73,7 +74,7 @@ func (r *ClusterDefinitionReconciler) Reconcile(ctx context.Context, req ctrl.Re } if clusterDef.Status.ObservedGeneration == clusterDef.Generation && - slices.Contains([]appsv1alpha1.Phase{appsv1alpha1.AvailablePhase}, clusterDef.Status.Phase) { + clusterDef.Status.Phase == appsv1.AvailablePhase { return intctrlutil.Reconciled() } @@ -100,7 +101,7 @@ func (r *ClusterDefinitionReconciler) SetupWithManager(mgr ctrl.Manager) error { Complete(r) } -func (r *ClusterDefinitionReconciler) deletionHandler(rctx intctrlutil.RequestCtx, clusterDef *appsv1alpha1.ClusterDefinition) func() (*ctrl.Result, error) { +func (r *ClusterDefinitionReconciler) deletionHandler(rctx intctrlutil.RequestCtx, clusterDef *appsv1.ClusterDefinition) func() (*ctrl.Result, error) { return func() (*ctrl.Result, error) { recordEvent := func() { r.Recorder.Event(clusterDef, corev1.EventTypeWarning, "ExistsReferencedResources", @@ -114,7 +115,7 @@ func (r *ClusterDefinitionReconciler) deletionHandler(rctx intctrlutil.RequestCt } } -func (r *ClusterDefinitionReconciler) deleteExternalResources(rctx intctrlutil.RequestCtx, clusterDef *appsv1alpha1.ClusterDefinition) error { +func (r *ClusterDefinitionReconciler) deleteExternalResources(rctx intctrlutil.RequestCtx, clusterDef *appsv1.ClusterDefinition) error { // delete any external resources associated with the cronJob // // Ensure that delete implementation is idempotent and safe to invoke @@ -122,30 +123,29 @@ func (r *ClusterDefinitionReconciler) deleteExternalResources(rctx intctrlutil.R return appsconfig.DeleteConfigMapFinalizer(r.Client, rctx, clusterDef) } -func (r *ClusterDefinitionReconciler) available(rctx intctrlutil.RequestCtx, clusterDef *appsv1alpha1.ClusterDefinition) error { - return r.status(rctx, clusterDef, appsv1alpha1.AvailablePhase, "") +func (r *ClusterDefinitionReconciler) available(rctx intctrlutil.RequestCtx, clusterDef *appsv1.ClusterDefinition) error { + return r.status(rctx, clusterDef, appsv1.AvailablePhase, "") } -func (r *ClusterDefinitionReconciler) unavailable(rctx intctrlutil.RequestCtx, clusterDef *appsv1alpha1.ClusterDefinition, err error) error { +func (r *ClusterDefinitionReconciler) unavailable(rctx intctrlutil.RequestCtx, clusterDef *appsv1.ClusterDefinition, err error) error { message := "" if err != nil { message = err.Error() } - return r.status(rctx, clusterDef, appsv1alpha1.UnavailablePhase, message) + return r.status(rctx, clusterDef, appsv1.UnavailablePhase, message) } func (r *ClusterDefinitionReconciler) status(rctx intctrlutil.RequestCtx, - clusterDef *appsv1alpha1.ClusterDefinition, phase appsv1alpha1.Phase, message string) error { + clusterDef *appsv1.ClusterDefinition, phase appsv1.Phase, message string) error { patch := client.MergeFrom(clusterDef.DeepCopy()) clusterDef.Status.ObservedGeneration = clusterDef.Generation clusterDef.Status.Phase = phase clusterDef.Status.Message = message clusterDef.Status.Topologies = r.supportedTopologies(clusterDef) - clusterDef.Status.ServiceRefs = r.referredServiceRefs(clusterDef) return r.Client.Status().Patch(rctx.Ctx, clusterDef, patch) } -func (r *ClusterDefinitionReconciler) supportedTopologies(clusterDef *appsv1alpha1.ClusterDefinition) string { +func (r *ClusterDefinitionReconciler) supportedTopologies(clusterDef *appsv1.ClusterDefinition) string { topologies := make([]string, 0) for _, topology := range clusterDef.Spec.Topologies { topologies = append(topologies, topology.Name) @@ -154,11 +154,7 @@ func (r *ClusterDefinitionReconciler) supportedTopologies(clusterDef *appsv1alph return strings.Join(topologies, ",") // TODO(API): topologies length } -func (r *ClusterDefinitionReconciler) referredServiceRefs(clusterDef *appsv1alpha1.ClusterDefinition) string { - return "" // TODO(API): referred service refs -} - -func (r *ClusterDefinitionReconciler) reconcile(rctx intctrlutil.RequestCtx, clusterDef *appsv1alpha1.ClusterDefinition) (*ctrl.Result, error) { +func (r *ClusterDefinitionReconciler) reconcile(rctx intctrlutil.RequestCtx, clusterDef *appsv1.ClusterDefinition) (*ctrl.Result, error) { if err := r.reconcileTopologies(rctx, clusterDef); err != nil { res, err1 := intctrlutil.CheckedRequeueWithError(err, rctx.Log, "") return &res, err1 @@ -166,7 +162,7 @@ func (r *ClusterDefinitionReconciler) reconcile(rctx intctrlutil.RequestCtx, clu return nil, nil } -func (r *ClusterDefinitionReconciler) reconcileTopologies(rctx intctrlutil.RequestCtx, clusterDef *appsv1alpha1.ClusterDefinition) error { +func (r *ClusterDefinitionReconciler) reconcileTopologies(rctx intctrlutil.RequestCtx, clusterDef *appsv1.ClusterDefinition) error { if !checkUniqueItemWithValue(clusterDef.Spec.Topologies, "Name", nil) { return fmt.Errorf("duplicate topology names") } @@ -181,7 +177,7 @@ func (r *ClusterDefinitionReconciler) reconcileTopologies(rctx intctrlutil.Reque return nil } -func (r *ClusterDefinitionReconciler) validateTopology(rctx intctrlutil.RequestCtx, topology appsv1alpha1.ClusterTopology) error { +func (r *ClusterDefinitionReconciler) validateTopology(rctx intctrlutil.RequestCtx, topology appsv1.ClusterTopology) error { if !checkUniqueItemWithValue(topology.Components, "Name", nil) { return fmt.Errorf("duplicate topology component names") } @@ -202,7 +198,7 @@ func (r *ClusterDefinitionReconciler) validateTopology(rctx intctrlutil.RequestC return nil } -func (r *ClusterDefinitionReconciler) validateTopologyOrders(topology appsv1alpha1.ClusterTopology) error { +func (r *ClusterDefinitionReconciler) validateTopologyOrders(topology appsv1.ClusterTopology) error { comps := make([]string, 0) for _, comp := range topology.Components { comps = append(comps, comp.Name) @@ -231,7 +227,7 @@ func (r *ClusterDefinitionReconciler) validateTopologyOrders(topology appsv1alph } func (r *ClusterDefinitionReconciler) loadTopologyCompDefs(ctx context.Context, - topology appsv1alpha1.ClusterTopology) (map[string][]*appsv1alpha1.ComponentDefinition, error) { + topology appsv1.ClusterTopology) (map[string][]*appsv1alpha1.ComponentDefinition, error) { compDefList := &appsv1alpha1.ComponentDefinitionList{} if err := r.Client.List(ctx, compDefList); err != nil { return nil, err @@ -256,7 +252,7 @@ func (r *ClusterDefinitionReconciler) loadTopologyCompDefs(ctx context.Context, } func (r *ClusterDefinitionReconciler) validateTopologyComponent(compDefs map[string][]*appsv1alpha1.ComponentDefinition, - comp appsv1alpha1.ClusterTopologyComponent) error { + comp appsv1.ClusterTopologyComponent) error { defs, ok := compDefs[comp.Name] if !ok || len(defs) == 0 { return fmt.Errorf("there is no matched definitions found for the topology component %s", comp.Name) @@ -265,7 +261,7 @@ func (r *ClusterDefinitionReconciler) validateTopologyComponent(compDefs map[str } // defaultClusterTopology returns the default cluster topology in specified cluster definition. -func defaultClusterTopology(clusterDef *appsv1alpha1.ClusterDefinition) *appsv1alpha1.ClusterTopology { +func defaultClusterTopology(clusterDef *appsv1.ClusterDefinition) *appsv1.ClusterTopology { for i, topology := range clusterDef.Spec.Topologies { if topology.Default { return &clusterDef.Spec.Topologies[i] @@ -275,7 +271,7 @@ func defaultClusterTopology(clusterDef *appsv1alpha1.ClusterDefinition) *appsv1a } // referredClusterTopology returns the cluster topology which has name @name. -func referredClusterTopology(clusterDef *appsv1alpha1.ClusterDefinition, name string) *appsv1alpha1.ClusterTopology { +func referredClusterTopology(clusterDef *appsv1.ClusterDefinition, name string) *appsv1.ClusterTopology { if len(name) == 0 { return defaultClusterTopology(clusterDef) } diff --git a/controllers/apps/clusterdefinition_controller_test.go b/controllers/apps/clusterdefinition_controller_test.go index fb9de205fbf..ada1811244e 100644 --- a/controllers/apps/clusterdefinition_controller_test.go +++ b/controllers/apps/clusterdefinition_controller_test.go @@ -27,6 +27,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" intctrlutil "github.com/apecloud/kubeblocks/pkg/generics" testapps "github.com/apecloud/kubeblocks/pkg/testutil/apps" @@ -39,7 +40,7 @@ var _ = Describe("ClusterDefinition Controller", func() { ) var ( - clusterDefObj *appsv1alpha1.ClusterDefinition + clusterDefObj *appsv1.ClusterDefinition ) cleanEnv := func() { @@ -72,21 +73,21 @@ var _ = Describe("ClusterDefinition Controller", func() { Context("cluster topology", func() { var ( - singleCompTopology = appsv1alpha1.ClusterTopology{ + singleCompTopology = appsv1.ClusterTopology{ Name: "topo1", Default: true, - Components: []appsv1alpha1.ClusterTopologyComponent{ + Components: []appsv1.ClusterTopologyComponent{ { Name: "server", CompDef: compDefinitionName, }, }, - Orders: &appsv1alpha1.ClusterTopologyOrders{}, + Orders: &appsv1.ClusterTopologyOrders{}, } - multipleCompsTopology = appsv1alpha1.ClusterTopology{ + multipleCompsTopology = appsv1.ClusterTopology{ Name: "topo2", Default: false, - Components: []appsv1alpha1.ClusterTopologyComponent{ + Components: []appsv1.ClusterTopologyComponent{ { Name: "proxy", CompDef: compDefinitionName, @@ -100,7 +101,7 @@ var _ = Describe("ClusterDefinition Controller", func() { CompDef: compDefinitionName, }, }, - Orders: &appsv1alpha1.ClusterTopologyOrders{ + Orders: &appsv1.ClusterTopologyOrders{ Provision: []string{"storage", "server", "proxy"}, Update: []string{"storage", "server", "proxy"}, }, @@ -126,9 +127,9 @@ var _ = Describe("ClusterDefinition Controller", func() { AddClusterTopology(multipleCompsTopology). Create(&testCtx). GetObject() - Eventually(testapps.CheckObj(&testCtx, client.ObjectKeyFromObject(clusterDefObj), func(g Gomega, cd *appsv1alpha1.ClusterDefinition) { + Eventually(testapps.CheckObj(&testCtx, client.ObjectKeyFromObject(clusterDefObj), func(g Gomega, cd *appsv1.ClusterDefinition) { g.Expect(cd.Status.ObservedGeneration).Should(Equal(cd.Generation)) - g.Expect(cd.Status.Phase).Should(Equal(appsv1alpha1.AvailablePhase)) + g.Expect(cd.Status.Phase).Should(Equal(appsv1.AvailablePhase)) })).Should(Succeed()) }) @@ -137,43 +138,43 @@ var _ = Describe("ClusterDefinition Controller", func() { }) It("ok", func() { - Eventually(testapps.CheckObj(&testCtx, client.ObjectKeyFromObject(clusterDefObj), func(g Gomega, cd *appsv1alpha1.ClusterDefinition) { + Eventually(testapps.CheckObj(&testCtx, client.ObjectKeyFromObject(clusterDefObj), func(g Gomega, cd *appsv1.ClusterDefinition) { g.Expect(cd.Status.ObservedGeneration).Should(Equal(cd.Generation)) - g.Expect(cd.Status.Phase).Should(Equal(appsv1alpha1.AvailablePhase)) + g.Expect(cd.Status.Phase).Should(Equal(appsv1.AvailablePhase)) })).Should(Succeed()) }) It("duplicate topology", func() { By("update cd to add a topology with same name") - Expect(testapps.GetAndChangeObj(&testCtx, client.ObjectKeyFromObject(clusterDefObj), func(cd *appsv1alpha1.ClusterDefinition) { + Expect(testapps.GetAndChangeObj(&testCtx, client.ObjectKeyFromObject(clusterDefObj), func(cd *appsv1.ClusterDefinition) { cd.Spec.Topologies = append(cd.Spec.Topologies, singleCompTopology) })()).Should(Succeed()) - Eventually(testapps.CheckObj(&testCtx, client.ObjectKeyFromObject(clusterDefObj), func(g Gomega, cd *appsv1alpha1.ClusterDefinition) { + Eventually(testapps.CheckObj(&testCtx, client.ObjectKeyFromObject(clusterDefObj), func(g Gomega, cd *appsv1.ClusterDefinition) { g.Expect(cd.Status.ObservedGeneration).Should(Equal(cd.Generation)) - g.Expect(cd.Status.Phase).Should(Equal(appsv1alpha1.UnavailablePhase)) + g.Expect(cd.Status.Phase).Should(Equal(appsv1.UnavailablePhase)) g.Expect(cd.Status.Message).Should(ContainSubstring("duplicate topology")) })).Should(Succeed()) }) It("multiple default topologies", func() { By("update cd to set all topologies as default") - Expect(testapps.GetAndChangeObj(&testCtx, client.ObjectKeyFromObject(clusterDefObj), func(cd *appsv1alpha1.ClusterDefinition) { + Expect(testapps.GetAndChangeObj(&testCtx, client.ObjectKeyFromObject(clusterDefObj), func(cd *appsv1.ClusterDefinition) { for i := range cd.Spec.Topologies { cd.Spec.Topologies[i].Default = true } })()).Should(Succeed()) - Eventually(testapps.CheckObj(&testCtx, client.ObjectKeyFromObject(clusterDefObj), func(g Gomega, cd *appsv1alpha1.ClusterDefinition) { + Eventually(testapps.CheckObj(&testCtx, client.ObjectKeyFromObject(clusterDefObj), func(g Gomega, cd *appsv1.ClusterDefinition) { g.Expect(cd.Status.ObservedGeneration).Should(Equal(cd.Generation)) - g.Expect(cd.Status.Phase).Should(Equal(appsv1alpha1.UnavailablePhase)) + g.Expect(cd.Status.Phase).Should(Equal(appsv1.UnavailablePhase)) g.Expect(cd.Status.Message).Should(ContainSubstring("multiple default topologies")) })).Should(Succeed()) }) It("duplicate topology component", func() { By("update cd to set all component names as same") - Expect(testapps.GetAndChangeObj(&testCtx, client.ObjectKeyFromObject(clusterDefObj), func(cd *appsv1alpha1.ClusterDefinition) { + Expect(testapps.GetAndChangeObj(&testCtx, client.ObjectKeyFromObject(clusterDefObj), func(cd *appsv1.ClusterDefinition) { compName := cd.Spec.Topologies[0].Components[0].Name for i, topology := range cd.Spec.Topologies { for j := range topology.Components { @@ -182,16 +183,16 @@ var _ = Describe("ClusterDefinition Controller", func() { } })()).Should(Succeed()) - Eventually(testapps.CheckObj(&testCtx, client.ObjectKeyFromObject(clusterDefObj), func(g Gomega, cd *appsv1alpha1.ClusterDefinition) { + Eventually(testapps.CheckObj(&testCtx, client.ObjectKeyFromObject(clusterDefObj), func(g Gomega, cd *appsv1.ClusterDefinition) { g.Expect(cd.Status.ObservedGeneration).Should(Equal(cd.Generation)) - g.Expect(cd.Status.Phase).Should(Equal(appsv1alpha1.UnavailablePhase)) + g.Expect(cd.Status.Phase).Should(Equal(appsv1.UnavailablePhase)) g.Expect(cd.Status.Message).Should(ContainSubstring("duplicate topology component")) })).Should(Succeed()) }) It("different components in topology orders", func() { By("update cd to add/remove components in orders") - Expect(testapps.GetAndChangeObj(&testCtx, client.ObjectKeyFromObject(clusterDefObj), func(cd *appsv1alpha1.ClusterDefinition) { + Expect(testapps.GetAndChangeObj(&testCtx, client.ObjectKeyFromObject(clusterDefObj), func(cd *appsv1.ClusterDefinition) { for i := range cd.Spec.Topologies { update := func(orders []string) []string { if len(orders) == 0 { @@ -211,22 +212,22 @@ var _ = Describe("ClusterDefinition Controller", func() { } })()).Should(Succeed()) - Eventually(testapps.CheckObj(&testCtx, client.ObjectKeyFromObject(clusterDefObj), func(g Gomega, cd *appsv1alpha1.ClusterDefinition) { + Eventually(testapps.CheckObj(&testCtx, client.ObjectKeyFromObject(clusterDefObj), func(g Gomega, cd *appsv1.ClusterDefinition) { g.Expect(cd.Status.ObservedGeneration).Should(Equal(cd.Generation)) - g.Expect(cd.Status.Phase).Should(Equal(appsv1alpha1.UnavailablePhase)) + g.Expect(cd.Status.Phase).Should(Equal(appsv1.UnavailablePhase)) g.Expect(cd.Status.Message).Should(MatchRegexp("the components in provision|terminate|update orders are different from those in definition")) })).Should(Succeed()) }) It("topology component has no matched definitions", func() { By("update cd to set a non-exist compdef for the first topology and component") - Expect(testapps.GetAndChangeObj(&testCtx, client.ObjectKeyFromObject(clusterDefObj), func(cd *appsv1alpha1.ClusterDefinition) { + Expect(testapps.GetAndChangeObj(&testCtx, client.ObjectKeyFromObject(clusterDefObj), func(cd *appsv1.ClusterDefinition) { cd.Spec.Topologies[0].Components[0].CompDef = "compdef-non-exist" })()).Should(Succeed()) - Eventually(testapps.CheckObj(&testCtx, client.ObjectKeyFromObject(clusterDefObj), func(g Gomega, cd *appsv1alpha1.ClusterDefinition) { + Eventually(testapps.CheckObj(&testCtx, client.ObjectKeyFromObject(clusterDefObj), func(g Gomega, cd *appsv1.ClusterDefinition) { g.Expect(cd.Status.ObservedGeneration).Should(Equal(cd.Generation)) - g.Expect(cd.Status.Phase).Should(Equal(appsv1alpha1.UnavailablePhase)) + g.Expect(cd.Status.Phase).Should(Equal(appsv1.UnavailablePhase)) g.Expect(cd.Status.Message).Should(ContainSubstring("there is no matched definitions found for the topology component")) })).Should(Succeed()) }) diff --git a/controllers/apps/transformer_cluster_api_normalization.go b/controllers/apps/transformer_cluster_api_normalization.go index cb927ddeb59..c0557442ebe 100644 --- a/controllers/apps/transformer_cluster_api_normalization.go +++ b/controllers/apps/transformer_cluster_api_normalization.go @@ -27,6 +27,7 @@ import ( "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/sets" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" "github.com/apecloud/kubeblocks/pkg/constant" "github.com/apecloud/kubeblocks/pkg/controller/component" @@ -106,16 +107,16 @@ func (t *ClusterAPINormalizationTransformer) buildCompSpecs(transCtx *clusterTra return nil, nil } -func (t *ClusterAPINormalizationTransformer) buildCompSpecs4Topology(clusterDef *appsv1alpha1.ClusterDefinition, +func (t *ClusterAPINormalizationTransformer) buildCompSpecs4Topology(clusterDef *appsv1.ClusterDefinition, cluster *appsv1alpha1.Cluster) ([]*appsv1alpha1.ClusterComponentSpec, error) { - newCompSpec := func(comp appsv1alpha1.ClusterTopologyComponent) *appsv1alpha1.ClusterComponentSpec { + newCompSpec := func(comp appsv1.ClusterTopologyComponent) *appsv1alpha1.ClusterComponentSpec { return &appsv1alpha1.ClusterComponentSpec{ Name: comp.Name, ComponentDef: comp.CompDef, } } - mergeCompSpec := func(comp appsv1alpha1.ClusterTopologyComponent, compSpec *appsv1alpha1.ClusterComponentSpec) *appsv1alpha1.ClusterComponentSpec { + mergeCompSpec := func(comp appsv1.ClusterTopologyComponent, compSpec *appsv1alpha1.ClusterComponentSpec) *appsv1alpha1.ClusterComponentSpec { if len(compSpec.ComponentDef) == 0 { compSpec.ComponentDef = comp.CompDef } diff --git a/controllers/apps/transformer_cluster_component_test.go b/controllers/apps/transformer_cluster_component_test.go index 2f474599a5b..e36a179ef44 100644 --- a/controllers/apps/transformer_cluster_component_test.go +++ b/controllers/apps/transformer_cluster_component_test.go @@ -31,6 +31,7 @@ import ( "k8s.io/apimachinery/pkg/runtime/schema" "sigs.k8s.io/controller-runtime/pkg/client" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" "github.com/apecloud/kubeblocks/pkg/controller/component" "github.com/apecloud/kubeblocks/pkg/controller/graph" @@ -88,14 +89,14 @@ var _ = Describe("cluster component transformer test", func() { ) var ( - clusterDef *appsv1alpha1.ClusterDefinition + clusterDef *appsv1.ClusterDefinition ) BeforeEach(func() { clusterDef = testapps.NewClusterDefFactory(clusterDefName). - AddClusterTopology(appsv1alpha1.ClusterTopology{ + AddClusterTopology(appsv1.ClusterTopology{ Name: clusterTopologyDefault, - Components: []appsv1alpha1.ClusterTopologyComponent{ + Components: []appsv1.ClusterTopologyComponent{ { Name: comp1aName, CompDef: compDefName, @@ -113,7 +114,7 @@ var _ = Describe("cluster component transformer test", func() { CompDef: compDefName, }, }, - Orders: &appsv1alpha1.ClusterTopologyOrders{ + Orders: &appsv1.ClusterTopologyOrders{ Provision: []string{ fmt.Sprintf("%s,%s", comp1aName, comp1bName), fmt.Sprintf("%s,%s", comp2aName, comp2bName), @@ -128,9 +129,9 @@ var _ = Describe("cluster component transformer test", func() { }, }, }). - AddClusterTopology(appsv1alpha1.ClusterTopology{ + AddClusterTopology(appsv1.ClusterTopology{ Name: clusterTopologyNoOrders, - Components: []appsv1alpha1.ClusterTopologyComponent{ + Components: []appsv1.ClusterTopologyComponent{ { Name: comp1aName, CompDef: compDefName, @@ -149,9 +150,9 @@ var _ = Describe("cluster component transformer test", func() { }, }, }). - AddClusterTopology(appsv1alpha1.ClusterTopology{ + AddClusterTopology(appsv1.ClusterTopology{ Name: clusterTopologyProvisionNUpdateOOD, - Components: []appsv1alpha1.ClusterTopologyComponent{ + Components: []appsv1.ClusterTopologyComponent{ { Name: comp1aName, CompDef: compDefName, @@ -169,7 +170,7 @@ var _ = Describe("cluster component transformer test", func() { CompDef: compDefName, }, }, - Orders: &appsv1alpha1.ClusterTopologyOrders{ + Orders: &appsv1.ClusterTopologyOrders{ Provision: []string{ fmt.Sprintf("%s,%s", comp1aName, comp1bName), fmt.Sprintf("%s,%s", comp2aName, comp2bName), @@ -180,9 +181,9 @@ var _ = Describe("cluster component transformer test", func() { }, }, }). - AddClusterTopology(appsv1alpha1.ClusterTopology{ + AddClusterTopology(appsv1.ClusterTopology{ Name: clusterTopology4Stop, - Components: []appsv1alpha1.ClusterTopologyComponent{ + Components: []appsv1.ClusterTopologyComponent{ { Name: comp1aName, CompDef: compDefName, @@ -196,7 +197,7 @@ var _ = Describe("cluster component transformer test", func() { CompDef: compDefName, }, }, - Orders: &appsv1alpha1.ClusterTopologyOrders{ + Orders: &appsv1.ClusterTopologyOrders{ Update: []string{comp1aName, comp2aName, comp3aName}, }, }). @@ -211,7 +212,7 @@ var _ = Describe("cluster component transformer test", func() { return d } - buildCompSpecs := func(clusterDef *appsv1alpha1.ClusterDefinition, cluster *appsv1alpha1.Cluster) []*appsv1alpha1.ClusterComponentSpec { + buildCompSpecs := func(clusterDef *appsv1.ClusterDefinition, cluster *appsv1alpha1.Cluster) []*appsv1alpha1.ClusterComponentSpec { apiTransformer := ClusterAPINormalizationTransformer{} compSpecs, err := apiTransformer.buildCompSpecs4Topology(clusterDef, cluster) Expect(err).Should(BeNil()) diff --git a/controllers/apps/transformer_cluster_deletion_test.go b/controllers/apps/transformer_cluster_deletion_test.go index 400110e3ea0..a2820ece9e3 100644 --- a/controllers/apps/transformer_cluster_deletion_test.go +++ b/controllers/apps/transformer_cluster_deletion_test.go @@ -29,6 +29,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/client" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" "github.com/apecloud/kubeblocks/pkg/controller/graph" "github.com/apecloud/kubeblocks/pkg/controller/model" @@ -40,7 +41,7 @@ var _ = Describe("clusterDeletionTransformer", func() { transCtx *clusterTransformContext reader client.Reader dag *graph.DAG - clusterDef *appsv1alpha1.ClusterDefinition + clusterDef *appsv1.ClusterDefinition cluster *appsv1alpha1.Cluster ) @@ -52,19 +53,19 @@ var _ = Describe("clusterDeletionTransformer", func() { BeforeEach(func() { clusterDef = testapps.NewClusterDefFactory("test-clusterdef"). - AddClusterTopology(appsv1alpha1.ClusterTopology{ + AddClusterTopology(appsv1.ClusterTopology{ Name: "default", - Components: []appsv1alpha1.ClusterTopologyComponent{ + Components: []appsv1.ClusterTopologyComponent{ {Name: "comp1", CompDef: "compdef1"}, {Name: "comp2", CompDef: "compdef2"}, {Name: "comp3", CompDef: "compdef3"}, }, - Orders: &appsv1alpha1.ClusterTopologyOrders{ + Orders: &appsv1.ClusterTopologyOrders{ Terminate: []string{"comp1", "comp2", "comp3"}, }, }). GetObject() - clusterDef.Status.Phase = appsv1alpha1.AvailablePhase + clusterDef.Status.Phase = appsv1.AvailablePhase cluster = testapps.NewClusterFactory(testCtx.DefaultNamespace, "test-cluster", clusterDef.Name). SetTopology(clusterDef.Spec.Topologies[0].Name). diff --git a/controllers/apps/transformer_cluster_load_resources.go b/controllers/apps/transformer_cluster_load_resources.go index a7c093281a4..46f6578990f 100644 --- a/controllers/apps/transformer_cluster_load_resources.go +++ b/controllers/apps/transformer_cluster_load_resources.go @@ -24,6 +24,7 @@ import ( "k8s.io/apimachinery/pkg/types" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" "github.com/apecloud/kubeblocks/pkg/controller/graph" "github.com/apecloud/kubeblocks/pkg/generics" @@ -96,9 +97,9 @@ func (t *clusterLoadRefResourcesTransformer) checkNUpdateClusterTopology(transCt } func loadNCheckClusterDefinition(transCtx *clusterTransformContext, cluster *appsv1alpha1.Cluster) error { - var cd *appsv1alpha1.ClusterDefinition + var cd *appsv1.ClusterDefinition if len(cluster.Spec.ClusterDefRef) > 0 { - cd = &appsv1alpha1.ClusterDefinition{} + cd = &appsv1.ClusterDefinition{} key := types.NamespacedName{Name: cluster.Spec.ClusterDefRef} if err := transCtx.Client.Get(transCtx.Context, key, cd); err != nil { return err @@ -109,13 +110,13 @@ func loadNCheckClusterDefinition(transCtx *clusterTransformContext, cluster *app if cd.Generation != cd.Status.ObservedGeneration { return fmt.Errorf("the referenced ClusterDefinition is not up to date: %s", cd.Name) } - if cd.Status.Phase != appsv1alpha1.AvailablePhase { + if cd.Status.Phase != appsv1.AvailablePhase { return fmt.Errorf("the referenced ClusterDefinition is unavailable: %s", cd.Name) } } if cd == nil { - cd = &appsv1alpha1.ClusterDefinition{} + cd = &appsv1.ClusterDefinition{} } transCtx.ClusterDef = cd return nil diff --git a/deploy/helm/crds/apps.kubeblocks.io_clusterdefinitions.yaml b/deploy/helm/crds/apps.kubeblocks.io_clusterdefinitions.yaml index a626e4fb376..133edfc7b7d 100644 --- a/deploy/helm/crds/apps.kubeblocks.io_clusterdefinitions.yaml +++ b/deploy/helm/crds/apps.kubeblocks.io_clusterdefinitions.yaml @@ -19,6 +19,190 @@ spec: singular: clusterdefinition scope: Cluster versions: + - additionalPrinterColumns: + - description: topologies + jsonPath: .status.topologies + name: Topologies + type: string + - description: status phase + jsonPath: .status.phase + name: STATUS + type: string + - jsonPath: .metadata.creationTimestamp + name: AGE + type: date + name: v1 + schema: + openAPIV3Schema: + description: |- + ClusterDefinition defines the topology for databases or storage systems, + offering a variety of topological configurations to meet diverse deployment needs and scenarios. + + + It includes a list of Components, each linked to a ComponentDefinition, which enhances reusability and reduce redundancy. + For example, widely used components such as etcd and Zookeeper can be defined once and reused across multiple ClusterDefinitions, + simplifying the setup of new systems. + + + Additionally, ClusterDefinition also specifies the sequence of startup, upgrade, and shutdown for Components, + ensuring a controlled and predictable management of component lifecycles. + 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: ClusterDefinitionSpec defines the desired state of ClusterDefinition. + properties: + topologies: + description: Topologies defines all possible topologies within the + cluster. + items: + description: ClusterTopology represents the definition for a specific + cluster topology. + properties: + components: + description: Components specifies the components in the topology. + items: + description: ClusterTopologyComponent defines a Component + within a ClusterTopology. + properties: + compDef: + description: |- + Specifies the name or prefix of the ComponentDefinition custom resource(CR) that + defines the Component's characteristics and behavior. + + + When a prefix is used, the system selects the ComponentDefinition CR with the latest version that matches the prefix. + This approach allows: + + + 1. Precise selection by providing the exact name of a ComponentDefinition CR. + 2. Flexible and automatic selection of the most up-to-date ComponentDefinition CR by specifying a prefix. + + + Once set, this field cannot be updated. + maxLength: 64 + type: string + name: + description: |- + Defines the unique identifier of the component within the cluster topology. + It follows IANA Service naming rules and is used as part of the Service's DNS name. + The name must start with a lowercase letter, can contain lowercase letters, numbers, + and hyphens, and must end with a lowercase letter or number. + + + Cannot be updated once set. + maxLength: 16 + pattern: ^[a-z]([a-z0-9\-]*[a-z0-9])?$ + type: string + required: + - compDef + - name + type: object + maxItems: 128 + minItems: 1 + type: array + default: + description: |- + Default indicates whether this topology serves as the default configuration. + When set to true, this topology is automatically used unless another is explicitly specified. + type: boolean + name: + description: |- + Name is the unique identifier for the cluster topology. + Cannot be updated. + maxLength: 32 + type: string + orders: + description: |- + Specifies the sequence in which components within a cluster topology are + started, stopped, and upgraded. + This ordering is crucial for maintaining the correct dependencies and operational flow across components. + properties: + provision: + description: |- + Specifies the order for creating and initializing components. + This is designed for components that depend on one another. Components without dependencies can be grouped together. + + + Components that can be provisioned independently or have no dependencies can be listed together in the same stage, + separated by commas. + items: + type: string + type: array + terminate: + description: |- + Outlines the order for stopping and deleting components. + This sequence is designed for components that require a graceful shutdown or have interdependencies. + + + Components that can be terminated independently or have no dependencies can be listed together in the same stage, + separated by commas. + items: + type: string + type: array + update: + description: |- + Update determines the order for updating components' specifications, such as image upgrades or resource scaling. + This sequence is designed for components that have dependencies or require specific update procedures. + + + Components that can be updated independently or have no dependencies can be listed together in the same stage, + separated by commas. + items: + type: string + type: array + type: object + required: + - components + - name + type: object + maxItems: 128 + minItems: 1 + type: array + type: object + status: + description: ClusterDefinitionStatus defines the observed state of ClusterDefinition + properties: + message: + description: Provides additional information about the current phase. + type: string + observedGeneration: + description: Represents the most recent generation observed for this + ClusterDefinition. + format: int64 + type: integer + phase: + description: |- + Specifies the current phase of the ClusterDefinition. Valid values are `empty`, `Available`, `Unavailable`. + When `Available`, the ClusterDefinition is ready and can be referenced by related objects. + enum: + - Available + - Unavailable + type: string + topologies: + description: Topologies this ClusterDefinition supported. + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} - additionalPrinterColumns: - description: topologies jsonPath: .status.topologies @@ -207,6 +391,6 @@ spec: type: object type: object served: true - storage: true + storage: false subresources: status: {} diff --git a/docs/developer_docs/api-reference/cluster.md b/docs/developer_docs/api-reference/cluster.md index f18a39eb21a..a65cc264249 100644 --- a/docs/developer_docs/api-reference/cluster.md +++ b/docs/developer_docs/api-reference/cluster.md @@ -26,8 +26,102 @@ sidebar_label: Cluster Resource Types: +

ClusterDefinition +

+
+

ClusterDefinition defines the topology for databases or storage systems, +offering a variety of topological configurations to meet diverse deployment needs and scenarios.

+

It includes a list of Components, each linked to a ComponentDefinition, which enhances reusability and reduce redundancy. +For example, widely used components such as etcd and Zookeeper can be defined once and reused across multiple ClusterDefinitions, +simplifying the setup of new systems.

+

Additionally, ClusterDefinition also specifies the sequence of startup, upgrade, and shutdown for Components, +ensuring a controlled and predictable management of component lifecycles.

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+apiVersion
+string
+apps.kubeblocks.io/v1 +
+kind
+string +
ClusterDefinition
+metadata
+ + +Kubernetes meta/v1.ObjectMeta + + +
+Refer to the Kubernetes API documentation for the fields of the +metadata field. +
+spec
+ + +ClusterDefinitionSpec + + +
+
+
+ + + + + +
+topologies
+ + +[]ClusterTopology + + +
+(Optional) +

Topologies defines all possible topologies within the cluster.

+
+
+status
+ + +ClusterDefinitionStatus + + +
+

ServiceDescriptor

@@ -194,6 +288,297 @@ ServiceDescriptorStatus +

ClusterDefinitionSpec +

+

+(Appears on:ClusterDefinition) +

+
+

ClusterDefinitionSpec defines the desired state of ClusterDefinition.

+
+ + + + + + + + + + + + + +
FieldDescription
+topologies
+ + +[]ClusterTopology + + +
+(Optional) +

Topologies defines all possible topologies within the cluster.

+
+

ClusterDefinitionStatus +

+

+(Appears on:ClusterDefinition) +

+
+

ClusterDefinitionStatus defines the observed state of ClusterDefinition

+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+observedGeneration
+ +int64 + +
+(Optional) +

Represents the most recent generation observed for this ClusterDefinition.

+
+phase
+ + +Phase + + +
+

Specifies the current phase of the ClusterDefinition. Valid values are empty, Available, Unavailable. +When Available, the ClusterDefinition is ready and can be referenced by related objects.

+
+message
+ +string + +
+(Optional) +

Provides additional information about the current phase.

+
+topologies
+ +string + +
+(Optional) +

Topologies this ClusterDefinition supported.

+
+

ClusterTopology +

+

+(Appears on:ClusterDefinitionSpec) +

+
+

ClusterTopology represents the definition for a specific cluster topology.

+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+name
+ +string + +
+

Name is the unique identifier for the cluster topology. +Cannot be updated.

+
+components
+ + +[]ClusterTopologyComponent + + +
+

Components specifies the components in the topology.

+
+orders
+ + +ClusterTopologyOrders + + +
+(Optional) +

Specifies the sequence in which components within a cluster topology are +started, stopped, and upgraded. +This ordering is crucial for maintaining the correct dependencies and operational flow across components.

+
+default
+ +bool + +
+(Optional) +

Default indicates whether this topology serves as the default configuration. +When set to true, this topology is automatically used unless another is explicitly specified.

+
+

ClusterTopologyComponent +

+

+(Appears on:ClusterTopology) +

+
+

ClusterTopologyComponent defines a Component within a ClusterTopology.

+
+ + + + + + + + + + + + + + + + + +
FieldDescription
+name
+ +string + +
+

Defines the unique identifier of the component within the cluster topology. +It follows IANA Service naming rules and is used as part of the Service’s DNS name. +The name must start with a lowercase letter, can contain lowercase letters, numbers, +and hyphens, and must end with a lowercase letter or number.

+

Cannot be updated once set.

+
+compDef
+ +string + +
+

Specifies the name or prefix of the ComponentDefinition custom resource(CR) that +defines the Component’s characteristics and behavior.

+

When a prefix is used, the system selects the ComponentDefinition CR with the latest version that matches the prefix. +This approach allows:

+
    +
  1. Precise selection by providing the exact name of a ComponentDefinition CR.
  2. +
  3. Flexible and automatic selection of the most up-to-date ComponentDefinition CR by specifying a prefix.
  4. +
+

Once set, this field cannot be updated.

+
+

ClusterTopologyOrders +

+

+(Appears on:ClusterTopology) +

+
+

ClusterTopologyOrders manages the lifecycle of components within a cluster by defining their provisioning, +terminating, and updating sequences. +It organizes components into stages or groups, where each group indicates a set of components +that can be managed concurrently. +These groups are processed sequentially, allowing precise control based on component dependencies and requirements.

+
+ + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+provision
+ +[]string + +
+(Optional) +

Specifies the order for creating and initializing components. +This is designed for components that depend on one another. Components without dependencies can be grouped together.

+

Components that can be provisioned independently or have no dependencies can be listed together in the same stage, +separated by commas.

+
+terminate
+ +[]string + +
+(Optional) +

Outlines the order for stopping and deleting components. +This sequence is designed for components that require a graceful shutdown or have interdependencies.

+

Components that can be terminated independently or have no dependencies can be listed together in the same stage, +separated by commas.

+
+update
+ +[]string + +
+(Optional) +

Update determines the order for updating components’ specifications, such as image upgrades or resource scaling. +This sequence is designed for components that have dependencies or require specific update procedures.

+

Components that can be updated independently or have no dependencies can be listed together in the same stage, +separated by commas.

+

ConnectionCredentialAuth

@@ -299,7 +684,7 @@ Kubernetes core/v1.EnvVarSource

Phase (string alias)

-(Appears on:ServiceDescriptorStatus) +(Appears on:ClusterDefinitionStatus, ServiceDescriptorStatus)

Phase represents the status of a CR.

diff --git a/hack/client-sdk-gen.sh b/hack/client-sdk-gen.sh index 46ade88241c..ce3d9d5f899 100755 --- a/hack/client-sdk-gen.sh +++ b/hack/client-sdk-gen.sh @@ -32,7 +32,7 @@ chmod u+x ${CODE_GENERATOR_PATH}/*.sh GENERATORS="client,informer,lister" OUTPUT_PACKAGE="github.com/apecloud/kubeblocks/pkg/client" APIS_PACKAGE="github.com/apecloud/kubeblocks/apis" -GROUP_VERSIONS="apps:v1alpha1 dataprotection:v1alpha1 extensions:v1alpha1 workloads:v1alpha1 apps:v1beta1" +GROUP_VERSIONS="apps:v1alpha1 apps:v1beta1 apps:v1 dataprotection:v1alpha1 extensions:v1alpha1 workloads:v1alpha1" OUTPUT_BASE="${SCRIPT_ROOT}/hack" @@ -47,4 +47,3 @@ bash ${CODE_GENERATOR_PATH}/generate-groups.sh \ rm -rf "${SCRIPT_ROOT}/pkg/client" mv "${OUTPUT_BASE}/${OUTPUT_PACKAGE}" "${SCRIPT_ROOT}/pkg/client" rm -rf "${OUTPUT_BASE}/github.com" - diff --git a/pkg/client/clientset/versioned/clientset.go b/pkg/client/clientset/versioned/clientset.go index a980d853187..a7b93e6756f 100644 --- a/pkg/client/clientset/versioned/clientset.go +++ b/pkg/client/clientset/versioned/clientset.go @@ -22,6 +22,7 @@ import ( "fmt" "net/http" + appsv1 "github.com/apecloud/kubeblocks/pkg/client/clientset/versioned/typed/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/pkg/client/clientset/versioned/typed/apps/v1alpha1" appsv1beta1 "github.com/apecloud/kubeblocks/pkg/client/clientset/versioned/typed/apps/v1beta1" dataprotectionv1alpha1 "github.com/apecloud/kubeblocks/pkg/client/clientset/versioned/typed/dataprotection/v1alpha1" @@ -36,6 +37,7 @@ type Interface interface { Discovery() discovery.DiscoveryInterface AppsV1alpha1() appsv1alpha1.AppsV1alpha1Interface AppsV1beta1() appsv1beta1.AppsV1beta1Interface + AppsV1() appsv1.AppsV1Interface DataprotectionV1alpha1() dataprotectionv1alpha1.DataprotectionV1alpha1Interface ExtensionsV1alpha1() extensionsv1alpha1.ExtensionsV1alpha1Interface WorkloadsV1alpha1() workloadsv1alpha1.WorkloadsV1alpha1Interface @@ -46,6 +48,7 @@ type Clientset struct { *discovery.DiscoveryClient appsV1alpha1 *appsv1alpha1.AppsV1alpha1Client appsV1beta1 *appsv1beta1.AppsV1beta1Client + appsV1 *appsv1.AppsV1Client dataprotectionV1alpha1 *dataprotectionv1alpha1.DataprotectionV1alpha1Client extensionsV1alpha1 *extensionsv1alpha1.ExtensionsV1alpha1Client workloadsV1alpha1 *workloadsv1alpha1.WorkloadsV1alpha1Client @@ -61,6 +64,11 @@ func (c *Clientset) AppsV1beta1() appsv1beta1.AppsV1beta1Interface { return c.appsV1beta1 } +// AppsV1 retrieves the AppsV1Client +func (c *Clientset) AppsV1() appsv1.AppsV1Interface { + return c.appsV1 +} + // DataprotectionV1alpha1 retrieves the DataprotectionV1alpha1Client func (c *Clientset) DataprotectionV1alpha1() dataprotectionv1alpha1.DataprotectionV1alpha1Interface { return c.dataprotectionV1alpha1 @@ -128,6 +136,10 @@ func NewForConfigAndClient(c *rest.Config, httpClient *http.Client) (*Clientset, if err != nil { return nil, err } + cs.appsV1, err = appsv1.NewForConfigAndClient(&configShallowCopy, httpClient) + if err != nil { + return nil, err + } cs.dataprotectionV1alpha1, err = dataprotectionv1alpha1.NewForConfigAndClient(&configShallowCopy, httpClient) if err != nil { return nil, err @@ -163,6 +175,7 @@ func New(c rest.Interface) *Clientset { var cs Clientset cs.appsV1alpha1 = appsv1alpha1.New(c) cs.appsV1beta1 = appsv1beta1.New(c) + cs.appsV1 = appsv1.New(c) cs.dataprotectionV1alpha1 = dataprotectionv1alpha1.New(c) cs.extensionsV1alpha1 = extensionsv1alpha1.New(c) cs.workloadsV1alpha1 = workloadsv1alpha1.New(c) diff --git a/pkg/client/clientset/versioned/fake/clientset_generated.go b/pkg/client/clientset/versioned/fake/clientset_generated.go index bf45fc093c4..1d5d8e85a9c 100644 --- a/pkg/client/clientset/versioned/fake/clientset_generated.go +++ b/pkg/client/clientset/versioned/fake/clientset_generated.go @@ -20,6 +20,8 @@ package fake import ( clientset "github.com/apecloud/kubeblocks/pkg/client/clientset/versioned" + appsv1 "github.com/apecloud/kubeblocks/pkg/client/clientset/versioned/typed/apps/v1" + fakeappsv1 "github.com/apecloud/kubeblocks/pkg/client/clientset/versioned/typed/apps/v1/fake" appsv1alpha1 "github.com/apecloud/kubeblocks/pkg/client/clientset/versioned/typed/apps/v1alpha1" fakeappsv1alpha1 "github.com/apecloud/kubeblocks/pkg/client/clientset/versioned/typed/apps/v1alpha1/fake" appsv1beta1 "github.com/apecloud/kubeblocks/pkg/client/clientset/versioned/typed/apps/v1beta1" @@ -97,6 +99,11 @@ func (c *Clientset) AppsV1beta1() appsv1beta1.AppsV1beta1Interface { return &fakeappsv1beta1.FakeAppsV1beta1{Fake: &c.Fake} } +// AppsV1 retrieves the AppsV1Client +func (c *Clientset) AppsV1() appsv1.AppsV1Interface { + return &fakeappsv1.FakeAppsV1{Fake: &c.Fake} +} + // DataprotectionV1alpha1 retrieves the DataprotectionV1alpha1Client func (c *Clientset) DataprotectionV1alpha1() dataprotectionv1alpha1.DataprotectionV1alpha1Interface { return &fakedataprotectionv1alpha1.FakeDataprotectionV1alpha1{Fake: &c.Fake} diff --git a/pkg/client/clientset/versioned/fake/register.go b/pkg/client/clientset/versioned/fake/register.go index 46068107fa2..b4e4ed192ed 100644 --- a/pkg/client/clientset/versioned/fake/register.go +++ b/pkg/client/clientset/versioned/fake/register.go @@ -19,6 +19,7 @@ limitations under the License. package fake import ( + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" appsv1beta1 "github.com/apecloud/kubeblocks/apis/apps/v1beta1" dataprotectionv1alpha1 "github.com/apecloud/kubeblocks/apis/dataprotection/v1alpha1" @@ -37,6 +38,7 @@ var codecs = serializer.NewCodecFactory(scheme) var localSchemeBuilder = runtime.SchemeBuilder{ appsv1alpha1.AddToScheme, appsv1beta1.AddToScheme, + appsv1.AddToScheme, dataprotectionv1alpha1.AddToScheme, extensionsv1alpha1.AddToScheme, workloadsv1alpha1.AddToScheme, diff --git a/pkg/client/clientset/versioned/scheme/register.go b/pkg/client/clientset/versioned/scheme/register.go index 5a67ccb25e9..f59c8386928 100644 --- a/pkg/client/clientset/versioned/scheme/register.go +++ b/pkg/client/clientset/versioned/scheme/register.go @@ -19,6 +19,7 @@ limitations under the License. package scheme import ( + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" appsv1beta1 "github.com/apecloud/kubeblocks/apis/apps/v1beta1" dataprotectionv1alpha1 "github.com/apecloud/kubeblocks/apis/dataprotection/v1alpha1" @@ -37,6 +38,7 @@ var ParameterCodec = runtime.NewParameterCodec(Scheme) var localSchemeBuilder = runtime.SchemeBuilder{ appsv1alpha1.AddToScheme, appsv1beta1.AddToScheme, + appsv1.AddToScheme, dataprotectionv1alpha1.AddToScheme, extensionsv1alpha1.AddToScheme, workloadsv1alpha1.AddToScheme, diff --git a/pkg/client/clientset/versioned/typed/apps/v1/apps_client.go b/pkg/client/clientset/versioned/typed/apps/v1/apps_client.go new file mode 100644 index 00000000000..0686d328598 --- /dev/null +++ b/pkg/client/clientset/versioned/typed/apps/v1/apps_client.go @@ -0,0 +1,112 @@ +/* +Copyright (C) 2022-2024 ApeCloud Co., Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1 + +import ( + "net/http" + + v1 "github.com/apecloud/kubeblocks/apis/apps/v1" + "github.com/apecloud/kubeblocks/pkg/client/clientset/versioned/scheme" + rest "k8s.io/client-go/rest" +) + +type AppsV1Interface interface { + RESTClient() rest.Interface + ClusterDefinitionsGetter + ServiceDescriptorsGetter +} + +// AppsV1Client is used to interact with features provided by the apps.kubeblocks.io group. +type AppsV1Client struct { + restClient rest.Interface +} + +func (c *AppsV1Client) ClusterDefinitions() ClusterDefinitionInterface { + return newClusterDefinitions(c) +} + +func (c *AppsV1Client) ServiceDescriptors(namespace string) ServiceDescriptorInterface { + return newServiceDescriptors(c, namespace) +} + +// NewForConfig creates a new AppsV1Client for the given config. +// NewForConfig is equivalent to NewForConfigAndClient(c, httpClient), +// where httpClient was generated with rest.HTTPClientFor(c). +func NewForConfig(c *rest.Config) (*AppsV1Client, error) { + config := *c + if err := setConfigDefaults(&config); err != nil { + return nil, err + } + httpClient, err := rest.HTTPClientFor(&config) + if err != nil { + return nil, err + } + return NewForConfigAndClient(&config, httpClient) +} + +// NewForConfigAndClient creates a new AppsV1Client for the given config and http client. +// Note the http client provided takes precedence over the configured transport values. +func NewForConfigAndClient(c *rest.Config, h *http.Client) (*AppsV1Client, error) { + config := *c + if err := setConfigDefaults(&config); err != nil { + return nil, err + } + client, err := rest.RESTClientForConfigAndClient(&config, h) + if err != nil { + return nil, err + } + return &AppsV1Client{client}, nil +} + +// NewForConfigOrDie creates a new AppsV1Client for the given config and +// panics if there is an error in the config. +func NewForConfigOrDie(c *rest.Config) *AppsV1Client { + client, err := NewForConfig(c) + if err != nil { + panic(err) + } + return client +} + +// New creates a new AppsV1Client for the given RESTClient. +func New(c rest.Interface) *AppsV1Client { + return &AppsV1Client{c} +} + +func setConfigDefaults(config *rest.Config) error { + gv := v1.SchemeGroupVersion + config.GroupVersion = &gv + config.APIPath = "/apis" + config.NegotiatedSerializer = scheme.Codecs.WithoutConversion() + + if config.UserAgent == "" { + config.UserAgent = rest.DefaultKubernetesUserAgent() + } + + return nil +} + +// RESTClient returns a RESTClient that is used to communicate +// with API server by this client implementation. +func (c *AppsV1Client) RESTClient() rest.Interface { + if c == nil { + return nil + } + return c.restClient +} diff --git a/pkg/client/clientset/versioned/typed/apps/v1/clusterdefinition.go b/pkg/client/clientset/versioned/typed/apps/v1/clusterdefinition.go new file mode 100644 index 00000000000..91e490a5388 --- /dev/null +++ b/pkg/client/clientset/versioned/typed/apps/v1/clusterdefinition.go @@ -0,0 +1,184 @@ +/* +Copyright (C) 2022-2024 ApeCloud Co., Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1 + +import ( + "context" + "time" + + v1 "github.com/apecloud/kubeblocks/apis/apps/v1" + scheme "github.com/apecloud/kubeblocks/pkg/client/clientset/versioned/scheme" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + rest "k8s.io/client-go/rest" +) + +// ClusterDefinitionsGetter has a method to return a ClusterDefinitionInterface. +// A group's client should implement this interface. +type ClusterDefinitionsGetter interface { + ClusterDefinitions() ClusterDefinitionInterface +} + +// ClusterDefinitionInterface has methods to work with ClusterDefinition resources. +type ClusterDefinitionInterface interface { + Create(ctx context.Context, clusterDefinition *v1.ClusterDefinition, opts metav1.CreateOptions) (*v1.ClusterDefinition, error) + Update(ctx context.Context, clusterDefinition *v1.ClusterDefinition, opts metav1.UpdateOptions) (*v1.ClusterDefinition, error) + UpdateStatus(ctx context.Context, clusterDefinition *v1.ClusterDefinition, opts metav1.UpdateOptions) (*v1.ClusterDefinition, error) + Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error + Get(ctx context.Context, name string, opts metav1.GetOptions) (*v1.ClusterDefinition, error) + List(ctx context.Context, opts metav1.ListOptions) (*v1.ClusterDefinitionList, error) + Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.ClusterDefinition, err error) + ClusterDefinitionExpansion +} + +// clusterDefinitions implements ClusterDefinitionInterface +type clusterDefinitions struct { + client rest.Interface +} + +// newClusterDefinitions returns a ClusterDefinitions +func newClusterDefinitions(c *AppsV1Client) *clusterDefinitions { + return &clusterDefinitions{ + client: c.RESTClient(), + } +} + +// Get takes name of the clusterDefinition, and returns the corresponding clusterDefinition object, and an error if there is any. +func (c *clusterDefinitions) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.ClusterDefinition, err error) { + result = &v1.ClusterDefinition{} + err = c.client.Get(). + Resource("clusterdefinitions"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(ctx). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of ClusterDefinitions that match those selectors. +func (c *clusterDefinitions) List(ctx context.Context, opts metav1.ListOptions) (result *v1.ClusterDefinitionList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1.ClusterDefinitionList{} + err = c.client.Get(). + Resource("clusterdefinitions"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(ctx). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested clusterDefinitions. +func (c *clusterDefinitions) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + opts.Watch = true + return c.client.Get(). + Resource("clusterdefinitions"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch(ctx) +} + +// Create takes the representation of a clusterDefinition and creates it. Returns the server's representation of the clusterDefinition, and an error, if there is any. +func (c *clusterDefinitions) Create(ctx context.Context, clusterDefinition *v1.ClusterDefinition, opts metav1.CreateOptions) (result *v1.ClusterDefinition, err error) { + result = &v1.ClusterDefinition{} + err = c.client.Post(). + Resource("clusterdefinitions"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(clusterDefinition). + Do(ctx). + Into(result) + return +} + +// Update takes the representation of a clusterDefinition and updates it. Returns the server's representation of the clusterDefinition, and an error, if there is any. +func (c *clusterDefinitions) Update(ctx context.Context, clusterDefinition *v1.ClusterDefinition, opts metav1.UpdateOptions) (result *v1.ClusterDefinition, err error) { + result = &v1.ClusterDefinition{} + err = c.client.Put(). + Resource("clusterdefinitions"). + Name(clusterDefinition.Name). + VersionedParams(&opts, scheme.ParameterCodec). + Body(clusterDefinition). + Do(ctx). + Into(result) + return +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *clusterDefinitions) UpdateStatus(ctx context.Context, clusterDefinition *v1.ClusterDefinition, opts metav1.UpdateOptions) (result *v1.ClusterDefinition, err error) { + result = &v1.ClusterDefinition{} + err = c.client.Put(). + Resource("clusterdefinitions"). + Name(clusterDefinition.Name). + SubResource("status"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(clusterDefinition). + Do(ctx). + Into(result) + return +} + +// Delete takes name of the clusterDefinition and deletes it. Returns an error if one occurs. +func (c *clusterDefinitions) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { + return c.client.Delete(). + Resource("clusterdefinitions"). + Name(name). + Body(&opts). + Do(ctx). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *clusterDefinitions) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { + var timeout time.Duration + if listOpts.TimeoutSeconds != nil { + timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Resource("clusterdefinitions"). + VersionedParams(&listOpts, scheme.ParameterCodec). + Timeout(timeout). + Body(&opts). + Do(ctx). + Error() +} + +// Patch applies the patch and returns the patched clusterDefinition. +func (c *clusterDefinitions) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.ClusterDefinition, err error) { + result = &v1.ClusterDefinition{} + err = c.client.Patch(pt). + Resource("clusterdefinitions"). + Name(name). + SubResource(subresources...). + VersionedParams(&opts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} diff --git a/pkg/client/clientset/versioned/typed/apps/v1/doc.go b/pkg/client/clientset/versioned/typed/apps/v1/doc.go new file mode 100644 index 00000000000..8a483cc3601 --- /dev/null +++ b/pkg/client/clientset/versioned/typed/apps/v1/doc.go @@ -0,0 +1,20 @@ +/* +Copyright (C) 2022-2024 ApeCloud Co., Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +// This package has the automatically generated typed clients. +package v1 diff --git a/pkg/client/clientset/versioned/typed/apps/v1/fake/doc.go b/pkg/client/clientset/versioned/typed/apps/v1/fake/doc.go new file mode 100644 index 00000000000..a68eddec4bb --- /dev/null +++ b/pkg/client/clientset/versioned/typed/apps/v1/fake/doc.go @@ -0,0 +1,20 @@ +/* +Copyright (C) 2022-2024 ApeCloud Co., Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +// Package fake has the automatically generated clients. +package fake diff --git a/pkg/client/clientset/versioned/typed/apps/v1/fake/fake_apps_client.go b/pkg/client/clientset/versioned/typed/apps/v1/fake/fake_apps_client.go new file mode 100644 index 00000000000..8af07ad5e70 --- /dev/null +++ b/pkg/client/clientset/versioned/typed/apps/v1/fake/fake_apps_client.go @@ -0,0 +1,44 @@ +/* +Copyright (C) 2022-2024 ApeCloud Co., Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + v1 "github.com/apecloud/kubeblocks/pkg/client/clientset/versioned/typed/apps/v1" + rest "k8s.io/client-go/rest" + testing "k8s.io/client-go/testing" +) + +type FakeAppsV1 struct { + *testing.Fake +} + +func (c *FakeAppsV1) ClusterDefinitions() v1.ClusterDefinitionInterface { + return &FakeClusterDefinitions{c} +} + +func (c *FakeAppsV1) ServiceDescriptors(namespace string) v1.ServiceDescriptorInterface { + return &FakeServiceDescriptors{c, namespace} +} + +// RESTClient returns a RESTClient that is used to communicate +// with API server by this client implementation. +func (c *FakeAppsV1) RESTClient() rest.Interface { + var ret *rest.RESTClient + return ret +} diff --git a/pkg/client/clientset/versioned/typed/apps/v1/fake/fake_clusterdefinition.go b/pkg/client/clientset/versioned/typed/apps/v1/fake/fake_clusterdefinition.go new file mode 100644 index 00000000000..afd0d57934e --- /dev/null +++ b/pkg/client/clientset/versioned/typed/apps/v1/fake/fake_clusterdefinition.go @@ -0,0 +1,132 @@ +/* +Copyright (C) 2022-2024 ApeCloud Co., Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + "context" + + v1 "github.com/apecloud/kubeblocks/apis/apps/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + labels "k8s.io/apimachinery/pkg/labels" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + testing "k8s.io/client-go/testing" +) + +// FakeClusterDefinitions implements ClusterDefinitionInterface +type FakeClusterDefinitions struct { + Fake *FakeAppsV1 +} + +var clusterdefinitionsResource = v1.SchemeGroupVersion.WithResource("clusterdefinitions") + +var clusterdefinitionsKind = v1.SchemeGroupVersion.WithKind("ClusterDefinition") + +// Get takes name of the clusterDefinition, and returns the corresponding clusterDefinition object, and an error if there is any. +func (c *FakeClusterDefinitions) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.ClusterDefinition, err error) { + obj, err := c.Fake. + Invokes(testing.NewRootGetAction(clusterdefinitionsResource, name), &v1.ClusterDefinition{}) + if obj == nil { + return nil, err + } + return obj.(*v1.ClusterDefinition), err +} + +// List takes label and field selectors, and returns the list of ClusterDefinitions that match those selectors. +func (c *FakeClusterDefinitions) List(ctx context.Context, opts metav1.ListOptions) (result *v1.ClusterDefinitionList, err error) { + obj, err := c.Fake. + Invokes(testing.NewRootListAction(clusterdefinitionsResource, clusterdefinitionsKind, opts), &v1.ClusterDefinitionList{}) + if obj == nil { + return nil, err + } + + label, _, _ := testing.ExtractFromListOptions(opts) + if label == nil { + label = labels.Everything() + } + list := &v1.ClusterDefinitionList{ListMeta: obj.(*v1.ClusterDefinitionList).ListMeta} + for _, item := range obj.(*v1.ClusterDefinitionList).Items { + if label.Matches(labels.Set(item.Labels)) { + list.Items = append(list.Items, item) + } + } + return list, err +} + +// Watch returns a watch.Interface that watches the requested clusterDefinitions. +func (c *FakeClusterDefinitions) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { + return c.Fake. + InvokesWatch(testing.NewRootWatchAction(clusterdefinitionsResource, opts)) +} + +// Create takes the representation of a clusterDefinition and creates it. Returns the server's representation of the clusterDefinition, and an error, if there is any. +func (c *FakeClusterDefinitions) Create(ctx context.Context, clusterDefinition *v1.ClusterDefinition, opts metav1.CreateOptions) (result *v1.ClusterDefinition, err error) { + obj, err := c.Fake. + Invokes(testing.NewRootCreateAction(clusterdefinitionsResource, clusterDefinition), &v1.ClusterDefinition{}) + if obj == nil { + return nil, err + } + return obj.(*v1.ClusterDefinition), err +} + +// Update takes the representation of a clusterDefinition and updates it. Returns the server's representation of the clusterDefinition, and an error, if there is any. +func (c *FakeClusterDefinitions) Update(ctx context.Context, clusterDefinition *v1.ClusterDefinition, opts metav1.UpdateOptions) (result *v1.ClusterDefinition, err error) { + obj, err := c.Fake. + Invokes(testing.NewRootUpdateAction(clusterdefinitionsResource, clusterDefinition), &v1.ClusterDefinition{}) + if obj == nil { + return nil, err + } + return obj.(*v1.ClusterDefinition), err +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *FakeClusterDefinitions) UpdateStatus(ctx context.Context, clusterDefinition *v1.ClusterDefinition, opts metav1.UpdateOptions) (*v1.ClusterDefinition, error) { + obj, err := c.Fake. + Invokes(testing.NewRootUpdateSubresourceAction(clusterdefinitionsResource, "status", clusterDefinition), &v1.ClusterDefinition{}) + if obj == nil { + return nil, err + } + return obj.(*v1.ClusterDefinition), err +} + +// Delete takes name of the clusterDefinition and deletes it. Returns an error if one occurs. +func (c *FakeClusterDefinitions) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { + _, err := c.Fake. + Invokes(testing.NewRootDeleteActionWithOptions(clusterdefinitionsResource, name, opts), &v1.ClusterDefinition{}) + return err +} + +// DeleteCollection deletes a collection of objects. +func (c *FakeClusterDefinitions) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { + action := testing.NewRootDeleteCollectionAction(clusterdefinitionsResource, listOpts) + + _, err := c.Fake.Invokes(action, &v1.ClusterDefinitionList{}) + return err +} + +// Patch applies the patch and returns the patched clusterDefinition. +func (c *FakeClusterDefinitions) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.ClusterDefinition, err error) { + obj, err := c.Fake. + Invokes(testing.NewRootPatchSubresourceAction(clusterdefinitionsResource, name, pt, data, subresources...), &v1.ClusterDefinition{}) + if obj == nil { + return nil, err + } + return obj.(*v1.ClusterDefinition), err +} diff --git a/pkg/client/clientset/versioned/typed/apps/v1/fake/fake_servicedescriptor.go b/pkg/client/clientset/versioned/typed/apps/v1/fake/fake_servicedescriptor.go new file mode 100644 index 00000000000..cb09fb3b526 --- /dev/null +++ b/pkg/client/clientset/versioned/typed/apps/v1/fake/fake_servicedescriptor.go @@ -0,0 +1,141 @@ +/* +Copyright (C) 2022-2024 ApeCloud Co., Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + "context" + + v1 "github.com/apecloud/kubeblocks/apis/apps/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + labels "k8s.io/apimachinery/pkg/labels" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + testing "k8s.io/client-go/testing" +) + +// FakeServiceDescriptors implements ServiceDescriptorInterface +type FakeServiceDescriptors struct { + Fake *FakeAppsV1 + ns string +} + +var servicedescriptorsResource = v1.SchemeGroupVersion.WithResource("servicedescriptors") + +var servicedescriptorsKind = v1.SchemeGroupVersion.WithKind("ServiceDescriptor") + +// Get takes name of the serviceDescriptor, and returns the corresponding serviceDescriptor object, and an error if there is any. +func (c *FakeServiceDescriptors) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.ServiceDescriptor, err error) { + obj, err := c.Fake. + Invokes(testing.NewGetAction(servicedescriptorsResource, c.ns, name), &v1.ServiceDescriptor{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.ServiceDescriptor), err +} + +// List takes label and field selectors, and returns the list of ServiceDescriptors that match those selectors. +func (c *FakeServiceDescriptors) List(ctx context.Context, opts metav1.ListOptions) (result *v1.ServiceDescriptorList, err error) { + obj, err := c.Fake. + Invokes(testing.NewListAction(servicedescriptorsResource, servicedescriptorsKind, c.ns, opts), &v1.ServiceDescriptorList{}) + + if obj == nil { + return nil, err + } + + label, _, _ := testing.ExtractFromListOptions(opts) + if label == nil { + label = labels.Everything() + } + list := &v1.ServiceDescriptorList{ListMeta: obj.(*v1.ServiceDescriptorList).ListMeta} + for _, item := range obj.(*v1.ServiceDescriptorList).Items { + if label.Matches(labels.Set(item.Labels)) { + list.Items = append(list.Items, item) + } + } + return list, err +} + +// Watch returns a watch.Interface that watches the requested serviceDescriptors. +func (c *FakeServiceDescriptors) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { + return c.Fake. + InvokesWatch(testing.NewWatchAction(servicedescriptorsResource, c.ns, opts)) + +} + +// Create takes the representation of a serviceDescriptor and creates it. Returns the server's representation of the serviceDescriptor, and an error, if there is any. +func (c *FakeServiceDescriptors) Create(ctx context.Context, serviceDescriptor *v1.ServiceDescriptor, opts metav1.CreateOptions) (result *v1.ServiceDescriptor, err error) { + obj, err := c.Fake. + Invokes(testing.NewCreateAction(servicedescriptorsResource, c.ns, serviceDescriptor), &v1.ServiceDescriptor{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.ServiceDescriptor), err +} + +// Update takes the representation of a serviceDescriptor and updates it. Returns the server's representation of the serviceDescriptor, and an error, if there is any. +func (c *FakeServiceDescriptors) Update(ctx context.Context, serviceDescriptor *v1.ServiceDescriptor, opts metav1.UpdateOptions) (result *v1.ServiceDescriptor, err error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateAction(servicedescriptorsResource, c.ns, serviceDescriptor), &v1.ServiceDescriptor{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.ServiceDescriptor), err +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *FakeServiceDescriptors) UpdateStatus(ctx context.Context, serviceDescriptor *v1.ServiceDescriptor, opts metav1.UpdateOptions) (*v1.ServiceDescriptor, error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateSubresourceAction(servicedescriptorsResource, "status", c.ns, serviceDescriptor), &v1.ServiceDescriptor{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.ServiceDescriptor), err +} + +// Delete takes name of the serviceDescriptor and deletes it. Returns an error if one occurs. +func (c *FakeServiceDescriptors) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { + _, err := c.Fake. + Invokes(testing.NewDeleteActionWithOptions(servicedescriptorsResource, c.ns, name, opts), &v1.ServiceDescriptor{}) + + return err +} + +// DeleteCollection deletes a collection of objects. +func (c *FakeServiceDescriptors) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { + action := testing.NewDeleteCollectionAction(servicedescriptorsResource, c.ns, listOpts) + + _, err := c.Fake.Invokes(action, &v1.ServiceDescriptorList{}) + return err +} + +// Patch applies the patch and returns the patched serviceDescriptor. +func (c *FakeServiceDescriptors) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.ServiceDescriptor, err error) { + obj, err := c.Fake. + Invokes(testing.NewPatchSubresourceAction(servicedescriptorsResource, c.ns, name, pt, data, subresources...), &v1.ServiceDescriptor{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.ServiceDescriptor), err +} diff --git a/pkg/client/clientset/versioned/typed/apps/v1/generated_expansion.go b/pkg/client/clientset/versioned/typed/apps/v1/generated_expansion.go new file mode 100644 index 00000000000..dc737a1279c --- /dev/null +++ b/pkg/client/clientset/versioned/typed/apps/v1/generated_expansion.go @@ -0,0 +1,23 @@ +/* +Copyright (C) 2022-2024 ApeCloud Co., Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1 + +type ClusterDefinitionExpansion interface{} + +type ServiceDescriptorExpansion interface{} diff --git a/pkg/client/clientset/versioned/typed/apps/v1/servicedescriptor.go b/pkg/client/clientset/versioned/typed/apps/v1/servicedescriptor.go new file mode 100644 index 00000000000..9b41a5300e2 --- /dev/null +++ b/pkg/client/clientset/versioned/typed/apps/v1/servicedescriptor.go @@ -0,0 +1,195 @@ +/* +Copyright (C) 2022-2024 ApeCloud Co., Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1 + +import ( + "context" + "time" + + v1 "github.com/apecloud/kubeblocks/apis/apps/v1" + scheme "github.com/apecloud/kubeblocks/pkg/client/clientset/versioned/scheme" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + rest "k8s.io/client-go/rest" +) + +// ServiceDescriptorsGetter has a method to return a ServiceDescriptorInterface. +// A group's client should implement this interface. +type ServiceDescriptorsGetter interface { + ServiceDescriptors(namespace string) ServiceDescriptorInterface +} + +// ServiceDescriptorInterface has methods to work with ServiceDescriptor resources. +type ServiceDescriptorInterface interface { + Create(ctx context.Context, serviceDescriptor *v1.ServiceDescriptor, opts metav1.CreateOptions) (*v1.ServiceDescriptor, error) + Update(ctx context.Context, serviceDescriptor *v1.ServiceDescriptor, opts metav1.UpdateOptions) (*v1.ServiceDescriptor, error) + UpdateStatus(ctx context.Context, serviceDescriptor *v1.ServiceDescriptor, opts metav1.UpdateOptions) (*v1.ServiceDescriptor, error) + Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error + Get(ctx context.Context, name string, opts metav1.GetOptions) (*v1.ServiceDescriptor, error) + List(ctx context.Context, opts metav1.ListOptions) (*v1.ServiceDescriptorList, error) + Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.ServiceDescriptor, err error) + ServiceDescriptorExpansion +} + +// serviceDescriptors implements ServiceDescriptorInterface +type serviceDescriptors struct { + client rest.Interface + ns string +} + +// newServiceDescriptors returns a ServiceDescriptors +func newServiceDescriptors(c *AppsV1Client, namespace string) *serviceDescriptors { + return &serviceDescriptors{ + client: c.RESTClient(), + ns: namespace, + } +} + +// Get takes name of the serviceDescriptor, and returns the corresponding serviceDescriptor object, and an error if there is any. +func (c *serviceDescriptors) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.ServiceDescriptor, err error) { + result = &v1.ServiceDescriptor{} + err = c.client.Get(). + Namespace(c.ns). + Resource("servicedescriptors"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(ctx). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of ServiceDescriptors that match those selectors. +func (c *serviceDescriptors) List(ctx context.Context, opts metav1.ListOptions) (result *v1.ServiceDescriptorList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1.ServiceDescriptorList{} + err = c.client.Get(). + Namespace(c.ns). + Resource("servicedescriptors"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(ctx). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested serviceDescriptors. +func (c *serviceDescriptors) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + opts.Watch = true + return c.client.Get(). + Namespace(c.ns). + Resource("servicedescriptors"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch(ctx) +} + +// Create takes the representation of a serviceDescriptor and creates it. Returns the server's representation of the serviceDescriptor, and an error, if there is any. +func (c *serviceDescriptors) Create(ctx context.Context, serviceDescriptor *v1.ServiceDescriptor, opts metav1.CreateOptions) (result *v1.ServiceDescriptor, err error) { + result = &v1.ServiceDescriptor{} + err = c.client.Post(). + Namespace(c.ns). + Resource("servicedescriptors"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(serviceDescriptor). + Do(ctx). + Into(result) + return +} + +// Update takes the representation of a serviceDescriptor and updates it. Returns the server's representation of the serviceDescriptor, and an error, if there is any. +func (c *serviceDescriptors) Update(ctx context.Context, serviceDescriptor *v1.ServiceDescriptor, opts metav1.UpdateOptions) (result *v1.ServiceDescriptor, err error) { + result = &v1.ServiceDescriptor{} + err = c.client.Put(). + Namespace(c.ns). + Resource("servicedescriptors"). + Name(serviceDescriptor.Name). + VersionedParams(&opts, scheme.ParameterCodec). + Body(serviceDescriptor). + Do(ctx). + Into(result) + return +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *serviceDescriptors) UpdateStatus(ctx context.Context, serviceDescriptor *v1.ServiceDescriptor, opts metav1.UpdateOptions) (result *v1.ServiceDescriptor, err error) { + result = &v1.ServiceDescriptor{} + err = c.client.Put(). + Namespace(c.ns). + Resource("servicedescriptors"). + Name(serviceDescriptor.Name). + SubResource("status"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(serviceDescriptor). + Do(ctx). + Into(result) + return +} + +// Delete takes name of the serviceDescriptor and deletes it. Returns an error if one occurs. +func (c *serviceDescriptors) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { + return c.client.Delete(). + Namespace(c.ns). + Resource("servicedescriptors"). + Name(name). + Body(&opts). + Do(ctx). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *serviceDescriptors) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { + var timeout time.Duration + if listOpts.TimeoutSeconds != nil { + timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Namespace(c.ns). + Resource("servicedescriptors"). + VersionedParams(&listOpts, scheme.ParameterCodec). + Timeout(timeout). + Body(&opts). + Do(ctx). + Error() +} + +// Patch applies the patch and returns the patched serviceDescriptor. +func (c *serviceDescriptors) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.ServiceDescriptor, err error) { + result = &v1.ServiceDescriptor{} + err = c.client.Patch(pt). + Namespace(c.ns). + Resource("servicedescriptors"). + Name(name). + SubResource(subresources...). + VersionedParams(&opts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} diff --git a/pkg/client/informers/externalversions/apps/interface.go b/pkg/client/informers/externalversions/apps/interface.go index 251195c0d4b..6afe6cb30f7 100644 --- a/pkg/client/informers/externalversions/apps/interface.go +++ b/pkg/client/informers/externalversions/apps/interface.go @@ -19,6 +19,7 @@ limitations under the License. package apps import ( + v1 "github.com/apecloud/kubeblocks/pkg/client/informers/externalversions/apps/v1" v1alpha1 "github.com/apecloud/kubeblocks/pkg/client/informers/externalversions/apps/v1alpha1" v1beta1 "github.com/apecloud/kubeblocks/pkg/client/informers/externalversions/apps/v1beta1" internalinterfaces "github.com/apecloud/kubeblocks/pkg/client/informers/externalversions/internalinterfaces" @@ -30,6 +31,8 @@ type Interface interface { V1alpha1() v1alpha1.Interface // V1beta1 provides access to shared informers for resources in V1beta1. V1beta1() v1beta1.Interface + // V1 provides access to shared informers for resources in V1. + V1() v1.Interface } type group struct { @@ -52,3 +55,8 @@ func (g *group) V1alpha1() v1alpha1.Interface { func (g *group) V1beta1() v1beta1.Interface { return v1beta1.New(g.factory, g.namespace, g.tweakListOptions) } + +// V1 returns a new v1.Interface. +func (g *group) V1() v1.Interface { + return v1.New(g.factory, g.namespace, g.tweakListOptions) +} diff --git a/pkg/client/informers/externalversions/apps/v1/clusterdefinition.go b/pkg/client/informers/externalversions/apps/v1/clusterdefinition.go new file mode 100644 index 00000000000..4bf604e184d --- /dev/null +++ b/pkg/client/informers/externalversions/apps/v1/clusterdefinition.go @@ -0,0 +1,89 @@ +/* +Copyright (C) 2022-2024 ApeCloud Co., Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1 + +import ( + "context" + time "time" + + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" + versioned "github.com/apecloud/kubeblocks/pkg/client/clientset/versioned" + internalinterfaces "github.com/apecloud/kubeblocks/pkg/client/informers/externalversions/internalinterfaces" + v1 "github.com/apecloud/kubeblocks/pkg/client/listers/apps/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + cache "k8s.io/client-go/tools/cache" +) + +// ClusterDefinitionInformer provides access to a shared informer and lister for +// ClusterDefinitions. +type ClusterDefinitionInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1.ClusterDefinitionLister +} + +type clusterDefinitionInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// NewClusterDefinitionInformer constructs a new informer for ClusterDefinition type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewClusterDefinitionInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredClusterDefinitionInformer(client, resyncPeriod, indexers, nil) +} + +// NewFilteredClusterDefinitionInformer constructs a new informer for ClusterDefinition type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredClusterDefinitionInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.AppsV1().ClusterDefinitions().List(context.TODO(), options) + }, + WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.AppsV1().ClusterDefinitions().Watch(context.TODO(), options) + }, + }, + &appsv1.ClusterDefinition{}, + resyncPeriod, + indexers, + ) +} + +func (f *clusterDefinitionInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredClusterDefinitionInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *clusterDefinitionInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&appsv1.ClusterDefinition{}, f.defaultInformer) +} + +func (f *clusterDefinitionInformer) Lister() v1.ClusterDefinitionLister { + return v1.NewClusterDefinitionLister(f.Informer().GetIndexer()) +} diff --git a/pkg/client/informers/externalversions/apps/v1/interface.go b/pkg/client/informers/externalversions/apps/v1/interface.go new file mode 100644 index 00000000000..0c45a6e9c0c --- /dev/null +++ b/pkg/client/informers/externalversions/apps/v1/interface.go @@ -0,0 +1,52 @@ +/* +Copyright (C) 2022-2024 ApeCloud Co., Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1 + +import ( + internalinterfaces "github.com/apecloud/kubeblocks/pkg/client/informers/externalversions/internalinterfaces" +) + +// Interface provides access to all the informers in this group version. +type Interface interface { + // ClusterDefinitions returns a ClusterDefinitionInformer. + ClusterDefinitions() ClusterDefinitionInformer + // ServiceDescriptors returns a ServiceDescriptorInformer. + ServiceDescriptors() ServiceDescriptorInformer +} + +type version struct { + factory internalinterfaces.SharedInformerFactory + namespace string + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// New returns a new Interface. +func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { + return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} +} + +// ClusterDefinitions returns a ClusterDefinitionInformer. +func (v *version) ClusterDefinitions() ClusterDefinitionInformer { + return &clusterDefinitionInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} +} + +// ServiceDescriptors returns a ServiceDescriptorInformer. +func (v *version) ServiceDescriptors() ServiceDescriptorInformer { + return &serviceDescriptorInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +} diff --git a/pkg/client/informers/externalversions/apps/v1/servicedescriptor.go b/pkg/client/informers/externalversions/apps/v1/servicedescriptor.go new file mode 100644 index 00000000000..70df06cd11e --- /dev/null +++ b/pkg/client/informers/externalversions/apps/v1/servicedescriptor.go @@ -0,0 +1,90 @@ +/* +Copyright (C) 2022-2024 ApeCloud Co., Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1 + +import ( + "context" + time "time" + + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" + versioned "github.com/apecloud/kubeblocks/pkg/client/clientset/versioned" + internalinterfaces "github.com/apecloud/kubeblocks/pkg/client/informers/externalversions/internalinterfaces" + v1 "github.com/apecloud/kubeblocks/pkg/client/listers/apps/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + cache "k8s.io/client-go/tools/cache" +) + +// ServiceDescriptorInformer provides access to a shared informer and lister for +// ServiceDescriptors. +type ServiceDescriptorInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1.ServiceDescriptorLister +} + +type serviceDescriptorInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewServiceDescriptorInformer constructs a new informer for ServiceDescriptor type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewServiceDescriptorInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredServiceDescriptorInformer(client, namespace, resyncPeriod, indexers, nil) +} + +// NewFilteredServiceDescriptorInformer constructs a new informer for ServiceDescriptor type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredServiceDescriptorInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.AppsV1().ServiceDescriptors(namespace).List(context.TODO(), options) + }, + WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.AppsV1().ServiceDescriptors(namespace).Watch(context.TODO(), options) + }, + }, + &appsv1.ServiceDescriptor{}, + resyncPeriod, + indexers, + ) +} + +func (f *serviceDescriptorInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredServiceDescriptorInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *serviceDescriptorInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&appsv1.ServiceDescriptor{}, f.defaultInformer) +} + +func (f *serviceDescriptorInformer) Lister() v1.ServiceDescriptorLister { + return v1.NewServiceDescriptorLister(f.Informer().GetIndexer()) +} diff --git a/pkg/client/informers/externalversions/generic.go b/pkg/client/informers/externalversions/generic.go index 61b613d66e9..c7677b5e66d 100644 --- a/pkg/client/informers/externalversions/generic.go +++ b/pkg/client/informers/externalversions/generic.go @@ -21,6 +21,7 @@ package externalversions import ( "fmt" + v1 "github.com/apecloud/kubeblocks/apis/apps/v1" v1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" v1beta1 "github.com/apecloud/kubeblocks/apis/apps/v1beta1" dataprotectionv1alpha1 "github.com/apecloud/kubeblocks/apis/dataprotection/v1alpha1" @@ -56,7 +57,13 @@ func (f *genericInformer) Lister() cache.GenericLister { // TODO extend this to unknown resources with a client pool func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource) (GenericInformer, error) { switch resource { - // Group=apps.kubeblocks.io, Version=v1alpha1 + // Group=apps.kubeblocks.io, Version=v1 + case v1.SchemeGroupVersion.WithResource("clusterdefinitions"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Apps().V1().ClusterDefinitions().Informer()}, nil + case v1.SchemeGroupVersion.WithResource("servicedescriptors"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Apps().V1().ServiceDescriptors().Informer()}, nil + + // Group=apps.kubeblocks.io, Version=v1alpha1 case v1alpha1.SchemeGroupVersion.WithResource("backuppolicytemplates"): return &genericInformer{resource: resource.GroupResource(), informer: f.Apps().V1alpha1().BackupPolicyTemplates().Informer()}, nil case v1alpha1.SchemeGroupVersion.WithResource("clusters"): diff --git a/pkg/client/listers/apps/v1/clusterdefinition.go b/pkg/client/listers/apps/v1/clusterdefinition.go new file mode 100644 index 00000000000..31c11eaf080 --- /dev/null +++ b/pkg/client/listers/apps/v1/clusterdefinition.go @@ -0,0 +1,68 @@ +/* +Copyright (C) 2022-2024 ApeCloud Co., Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1 + +import ( + v1 "github.com/apecloud/kubeblocks/apis/apps/v1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// ClusterDefinitionLister helps list ClusterDefinitions. +// All objects returned here must be treated as read-only. +type ClusterDefinitionLister interface { + // List lists all ClusterDefinitions in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1.ClusterDefinition, err error) + // Get retrieves the ClusterDefinition from the index for a given name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1.ClusterDefinition, error) + ClusterDefinitionListerExpansion +} + +// clusterDefinitionLister implements the ClusterDefinitionLister interface. +type clusterDefinitionLister struct { + indexer cache.Indexer +} + +// NewClusterDefinitionLister returns a new ClusterDefinitionLister. +func NewClusterDefinitionLister(indexer cache.Indexer) ClusterDefinitionLister { + return &clusterDefinitionLister{indexer: indexer} +} + +// List lists all ClusterDefinitions in the indexer. +func (s *clusterDefinitionLister) List(selector labels.Selector) (ret []*v1.ClusterDefinition, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1.ClusterDefinition)) + }) + return ret, err +} + +// Get retrieves the ClusterDefinition from the index for a given name. +func (s *clusterDefinitionLister) Get(name string) (*v1.ClusterDefinition, error) { + obj, exists, err := s.indexer.GetByKey(name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1.Resource("clusterdefinition"), name) + } + return obj.(*v1.ClusterDefinition), nil +} diff --git a/pkg/client/listers/apps/v1/expansion_generated.go b/pkg/client/listers/apps/v1/expansion_generated.go new file mode 100644 index 00000000000..6e13e0b4f33 --- /dev/null +++ b/pkg/client/listers/apps/v1/expansion_generated.go @@ -0,0 +1,31 @@ +/* +Copyright (C) 2022-2024 ApeCloud Co., Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1 + +// ClusterDefinitionListerExpansion allows custom methods to be added to +// ClusterDefinitionLister. +type ClusterDefinitionListerExpansion interface{} + +// ServiceDescriptorListerExpansion allows custom methods to be added to +// ServiceDescriptorLister. +type ServiceDescriptorListerExpansion interface{} + +// ServiceDescriptorNamespaceListerExpansion allows custom methods to be added to +// ServiceDescriptorNamespaceLister. +type ServiceDescriptorNamespaceListerExpansion interface{} diff --git a/pkg/client/listers/apps/v1/servicedescriptor.go b/pkg/client/listers/apps/v1/servicedescriptor.go new file mode 100644 index 00000000000..38bb7dd6669 --- /dev/null +++ b/pkg/client/listers/apps/v1/servicedescriptor.go @@ -0,0 +1,99 @@ +/* +Copyright (C) 2022-2024 ApeCloud Co., Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1 + +import ( + v1 "github.com/apecloud/kubeblocks/apis/apps/v1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// ServiceDescriptorLister helps list ServiceDescriptors. +// All objects returned here must be treated as read-only. +type ServiceDescriptorLister interface { + // List lists all ServiceDescriptors in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1.ServiceDescriptor, err error) + // ServiceDescriptors returns an object that can list and get ServiceDescriptors. + ServiceDescriptors(namespace string) ServiceDescriptorNamespaceLister + ServiceDescriptorListerExpansion +} + +// serviceDescriptorLister implements the ServiceDescriptorLister interface. +type serviceDescriptorLister struct { + indexer cache.Indexer +} + +// NewServiceDescriptorLister returns a new ServiceDescriptorLister. +func NewServiceDescriptorLister(indexer cache.Indexer) ServiceDescriptorLister { + return &serviceDescriptorLister{indexer: indexer} +} + +// List lists all ServiceDescriptors in the indexer. +func (s *serviceDescriptorLister) List(selector labels.Selector) (ret []*v1.ServiceDescriptor, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1.ServiceDescriptor)) + }) + return ret, err +} + +// ServiceDescriptors returns an object that can list and get ServiceDescriptors. +func (s *serviceDescriptorLister) ServiceDescriptors(namespace string) ServiceDescriptorNamespaceLister { + return serviceDescriptorNamespaceLister{indexer: s.indexer, namespace: namespace} +} + +// ServiceDescriptorNamespaceLister helps list and get ServiceDescriptors. +// All objects returned here must be treated as read-only. +type ServiceDescriptorNamespaceLister interface { + // List lists all ServiceDescriptors in the indexer for a given namespace. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1.ServiceDescriptor, err error) + // Get retrieves the ServiceDescriptor from the indexer for a given namespace and name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1.ServiceDescriptor, error) + ServiceDescriptorNamespaceListerExpansion +} + +// serviceDescriptorNamespaceLister implements the ServiceDescriptorNamespaceLister +// interface. +type serviceDescriptorNamespaceLister struct { + indexer cache.Indexer + namespace string +} + +// List lists all ServiceDescriptors in the indexer for a given namespace. +func (s serviceDescriptorNamespaceLister) List(selector labels.Selector) (ret []*v1.ServiceDescriptor, err error) { + err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { + ret = append(ret, m.(*v1.ServiceDescriptor)) + }) + return ret, err +} + +// Get retrieves the ServiceDescriptor from the indexer for a given namespace and name. +func (s serviceDescriptorNamespaceLister) Get(name string) (*v1.ServiceDescriptor, error) { + obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1.Resource("servicedescriptor"), name) + } + return obj.(*v1.ServiceDescriptor), nil +} diff --git a/pkg/testutil/apps/clusterdef_factory.go b/pkg/testutil/apps/clusterdef_factory.go index 66adb7448b1..bb8e6d224aa 100644 --- a/pkg/testutil/apps/clusterdef_factory.go +++ b/pkg/testutil/apps/clusterdef_factory.go @@ -20,23 +20,23 @@ along with this program. If not, see . package apps import ( - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" ) type MockClusterDefFactory struct { - BaseFactory[appsv1alpha1.ClusterDefinition, *appsv1alpha1.ClusterDefinition, MockClusterDefFactory] + BaseFactory[appsv1.ClusterDefinition, *appsv1.ClusterDefinition, MockClusterDefFactory] } func NewClusterDefFactory(name string) *MockClusterDefFactory { f := &MockClusterDefFactory{} f.Init("", name, - &appsv1alpha1.ClusterDefinition{ - Spec: appsv1alpha1.ClusterDefinitionSpec{}, + &appsv1.ClusterDefinition{ + Spec: appsv1.ClusterDefinitionSpec{}, }, f) return f } -func (factory *MockClusterDefFactory) AddClusterTopology(topology appsv1alpha1.ClusterTopology) *MockClusterDefFactory { +func (factory *MockClusterDefFactory) AddClusterTopology(topology appsv1.ClusterTopology) *MockClusterDefFactory { factory.Get().Spec.Topologies = append(factory.Get().Spec.Topologies, topology) return factory } From 76235898d1a76d597abd2354cba4216367709f93 Mon Sep 17 00:00:00 2001 From: Leon Date: Thu, 29 Aug 2024 15:16:09 +0800 Subject: [PATCH 03/15] update --- config/crd/bases/apps.kubeblocks.io_servicedescriptors.yaml | 1 - controllers/apps/cluster_plan_builder.go | 4 ++-- deploy/helm/crds/apps.kubeblocks.io_servicedescriptors.yaml | 1 - 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/config/crd/bases/apps.kubeblocks.io_servicedescriptors.yaml b/config/crd/bases/apps.kubeblocks.io_servicedescriptors.yaml index 99d33d9eaff..3b84dcb3e59 100644 --- a/config/crd/bases/apps.kubeblocks.io_servicedescriptors.yaml +++ b/config/crd/bases/apps.kubeblocks.io_servicedescriptors.yaml @@ -11,7 +11,6 @@ spec: names: categories: - kubeblocks - - all kind: ServiceDescriptor listKind: ServiceDescriptorList plural: servicedescriptors diff --git a/controllers/apps/cluster_plan_builder.go b/controllers/apps/cluster_plan_builder.go index 97c088c9b49..629fde35c70 100644 --- a/controllers/apps/cluster_plan_builder.go +++ b/controllers/apps/cluster_plan_builder.go @@ -36,7 +36,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" - kbappsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" appsv1beta1 "github.com/apecloud/kubeblocks/apis/apps/v1beta1" dpv1alpha1 "github.com/apecloud/kubeblocks/apis/dataprotection/v1alpha1" @@ -56,7 +56,7 @@ type clusterTransformContext struct { logr.Logger Cluster *appsv1alpha1.Cluster OrigCluster *appsv1alpha1.Cluster - ClusterDef *kbappsv1.ClusterDefinition + ClusterDef *appsv1.ClusterDefinition ComponentDefs map[string]*appsv1alpha1.ComponentDefinition // ComponentSpecs includes all cluster component specs generated from ComponentSpecs and ShardingSpecs ComponentSpecs []*appsv1alpha1.ClusterComponentSpec diff --git a/deploy/helm/crds/apps.kubeblocks.io_servicedescriptors.yaml b/deploy/helm/crds/apps.kubeblocks.io_servicedescriptors.yaml index 99d33d9eaff..3b84dcb3e59 100644 --- a/deploy/helm/crds/apps.kubeblocks.io_servicedescriptors.yaml +++ b/deploy/helm/crds/apps.kubeblocks.io_servicedescriptors.yaml @@ -11,7 +11,6 @@ spec: names: categories: - kubeblocks - - all kind: ServiceDescriptor listKind: ServiceDescriptorList plural: servicedescriptors From a1d9ed640a9c01628d8d17c8af99f1d86fe2645b Mon Sep 17 00:00:00 2001 From: Leon Date: Mon, 2 Sep 2024 14:49:57 +0800 Subject: [PATCH 04/15] add cluster, component, cmpd and cmpv --- PROJECT | 60 +- apis/apps/v1/cluster_conversion.go | 22 + apis/apps/v1/cluster_types.go | 96 ++++ apis/apps/v1/cluster_webhook.go | 36 ++ apis/apps/v1/clusterdefinition_webhook.go | 43 -- apis/apps/v1/component_conversion.go | 22 + apis/apps/v1/component_types.go | 82 +++ apis/apps/v1/component_webhook.go | 36 ++ .../apps/v1/componentdefinition_conversion.go | 22 + apis/apps/v1/componentdefinition_types.go | 96 ++++ apis/apps/v1/componentdefinition_webhook.go | 36 ++ apis/apps/v1/componentversion_conversion.go | 22 + apis/apps/v1/componentversion_types.go | 75 +++ apis/apps/v1/componentversion_webhook.go | 36 ++ apis/apps/v1/servicedescriptor_webhook.go | 43 -- apis/apps/v1/webhook_suite_test.go | 6 - apis/apps/v1/zz_generated.deepcopy.go | 358 +++++++++++- apis/apps/v1alpha1/cluster_conversion.go | 34 ++ apis/apps/v1alpha1/cluster_types.go | 6 +- .../v1alpha1/clusterdefinition_webhook.go | 79 --- apis/apps/v1alpha1/component_conversion.go | 34 ++ .../componentdefinition_conversion.go | 34 ++ .../v1alpha1/componentversion_conversion.go | 34 ++ .../v1alpha1/servicedescriptor_webhook.go | 79 --- apis/apps/v1alpha1/webhook_suite_test.go | 138 ----- apis/apps/v1alpha1/zz_generated.deepcopy.go | 2 +- cmd/manager/main.go | 18 +- .../bases/apps.kubeblocks.io_clusters.yaml | 88 ++- ...ps.kubeblocks.io_componentdefinitions.yaml | 84 ++- .../bases/apps.kubeblocks.io_components.yaml | 71 ++- .../apps.kubeblocks.io_componentversions.yaml | 52 +- ...apps.kubeblocks.io_servicedescriptors.yaml | 1 + config/samples/apps_v1_cluster.yaml | 12 + config/samples/apps_v1_component.yaml | 12 + .../samples/apps_v1_componentdefinition.yaml | 12 + config/samples/apps_v1_componentversion.yaml | 12 + .../crds/apps.kubeblocks.io_clusters.yaml | 88 ++- ...ps.kubeblocks.io_componentdefinitions.yaml | 84 ++- .../crds/apps.kubeblocks.io_components.yaml | 71 ++- .../apps.kubeblocks.io_componentversions.yaml | 52 +- ...apps.kubeblocks.io_servicedescriptors.yaml | 1 + docs/developer_docs/api-reference/cluster.md | 539 ++++++++++++++++++ .../versioned/typed/apps/v1/apps_client.go | 20 + .../versioned/typed/apps/v1/cluster.go | 195 +++++++ .../versioned/typed/apps/v1/component.go | 195 +++++++ .../typed/apps/v1/componentdefinition.go | 184 ++++++ .../typed/apps/v1/componentversion.go | 184 ++++++ .../typed/apps/v1/fake/fake_apps_client.go | 16 + .../typed/apps/v1/fake/fake_cluster.go | 141 +++++ .../typed/apps/v1/fake/fake_component.go | 141 +++++ .../apps/v1/fake/fake_componentdefinition.go | 132 +++++ .../apps/v1/fake/fake_componentversion.go | 132 +++++ .../typed/apps/v1/generated_expansion.go | 8 + .../externalversions/apps/v1/cluster.go | 90 +++ .../externalversions/apps/v1/component.go | 90 +++ .../apps/v1/componentdefinition.go | 89 +++ .../apps/v1/componentversion.go | 89 +++ .../externalversions/apps/v1/interface.go | 28 + .../informers/externalversions/generic.go | 8 + pkg/client/listers/apps/v1/cluster.go | 99 ++++ pkg/client/listers/apps/v1/component.go | 99 ++++ .../listers/apps/v1/componentdefinition.go | 68 +++ .../listers/apps/v1/componentversion.go | 68 +++ .../listers/apps/v1/expansion_generated.go | 24 + 64 files changed, 4408 insertions(+), 420 deletions(-) create mode 100644 apis/apps/v1/cluster_conversion.go create mode 100644 apis/apps/v1/cluster_types.go create mode 100644 apis/apps/v1/cluster_webhook.go create mode 100644 apis/apps/v1/component_conversion.go create mode 100644 apis/apps/v1/component_types.go create mode 100644 apis/apps/v1/component_webhook.go create mode 100644 apis/apps/v1/componentdefinition_conversion.go create mode 100644 apis/apps/v1/componentdefinition_types.go create mode 100644 apis/apps/v1/componentdefinition_webhook.go create mode 100644 apis/apps/v1/componentversion_conversion.go create mode 100644 apis/apps/v1/componentversion_types.go create mode 100644 apis/apps/v1/componentversion_webhook.go create mode 100644 apis/apps/v1alpha1/cluster_conversion.go delete mode 100644 apis/apps/v1alpha1/clusterdefinition_webhook.go create mode 100644 apis/apps/v1alpha1/component_conversion.go create mode 100644 apis/apps/v1alpha1/componentdefinition_conversion.go create mode 100644 apis/apps/v1alpha1/componentversion_conversion.go delete mode 100644 apis/apps/v1alpha1/servicedescriptor_webhook.go delete mode 100644 apis/apps/v1alpha1/webhook_suite_test.go create mode 100644 config/samples/apps_v1_cluster.yaml create mode 100644 config/samples/apps_v1_component.yaml create mode 100644 config/samples/apps_v1_componentdefinition.yaml create mode 100644 config/samples/apps_v1_componentversion.yaml create mode 100644 pkg/client/clientset/versioned/typed/apps/v1/cluster.go create mode 100644 pkg/client/clientset/versioned/typed/apps/v1/component.go create mode 100644 pkg/client/clientset/versioned/typed/apps/v1/componentdefinition.go create mode 100644 pkg/client/clientset/versioned/typed/apps/v1/componentversion.go create mode 100644 pkg/client/clientset/versioned/typed/apps/v1/fake/fake_cluster.go create mode 100644 pkg/client/clientset/versioned/typed/apps/v1/fake/fake_component.go create mode 100644 pkg/client/clientset/versioned/typed/apps/v1/fake/fake_componentdefinition.go create mode 100644 pkg/client/clientset/versioned/typed/apps/v1/fake/fake_componentversion.go create mode 100644 pkg/client/informers/externalversions/apps/v1/cluster.go create mode 100644 pkg/client/informers/externalversions/apps/v1/component.go create mode 100644 pkg/client/informers/externalversions/apps/v1/componentdefinition.go create mode 100644 pkg/client/informers/externalversions/apps/v1/componentversion.go create mode 100644 pkg/client/listers/apps/v1/cluster.go create mode 100644 pkg/client/listers/apps/v1/component.go create mode 100644 pkg/client/listers/apps/v1/componentdefinition.go create mode 100644 pkg/client/listers/apps/v1/componentversion.go diff --git a/PROJECT b/PROJECT index 75b844345e6..5f0b988bbc0 100644 --- a/PROJECT +++ b/PROJECT @@ -18,6 +18,18 @@ resources: kind: Cluster path: github.com/apecloud/kubeblocks/apis/apps/v1alpha1 version: v1alpha1 +- api: + crdVersion: v1 + namespaced: true + controller: true + domain: kubeblocks.io + group: apps + kind: Cluster + path: github.com/apecloud/kubeblocks/apis/apps/v1 + version: v1 + webhooks: + conversion: true + webhookVersion: v1 - api: crdVersion: v1 controller: true @@ -26,10 +38,6 @@ resources: kind: ClusterDefinition path: github.com/apecloud/kubeblocks/apis/apps/v1alpha1 version: v1alpha1 - webhooks: - defaulting: true - validation: true - webhookVersion: v1 - api: crdVersion: v1 controller: true @@ -39,8 +47,7 @@ resources: path: github.com/apecloud/kubeblocks/apis/apps/v1 version: v1 webhooks: - defaulting: true - validation: true + conversion: true webhookVersion: v1 - api: crdVersion: v1 @@ -169,10 +176,6 @@ resources: kind: ServiceDescriptor path: github.com/apecloud/kubeblocks/apis/apps/v1alpha1 version: v1alpha1 - webhooks: - defaulting: true - validation: true - webhookVersion: v1 - api: crdVersion: v1 namespaced: true @@ -183,8 +186,7 @@ resources: path: github.com/apecloud/kubeblocks/apis/apps/v1 version: v1 webhooks: - defaulting: true - validation: true + conversion: true webhookVersion: v1 - api: crdVersion: v1 @@ -203,6 +205,17 @@ resources: kind: ComponentDefinition path: github.com/apecloud/kubeblocks/apis/apps/v1alpha1 version: v1alpha1 +- api: + crdVersion: v1 + controller: true + domain: kubeblocks.io + group: apps + kind: ComponentDefinition + path: github.com/apecloud/kubeblocks/apis/apps/v1 + version: v1 + webhooks: + conversion: true + webhookVersion: v1 - api: crdVersion: v1 namespaced: true @@ -212,6 +225,18 @@ resources: kind: Component path: github.com/apecloud/kubeblocks/apis/apps/v1alpha1 version: v1alpha1 +- api: + crdVersion: v1 + namespaced: true + controller: true + domain: kubeblocks.io + group: apps + kind: Component + path: github.com/apecloud/kubeblocks/apis/apps/v1 + version: v1 + webhooks: + conversion: true + webhookVersion: v1 - api: crdVersion: v1 controller: true @@ -228,6 +253,17 @@ resources: kind: ComponentVersion path: github.com/apecloud/kubeblocks/apis/apps/v1alpha1 version: v1alpha1 +- api: + crdVersion: v1 + controller: true + domain: kubeblocks.io + group: apps + kind: ComponentVersion + path: github.com/apecloud/kubeblocks/apis/apps/v1 + version: v1 + webhooks: + conversion: true + webhookVersion: v1 - api: crdVersion: v1 domain: kubeblocks.io diff --git a/apis/apps/v1/cluster_conversion.go b/apis/apps/v1/cluster_conversion.go new file mode 100644 index 00000000000..fc35aaeea6a --- /dev/null +++ b/apis/apps/v1/cluster_conversion.go @@ -0,0 +1,22 @@ +/* +Copyright (C) 2022-2024 ApeCloud Co., Ltd + +This file is part of KubeBlocks project + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ + +package v1 + +func (r *Cluster) Hub() {} diff --git a/apis/apps/v1/cluster_types.go b/apis/apps/v1/cluster_types.go new file mode 100644 index 00000000000..a8367830472 --- /dev/null +++ b/apis/apps/v1/cluster_types.go @@ -0,0 +1,96 @@ +/* +Copyright (C) 2022-2024 ApeCloud Co., Ltd + +This file is part of KubeBlocks project + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ + +package v1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// +genclient +// +k8s:openapi-gen=true +// +kubebuilder:object:root=true +// +kubebuilder:subresource:status +// +kubebuilder:storageversion +// +kubebuilder:resource:categories={kubeblocks,all} +// +kubebuilder:printcolumn:name="CLUSTER-DEFINITION",type="string",JSONPath=".spec.clusterDefinitionRef",description="ClusterDefinition referenced by cluster." +// +kubebuilder:printcolumn:name="VERSION",type="string",JSONPath=".spec.clusterVersionRef",description="Cluster Application Version." +// +kubebuilder:printcolumn:name="TERMINATION-POLICY",type="string",JSONPath=".spec.terminationPolicy",description="Cluster termination policy." +// +kubebuilder:printcolumn:name="STATUS",type="string",JSONPath=".status.phase",description="Cluster Status." +// +kubebuilder:printcolumn:name="AGE",type="date",JSONPath=".metadata.creationTimestamp" + +// Cluster offers a unified management interface for a wide variety of database and storage systems: +// +// - Relational databases: MySQL, PostgreSQL, MariaDB +// - NoSQL databases: Redis, MongoDB +// - KV stores: ZooKeeper, etcd +// - Analytics systems: ElasticSearch, OpenSearch, ClickHouse, Doris, StarRocks, Solr +// - Message queues: Kafka, Pulsar +// - Distributed SQL: TiDB, OceanBase +// - Vector databases: Qdrant, Milvus, Weaviate +// - Object storage: Minio +// +// KubeBlocks utilizes an abstraction layer to encapsulate the characteristics of these diverse systems. +// A Cluster is composed of multiple Components, each defined by vendors or KubeBlocks Addon developers via ComponentDefinition, +// arranged in Directed Acyclic Graph (DAG) topologies. +// The topologies, defined in a ClusterDefinition, coordinate reconciliation across Cluster's lifecycle phases: +// Creating, Running, Updating, Stopping, Stopped, Deleting. +// Lifecycle management ensures that each Component operates in harmony, executing appropriate actions at each lifecycle stage. +// +// For sharded-nothing architecture, the Cluster supports managing multiple shards, +// each shard managed by a separate Component, supporting dynamic resharding. +// +// The Cluster object is aimed to maintain the overall integrity and availability of a database cluster, +// serves as the central control point, abstracting the complexity of multiple-component management, +// and providing a unified interface for cluster-wide operations. +type Cluster struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec ClusterSpec `json:"spec,omitempty"` + Status ClusterStatus `json:"status,omitempty"` +} + +// +kubebuilder:object:root=true + +// ClusterList contains a list of Cluster. +type ClusterList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []Cluster `json:"items"` +} + +func init() { + SchemeBuilder.Register(&Cluster{}, &ClusterList{}) +} + +// ClusterSpec defines the desired state of Cluster +type ClusterSpec struct { + // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster + // Important: Run "make" to regenerate code after modifying this file + + // Foo is an example field of Cluster. Edit cluster_types.go to remove/update + Foo string `json:"foo,omitempty"` +} + +// ClusterStatus defines the observed state of Cluster +type ClusterStatus struct { + // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster + // Important: Run "make" to regenerate code after modifying this file +} diff --git a/apis/apps/v1/cluster_webhook.go b/apis/apps/v1/cluster_webhook.go new file mode 100644 index 00000000000..de66fce24b0 --- /dev/null +++ b/apis/apps/v1/cluster_webhook.go @@ -0,0 +1,36 @@ +/* +Copyright (C) 2022-2024 ApeCloud Co., Ltd + +This file is part of KubeBlocks project + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ + +package v1 + +import ( + ctrl "sigs.k8s.io/controller-runtime" + logf "sigs.k8s.io/controller-runtime/pkg/log" +) + +// log is for logging in this package. +var clusterlog = logf.Log.WithName("cluster-resource") + +func (r *Cluster) SetupWebhookWithManager(mgr ctrl.Manager) error { + return ctrl.NewWebhookManagedBy(mgr). + For(r). + Complete() +} + +// TODO(user): EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! diff --git a/apis/apps/v1/clusterdefinition_webhook.go b/apis/apps/v1/clusterdefinition_webhook.go index 8161066c2ba..753261f0d49 100644 --- a/apis/apps/v1/clusterdefinition_webhook.go +++ b/apis/apps/v1/clusterdefinition_webhook.go @@ -20,11 +20,8 @@ along with this program. If not, see . package v1 import ( - "k8s.io/apimachinery/pkg/runtime" ctrl "sigs.k8s.io/controller-runtime" logf "sigs.k8s.io/controller-runtime/pkg/log" - "sigs.k8s.io/controller-runtime/pkg/webhook" - "sigs.k8s.io/controller-runtime/pkg/webhook/admission" ) // log is for logging in this package. @@ -37,43 +34,3 @@ func (r *ClusterDefinition) SetupWebhookWithManager(mgr ctrl.Manager) error { } // TODO(user): EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! - -//+kubebuilder:webhook:path=/mutate-apps-kubeblocks-io-v1-clusterdefinition,mutating=true,failurePolicy=fail,sideEffects=None,groups=apps.kubeblocks.io,resources=clusterdefinitions,verbs=create;update,versions=v1,name=mclusterdefinition.kb.io,admissionReviewVersions=v1 - -var _ webhook.Defaulter = &ClusterDefinition{} - -// Default implements webhook.Defaulter so a webhook will be registered for the type -func (r *ClusterDefinition) Default() { - clusterdefinitionlog.Info("default", "name", r.Name) - - // TODO(user): fill in your defaulting logic. -} - -// TODO(user): change verbs to "verbs=create;update;delete" if you want to enable deletion validation. -//+kubebuilder:webhook:path=/validate-apps-kubeblocks-io-v1-clusterdefinition,mutating=false,failurePolicy=fail,sideEffects=None,groups=apps.kubeblocks.io,resources=clusterdefinitions,verbs=create;update,versions=v1,name=vclusterdefinition.kb.io,admissionReviewVersions=v1 - -var _ webhook.Validator = &ClusterDefinition{} - -// ValidateCreate implements webhook.Validator so a webhook will be registered for the type -func (r *ClusterDefinition) ValidateCreate() (warnings admission.Warnings, err error) { - clusterdefinitionlog.Info("validate create", "name", r.Name) - - // TODO(user): fill in your validation logic upon object creation. - return nil, nil -} - -// ValidateUpdate implements webhook.Validator so a webhook will be registered for the type -func (r *ClusterDefinition) ValidateUpdate(old runtime.Object) (warnings admission.Warnings, err error) { - clusterdefinitionlog.Info("validate update", "name", r.Name) - - // TODO(user): fill in your validation logic upon object update. - return nil, nil -} - -// ValidateDelete implements webhook.Validator so a webhook will be registered for the type -func (r *ClusterDefinition) ValidateDelete() (warnings admission.Warnings, err error) { - clusterdefinitionlog.Info("validate delete", "name", r.Name) - - // TODO(user): fill in your validation logic upon object deletion. - return nil, nil -} diff --git a/apis/apps/v1/component_conversion.go b/apis/apps/v1/component_conversion.go new file mode 100644 index 00000000000..540d9638128 --- /dev/null +++ b/apis/apps/v1/component_conversion.go @@ -0,0 +1,22 @@ +/* +Copyright (C) 2022-2024 ApeCloud Co., Ltd + +This file is part of KubeBlocks project + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ + +package v1 + +func (r *Component) Hub() {} diff --git a/apis/apps/v1/component_types.go b/apis/apps/v1/component_types.go new file mode 100644 index 00000000000..3032f978020 --- /dev/null +++ b/apis/apps/v1/component_types.go @@ -0,0 +1,82 @@ +/* +Copyright (C) 2022-2024 ApeCloud Co., Ltd + +This file is part of KubeBlocks project + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ + +package v1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// +genclient +// +kubebuilder:object:root=true +// +kubebuilder:subresource:status +// +kubebuilder:storageversion +// +kubebuilder:resource:categories={kubeblocks},shortName=cmp +// +kubebuilder:printcolumn:name="DEFINITION",type="string",JSONPath=".spec.compDef",description="component definition" +// +kubebuilder:printcolumn:name="SERVICE-VERSION",type="string",JSONPath=".spec.serviceVersion",description="service version" +// +kubebuilder:printcolumn:name="STATUS",type="string",JSONPath=".status.phase",description="status phase" +// +kubebuilder:printcolumn:name="AGE",type="date",JSONPath=".metadata.creationTimestamp" + +// Component is a fundamental building block of a Cluster object. +// For example, a Redis Cluster can include Components like 'redis', 'sentinel', and potentially a proxy like 'twemproxy'. +// +// The Component object is responsible for managing the lifecycle of all replicas within a Cluster component, +// It supports a wide range of operations including provisioning, stopping, restarting, termination, upgrading, +// configuration changes, vertical and horizontal scaling, failover, switchover, cross-node migration, +// scheduling configuration, exposing Services, managing system accounts, enabling/disabling exporter, +// and configuring log collection. +// +// Component is an internal sub-object derived from the user-submitted Cluster object. +// It is designed primarily to be used by the KubeBlocks controllers, +// users are discouraged from modifying Component objects directly and should use them only for monitoring Component statuses. +type Component struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec ComponentSpec `json:"spec,omitempty"` + Status ComponentStatus `json:"status,omitempty"` +} + +// +kubebuilder:object:root=true + +// ComponentList contains a list of Component. +type ComponentList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []Component `json:"items"` +} + +func init() { + SchemeBuilder.Register(&Component{}, &ComponentList{}) +} + +// ComponentSpec defines the desired state of Component +type ComponentSpec struct { + // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster + // Important: Run "make" to regenerate code after modifying this file + + // Foo is an example field of Component. Edit component_types.go to remove/update + Foo string `json:"foo,omitempty"` +} + +// ComponentStatus defines the observed state of Component +type ComponentStatus struct { + // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster + // Important: Run "make" to regenerate code after modifying this file +} diff --git a/apis/apps/v1/component_webhook.go b/apis/apps/v1/component_webhook.go new file mode 100644 index 00000000000..c20a2e5b871 --- /dev/null +++ b/apis/apps/v1/component_webhook.go @@ -0,0 +1,36 @@ +/* +Copyright (C) 2022-2024 ApeCloud Co., Ltd + +This file is part of KubeBlocks project + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ + +package v1 + +import ( + ctrl "sigs.k8s.io/controller-runtime" + logf "sigs.k8s.io/controller-runtime/pkg/log" +) + +// log is for logging in this package. +var componentlog = logf.Log.WithName("component-resource") + +func (r *Component) SetupWebhookWithManager(mgr ctrl.Manager) error { + return ctrl.NewWebhookManagedBy(mgr). + For(r). + Complete() +} + +// TODO(user): EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! diff --git a/apis/apps/v1/componentdefinition_conversion.go b/apis/apps/v1/componentdefinition_conversion.go new file mode 100644 index 00000000000..6c4ac82e044 --- /dev/null +++ b/apis/apps/v1/componentdefinition_conversion.go @@ -0,0 +1,22 @@ +/* +Copyright (C) 2022-2024 ApeCloud Co., Ltd + +This file is part of KubeBlocks project + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ + +package v1 + +func (r *ComponentDefinition) Hub() {} diff --git a/apis/apps/v1/componentdefinition_types.go b/apis/apps/v1/componentdefinition_types.go new file mode 100644 index 00000000000..4bfa6ca0805 --- /dev/null +++ b/apis/apps/v1/componentdefinition_types.go @@ -0,0 +1,96 @@ +/* +Copyright (C) 2022-2024 ApeCloud Co., Ltd + +This file is part of KubeBlocks project + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ + +package v1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// +genclient +// +genclient:nonNamespaced +// +k8s:openapi-gen=true +// +kubebuilder:object:root=true +// +kubebuilder:subresource:status +// +kubebuilder:storageversion +// +kubebuilder:resource:categories={kubeblocks},scope=Cluster,shortName=cmpd +// +kubebuilder:printcolumn:name="SERVICE",type="string",JSONPath=".spec.serviceKind",description="service" +// +kubebuilder:printcolumn:name="SERVICE-VERSION",type="string",JSONPath=".spec.serviceVersion",description="service version" +// +kubebuilder:printcolumn:name="STATUS",type="string",JSONPath=".status.phase",description="status phase" +// +kubebuilder:printcolumn:name="AGE",type="date",JSONPath=".metadata.creationTimestamp" + +// ComponentDefinition serves as a reusable blueprint for creating Components, +// encapsulating essential static settings such as Component description, +// Pod templates, configuration file templates, scripts, parameter lists, +// injected environment variables and their sources, and event handlers. +// ComponentDefinition works in conjunction with dynamic settings from the ClusterComponentSpec, +// to instantiate Components during Cluster creation. +// +// Key aspects that can be defined in a ComponentDefinition include: +// +// - PodSpec template: Specifies the PodSpec template used by the Component. +// - Configuration templates: Specify the configuration file templates required by the Component. +// - Scripts: Provide the necessary scripts for Component management and operations. +// - Storage volumes: Specify the storage volumes and their configurations for the Component. +// - Pod roles: Outlines various roles of Pods within the Component along with their capabilities. +// - Exposed Kubernetes Services: Specify the Services that need to be exposed by the Component. +// - System accounts: Define the system accounts required for the Component. +// - Monitoring and logging: Configure the exporter and logging settings for the Component. +// +// ComponentDefinitions also enable defining reactive behaviors of the Component in response to events, +// such as member join/leave, Component addition/deletion, role changes, switch over, and more. +// This allows for automatic event handling, thus encapsulating complex behaviors within the Component. +// +// Referencing a ComponentDefinition when creating individual Components ensures inheritance of predefined configurations, +// promoting reusability and consistency across different deployments and cluster topologies. +type ComponentDefinition struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec ComponentDefinitionSpec `json:"spec,omitempty"` + Status ComponentDefinitionStatus `json:"status,omitempty"` +} + +// +kubebuilder:object:root=true + +// ComponentDefinitionList contains a list of ComponentDefinition +type ComponentDefinitionList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []ComponentDefinition `json:"items"` +} + +func init() { + SchemeBuilder.Register(&ComponentDefinition{}, &ComponentDefinitionList{}) +} + +// ComponentDefinitionSpec defines the desired state of ComponentDefinition +type ComponentDefinitionSpec struct { + // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster + // Important: Run "make" to regenerate code after modifying this file + + // Foo is an example field of ComponentDefinition. Edit componentdefinition_types.go to remove/update + Foo string `json:"foo,omitempty"` +} + +// ComponentDefinitionStatus defines the observed state of ComponentDefinition +type ComponentDefinitionStatus struct { + // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster + // Important: Run "make" to regenerate code after modifying this file +} diff --git a/apis/apps/v1/componentdefinition_webhook.go b/apis/apps/v1/componentdefinition_webhook.go new file mode 100644 index 00000000000..8df50c3b4c3 --- /dev/null +++ b/apis/apps/v1/componentdefinition_webhook.go @@ -0,0 +1,36 @@ +/* +Copyright (C) 2022-2024 ApeCloud Co., Ltd + +This file is part of KubeBlocks project + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ + +package v1 + +import ( + ctrl "sigs.k8s.io/controller-runtime" + logf "sigs.k8s.io/controller-runtime/pkg/log" +) + +// log is for logging in this package. +var componentdefinitionlog = logf.Log.WithName("componentdefinition-resource") + +func (r *ComponentDefinition) SetupWebhookWithManager(mgr ctrl.Manager) error { + return ctrl.NewWebhookManagedBy(mgr). + For(r). + Complete() +} + +// TODO(user): EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! diff --git a/apis/apps/v1/componentversion_conversion.go b/apis/apps/v1/componentversion_conversion.go new file mode 100644 index 00000000000..c54b5c3b254 --- /dev/null +++ b/apis/apps/v1/componentversion_conversion.go @@ -0,0 +1,22 @@ +/* +Copyright (C) 2022-2024 ApeCloud Co., Ltd + +This file is part of KubeBlocks project + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ + +package v1 + +func (r *ComponentVersion) Hub() {} diff --git a/apis/apps/v1/componentversion_types.go b/apis/apps/v1/componentversion_types.go new file mode 100644 index 00000000000..5d6cb7f21fb --- /dev/null +++ b/apis/apps/v1/componentversion_types.go @@ -0,0 +1,75 @@ +/* +Copyright (C) 2022-2024 ApeCloud Co., Ltd + +This file is part of KubeBlocks project + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ + +package v1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// +genclient +// +genclient:nonNamespaced +// +k8s:openapi-gen=true +// +kubebuilder:object:root=true +// +kubebuilder:subresource:status +// +kubebuilder:storageversion +// +kubebuilder:resource:categories={kubeblocks},scope=Cluster,shortName=cmpv +// +kubebuilder:printcolumn:name="Versions",type="string",JSONPath=".status.serviceVersions",description="service versions" +// +kubebuilder:printcolumn:name="Status",type="string",JSONPath=".status.phase",description="status phase" +// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp" + +// ComponentVersion is the Schema for the componentversions API +type ComponentVersion struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec ComponentVersionSpec `json:"spec,omitempty"` + Status ComponentVersionStatus `json:"status,omitempty"` +} + +// +kubebuilder:object:root=true + +// ComponentVersionList contains a list of ComponentVersion +type ComponentVersionList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []ComponentVersion `json:"items"` +} + +func init() { + SchemeBuilder.Register(&ComponentVersion{}, &ComponentVersionList{}) +} + +// 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. + +// ComponentVersionSpec defines the desired state of ComponentVersion +type ComponentVersionSpec struct { + // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster + // Important: Run "make" to regenerate code after modifying this file + + // Foo is an example field of ComponentVersion. Edit componentversion_types.go to remove/update + Foo string `json:"foo,omitempty"` +} + +// ComponentVersionStatus defines the observed state of ComponentVersion +type ComponentVersionStatus struct { + // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster + // Important: Run "make" to regenerate code after modifying this file +} diff --git a/apis/apps/v1/componentversion_webhook.go b/apis/apps/v1/componentversion_webhook.go new file mode 100644 index 00000000000..28f36e7afee --- /dev/null +++ b/apis/apps/v1/componentversion_webhook.go @@ -0,0 +1,36 @@ +/* +Copyright (C) 2022-2024 ApeCloud Co., Ltd + +This file is part of KubeBlocks project + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ + +package v1 + +import ( + ctrl "sigs.k8s.io/controller-runtime" + logf "sigs.k8s.io/controller-runtime/pkg/log" +) + +// log is for logging in this package. +var componentversionlog = logf.Log.WithName("componentversion-resource") + +func (r *ComponentVersion) SetupWebhookWithManager(mgr ctrl.Manager) error { + return ctrl.NewWebhookManagedBy(mgr). + For(r). + Complete() +} + +// TODO(user): EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! diff --git a/apis/apps/v1/servicedescriptor_webhook.go b/apis/apps/v1/servicedescriptor_webhook.go index e87ff9167ac..e2abc9cc592 100644 --- a/apis/apps/v1/servicedescriptor_webhook.go +++ b/apis/apps/v1/servicedescriptor_webhook.go @@ -20,11 +20,8 @@ along with this program. If not, see . package v1 import ( - "k8s.io/apimachinery/pkg/runtime" ctrl "sigs.k8s.io/controller-runtime" logf "sigs.k8s.io/controller-runtime/pkg/log" - "sigs.k8s.io/controller-runtime/pkg/webhook" - "sigs.k8s.io/controller-runtime/pkg/webhook/admission" ) // log is for logging in this package. @@ -37,43 +34,3 @@ func (r *ServiceDescriptor) SetupWebhookWithManager(mgr ctrl.Manager) error { } // TODO(user): EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! - -//+kubebuilder:webhook:path=/mutate-apps-kubeblocks-io-v1-servicedescriptor,mutating=true,failurePolicy=fail,sideEffects=None,groups=apps.kubeblocks.io,resources=servicedescriptors,verbs=create;update,versions=v1,name=mservicedescriptor.kb.io,admissionReviewVersions=v1 - -var _ webhook.Defaulter = &ServiceDescriptor{} - -// Default implements webhook.Defaulter so a webhook will be registered for the type -func (r *ServiceDescriptor) Default() { - servicedescriptorlog.Info("default", "name", r.Name) - - // TODO(user): fill in your defaulting logic. -} - -// TODO(user): change verbs to "verbs=create;update;delete" if you want to enable deletion validation. -//+kubebuilder:webhook:path=/validate-apps-kubeblocks-io-v1-servicedescriptor,mutating=false,failurePolicy=fail,sideEffects=None,groups=apps.kubeblocks.io,resources=servicedescriptors,verbs=create;update,versions=v1,name=vservicedescriptor.kb.io,admissionReviewVersions=v1 - -var _ webhook.Validator = &ServiceDescriptor{} - -// ValidateCreate implements webhook.Validator so a webhook will be registered for the type -func (r *ServiceDescriptor) ValidateCreate() (warnings admission.Warnings, err error) { - servicedescriptorlog.Info("validate create", "name", r.Name) - - // TODO(user): fill in your validation logic upon object creation. - return nil, nil -} - -// ValidateUpdate implements webhook.Validator so a webhook will be registered for the type -func (r *ServiceDescriptor) ValidateUpdate(old runtime.Object) (warnings admission.Warnings, err error) { - servicedescriptorlog.Info("validate update", "name", r.Name) - - // TODO(user): fill in your validation logic upon object update. - return nil, nil -} - -// ValidateDelete implements webhook.Validator so a webhook will be registered for the type -func (r *ServiceDescriptor) ValidateDelete() (warnings admission.Warnings, err error) { - servicedescriptorlog.Info("validate delete", "name", r.Name) - - // TODO(user): fill in your validation logic upon object deletion. - return nil, nil -} diff --git a/apis/apps/v1/webhook_suite_test.go b/apis/apps/v1/webhook_suite_test.go index 0c555fbe000..869a434a1c3 100644 --- a/apis/apps/v1/webhook_suite_test.go +++ b/apis/apps/v1/webhook_suite_test.go @@ -102,12 +102,6 @@ var _ = BeforeSuite(func() { }) Expect(err).NotTo(HaveOccurred()) - err = (&ClusterDefinition{}).SetupWebhookWithManager(mgr) - Expect(err).NotTo(HaveOccurred()) - - err = (&ServiceDescriptor{}).SetupWebhookWithManager(mgr) - Expect(err).NotTo(HaveOccurred()) - //+kubebuilder:scaffold:webhook go func() { diff --git a/apis/apps/v1/zz_generated.deepcopy.go b/apis/apps/v1/zz_generated.deepcopy.go index 8807748259e..40dd9325a80 100644 --- a/apis/apps/v1/zz_generated.deepcopy.go +++ b/apis/apps/v1/zz_generated.deepcopy.go @@ -25,9 +25,36 @@ package v1 import ( corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/runtime" + 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 *Cluster) DeepCopyInto(out *Cluster) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + out.Spec = in.Spec + out.Status = in.Status +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Cluster. +func (in *Cluster) DeepCopy() *Cluster { + if in == nil { + return nil + } + out := new(Cluster) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *Cluster) 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 *ClusterDefinition) DeepCopyInto(out *ClusterDefinition) { *out = *in @@ -124,6 +151,68 @@ func (in *ClusterDefinitionStatus) DeepCopy() *ClusterDefinitionStatus { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterList) DeepCopyInto(out *ClusterList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]Cluster, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterList. +func (in *ClusterList) DeepCopy() *ClusterList { + if in == nil { + return nil + } + out := new(ClusterList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ClusterList) 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 *ClusterSpec) DeepCopyInto(out *ClusterSpec) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterSpec. +func (in *ClusterSpec) DeepCopy() *ClusterSpec { + if in == nil { + return nil + } + out := new(ClusterSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterStatus) DeepCopyInto(out *ClusterStatus) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterStatus. +func (in *ClusterStatus) DeepCopy() *ClusterStatus { + if in == nil { + return nil + } + out := new(ClusterStatus) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ClusterTopology) DeepCopyInto(out *ClusterTopology) { *out = *in @@ -194,6 +283,273 @@ func (in *ClusterTopologyOrders) DeepCopy() *ClusterTopologyOrders { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Component) DeepCopyInto(out *Component) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + out.Spec = in.Spec + out.Status = in.Status +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Component. +func (in *Component) DeepCopy() *Component { + if in == nil { + return nil + } + out := new(Component) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *Component) 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 *ComponentDefinition) DeepCopyInto(out *ComponentDefinition) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + out.Spec = in.Spec + out.Status = in.Status +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ComponentDefinition. +func (in *ComponentDefinition) DeepCopy() *ComponentDefinition { + if in == nil { + return nil + } + out := new(ComponentDefinition) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ComponentDefinition) 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 *ComponentDefinitionList) DeepCopyInto(out *ComponentDefinitionList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]ComponentDefinition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ComponentDefinitionList. +func (in *ComponentDefinitionList) DeepCopy() *ComponentDefinitionList { + if in == nil { + return nil + } + out := new(ComponentDefinitionList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ComponentDefinitionList) 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 *ComponentDefinitionSpec) DeepCopyInto(out *ComponentDefinitionSpec) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ComponentDefinitionSpec. +func (in *ComponentDefinitionSpec) DeepCopy() *ComponentDefinitionSpec { + if in == nil { + return nil + } + out := new(ComponentDefinitionSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ComponentDefinitionStatus) DeepCopyInto(out *ComponentDefinitionStatus) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ComponentDefinitionStatus. +func (in *ComponentDefinitionStatus) DeepCopy() *ComponentDefinitionStatus { + if in == nil { + return nil + } + out := new(ComponentDefinitionStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ComponentList) DeepCopyInto(out *ComponentList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]Component, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ComponentList. +func (in *ComponentList) DeepCopy() *ComponentList { + if in == nil { + return nil + } + out := new(ComponentList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ComponentList) 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 *ComponentSpec) DeepCopyInto(out *ComponentSpec) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ComponentSpec. +func (in *ComponentSpec) DeepCopy() *ComponentSpec { + if in == nil { + return nil + } + out := new(ComponentSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ComponentStatus) DeepCopyInto(out *ComponentStatus) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ComponentStatus. +func (in *ComponentStatus) DeepCopy() *ComponentStatus { + if in == nil { + return nil + } + out := new(ComponentStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ComponentVersion) DeepCopyInto(out *ComponentVersion) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + out.Spec = in.Spec + out.Status = in.Status +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ComponentVersion. +func (in *ComponentVersion) DeepCopy() *ComponentVersion { + if in == nil { + return nil + } + out := new(ComponentVersion) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ComponentVersion) 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 *ComponentVersionList) DeepCopyInto(out *ComponentVersionList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]ComponentVersion, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ComponentVersionList. +func (in *ComponentVersionList) DeepCopy() *ComponentVersionList { + if in == nil { + return nil + } + out := new(ComponentVersionList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ComponentVersionList) 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 *ComponentVersionSpec) DeepCopyInto(out *ComponentVersionSpec) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ComponentVersionSpec. +func (in *ComponentVersionSpec) DeepCopy() *ComponentVersionSpec { + if in == nil { + return nil + } + out := new(ComponentVersionSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ComponentVersionStatus) DeepCopyInto(out *ComponentVersionStatus) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ComponentVersionStatus. +func (in *ComponentVersionStatus) DeepCopy() *ComponentVersionStatus { + if in == nil { + return nil + } + out := new(ComponentVersionStatus) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ConnectionCredentialAuth) DeepCopyInto(out *ConnectionCredentialAuth) { *out = *in diff --git a/apis/apps/v1alpha1/cluster_conversion.go b/apis/apps/v1alpha1/cluster_conversion.go new file mode 100644 index 00000000000..6b26cb289da --- /dev/null +++ b/apis/apps/v1alpha1/cluster_conversion.go @@ -0,0 +1,34 @@ +/* +Copyright (C) 2022-2024 ApeCloud Co., Ltd + +This file is part of KubeBlocks project + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ + +package v1alpha1 + +import ( + "sigs.k8s.io/controller-runtime/pkg/conversion" +) + +// ConvertTo converts this Cluster to the Hub version (v1). +func (r *Cluster) ConvertTo(dstRaw conversion.Hub) error { + return nil +} + +// ConvertFrom converts from the Hub version (v1) to this version. +func (r *Cluster) ConvertFrom(srcRaw conversion.Hub) error { + return nil +} diff --git a/apis/apps/v1alpha1/cluster_types.go b/apis/apps/v1alpha1/cluster_types.go index 549ac293327..2324c4baf86 100644 --- a/apis/apps/v1alpha1/cluster_types.go +++ b/apis/apps/v1alpha1/cluster_types.go @@ -1488,18 +1488,18 @@ func init() { SchemeBuilder.Register(&Cluster{}, &ClusterList{}) } -func (r Cluster) IsDeleting() bool { +func (r *Cluster) IsDeleting() bool { if r.GetDeletionTimestamp().IsZero() { return false } return r.Spec.TerminationPolicy != DoNotTerminate } -func (r Cluster) IsUpdating() bool { +func (r *Cluster) IsUpdating() bool { return r.Status.ObservedGeneration != r.Generation } -func (r Cluster) IsStatusUpdating() bool { +func (r *Cluster) IsStatusUpdating() bool { return !r.IsDeleting() && !r.IsUpdating() } diff --git a/apis/apps/v1alpha1/clusterdefinition_webhook.go b/apis/apps/v1alpha1/clusterdefinition_webhook.go deleted file mode 100644 index 13e161adc24..00000000000 --- a/apis/apps/v1alpha1/clusterdefinition_webhook.go +++ /dev/null @@ -1,79 +0,0 @@ -/* -Copyright (C) 2022-2024 ApeCloud Co., Ltd - -This file is part of KubeBlocks project - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Affero General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Affero General Public License for more details. - -You should have received a copy of the GNU Affero General Public License -along with this program. If not, see . -*/ - -package v1alpha1 - -import ( - "k8s.io/apimachinery/pkg/runtime" - ctrl "sigs.k8s.io/controller-runtime" - logf "sigs.k8s.io/controller-runtime/pkg/log" - "sigs.k8s.io/controller-runtime/pkg/webhook" - "sigs.k8s.io/controller-runtime/pkg/webhook/admission" -) - -// log is for logging in this package. -var clusterdefinitionlog = logf.Log.WithName("clusterdefinition-resource") - -func (r *ClusterDefinition) SetupWebhookWithManager(mgr ctrl.Manager) error { - return ctrl.NewWebhookManagedBy(mgr). - For(r). - Complete() -} - -// TODO(user): EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! - -//+kubebuilder:webhook:path=/mutate-apps-kubeblocks-io-v1alpha1-clusterdefinition,mutating=true,failurePolicy=fail,sideEffects=None,groups=apps.kubeblocks.io,resources=clusterdefinitions,verbs=create;update,versions=v1alpha1,name=mclusterdefinition.kb.io,admissionReviewVersions=v1 - -var _ webhook.Defaulter = &ClusterDefinition{} - -// Default implements webhook.Defaulter so a webhook will be registered for the type -func (r *ClusterDefinition) Default() { - clusterdefinitionlog.Info("default", "name", r.Name) - - // TODO(user): fill in your defaulting logic. -} - -// TODO(user): change verbs to "verbs=create;update;delete" if you want to enable deletion validation. -//+kubebuilder:webhook:path=/validate-apps-kubeblocks-io-v1alpha1-clusterdefinition,mutating=false,failurePolicy=fail,sideEffects=None,groups=apps.kubeblocks.io,resources=clusterdefinitions,verbs=create;update,versions=v1alpha1,name=vclusterdefinition.kb.io,admissionReviewVersions=v1 - -var _ webhook.Validator = &ClusterDefinition{} - -// ValidateCreate implements webhook.Validator so a webhook will be registered for the type -func (r *ClusterDefinition) ValidateCreate() (warnings admission.Warnings, err error) { - clusterdefinitionlog.Info("validate create", "name", r.Name) - - // TODO(user): fill in your validation logic upon object creation. - return nil, nil -} - -// ValidateUpdate implements webhook.Validator so a webhook will be registered for the type -func (r *ClusterDefinition) ValidateUpdate(old runtime.Object) (warnings admission.Warnings, err error) { - clusterdefinitionlog.Info("validate update", "name", r.Name) - - // TODO(user): fill in your validation logic upon object update. - return nil, nil -} - -// ValidateDelete implements webhook.Validator so a webhook will be registered for the type -func (r *ClusterDefinition) ValidateDelete() (warnings admission.Warnings, err error) { - clusterdefinitionlog.Info("validate delete", "name", r.Name) - - // TODO(user): fill in your validation logic upon object deletion. - return nil, nil -} diff --git a/apis/apps/v1alpha1/component_conversion.go b/apis/apps/v1alpha1/component_conversion.go new file mode 100644 index 00000000000..71549e8098b --- /dev/null +++ b/apis/apps/v1alpha1/component_conversion.go @@ -0,0 +1,34 @@ +/* +Copyright (C) 2022-2024 ApeCloud Co., Ltd + +This file is part of KubeBlocks project + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ + +package v1alpha1 + +import ( + "sigs.k8s.io/controller-runtime/pkg/conversion" +) + +// ConvertTo converts this Component to the Hub version (v1). +func (r *Component) ConvertTo(dstRaw conversion.Hub) error { + return nil +} + +// ConvertFrom converts from the Hub version (v1) to this version. +func (r *Component) ConvertFrom(srcRaw conversion.Hub) error { + return nil +} diff --git a/apis/apps/v1alpha1/componentdefinition_conversion.go b/apis/apps/v1alpha1/componentdefinition_conversion.go new file mode 100644 index 00000000000..7eb6e7d4caf --- /dev/null +++ b/apis/apps/v1alpha1/componentdefinition_conversion.go @@ -0,0 +1,34 @@ +/* +Copyright (C) 2022-2024 ApeCloud Co., Ltd + +This file is part of KubeBlocks project + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ + +package v1alpha1 + +import ( + "sigs.k8s.io/controller-runtime/pkg/conversion" +) + +// ConvertTo converts this ComponentDefinition to the Hub version (v1). +func (r *ComponentDefinition) ConvertTo(dstRaw conversion.Hub) error { + return nil +} + +// ConvertFrom converts from the Hub version (v1) to this version. +func (r *ComponentDefinition) ConvertFrom(srcRaw conversion.Hub) error { + return nil +} diff --git a/apis/apps/v1alpha1/componentversion_conversion.go b/apis/apps/v1alpha1/componentversion_conversion.go new file mode 100644 index 00000000000..f7f40366d9b --- /dev/null +++ b/apis/apps/v1alpha1/componentversion_conversion.go @@ -0,0 +1,34 @@ +/* +Copyright (C) 2022-2024 ApeCloud Co., Ltd + +This file is part of KubeBlocks project + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ + +package v1alpha1 + +import ( + "sigs.k8s.io/controller-runtime/pkg/conversion" +) + +// ConvertTo converts this ComponentVersion to the Hub version (v1). +func (r *ComponentVersion) ConvertTo(dstRaw conversion.Hub) error { + return nil +} + +// ConvertFrom converts from the Hub version (v1) to this version. +func (r *ComponentVersion) ConvertFrom(srcRaw conversion.Hub) error { + return nil +} diff --git a/apis/apps/v1alpha1/servicedescriptor_webhook.go b/apis/apps/v1alpha1/servicedescriptor_webhook.go deleted file mode 100644 index fbf31eae063..00000000000 --- a/apis/apps/v1alpha1/servicedescriptor_webhook.go +++ /dev/null @@ -1,79 +0,0 @@ -/* -Copyright (C) 2022-2024 ApeCloud Co., Ltd - -This file is part of KubeBlocks project - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Affero General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Affero General Public License for more details. - -You should have received a copy of the GNU Affero General Public License -along with this program. If not, see . -*/ - -package v1alpha1 - -import ( - "k8s.io/apimachinery/pkg/runtime" - ctrl "sigs.k8s.io/controller-runtime" - logf "sigs.k8s.io/controller-runtime/pkg/log" - "sigs.k8s.io/controller-runtime/pkg/webhook" - "sigs.k8s.io/controller-runtime/pkg/webhook/admission" -) - -// log is for logging in this package. -var servicedescriptorlog = logf.Log.WithName("servicedescriptor-resource") - -func (r *ServiceDescriptor) SetupWebhookWithManager(mgr ctrl.Manager) error { - return ctrl.NewWebhookManagedBy(mgr). - For(r). - Complete() -} - -// TODO(user): EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! - -//+kubebuilder:webhook:path=/mutate-apps-kubeblocks-io-v1alpha1-servicedescriptor,mutating=true,failurePolicy=fail,sideEffects=None,groups=apps.kubeblocks.io,resources=servicedescriptors,verbs=create;update,versions=v1alpha1,name=mservicedescriptor.kb.io,admissionReviewVersions=v1 - -var _ webhook.Defaulter = &ServiceDescriptor{} - -// Default implements webhook.Defaulter so a webhook will be registered for the type -func (r *ServiceDescriptor) Default() { - servicedescriptorlog.Info("default", "name", r.Name) - - // TODO(user): fill in your defaulting logic. -} - -// TODO(user): change verbs to "verbs=create;update;delete" if you want to enable deletion validation. -//+kubebuilder:webhook:path=/validate-apps-kubeblocks-io-v1alpha1-servicedescriptor,mutating=false,failurePolicy=fail,sideEffects=None,groups=apps.kubeblocks.io,resources=servicedescriptors,verbs=create;update,versions=v1alpha1,name=vservicedescriptor.kb.io,admissionReviewVersions=v1 - -var _ webhook.Validator = &ServiceDescriptor{} - -// ValidateCreate implements webhook.Validator so a webhook will be registered for the type -func (r *ServiceDescriptor) ValidateCreate() (warnings admission.Warnings, err error) { - servicedescriptorlog.Info("validate create", "name", r.Name) - - // TODO(user): fill in your validation logic upon object creation. - return nil, nil -} - -// ValidateUpdate implements webhook.Validator so a webhook will be registered for the type -func (r *ServiceDescriptor) ValidateUpdate(old runtime.Object) (warnings admission.Warnings, err error) { - servicedescriptorlog.Info("validate update", "name", r.Name) - - // TODO(user): fill in your validation logic upon object update. - return nil, nil -} - -// ValidateDelete implements webhook.Validator so a webhook will be registered for the type -func (r *ServiceDescriptor) ValidateDelete() (warnings admission.Warnings, err error) { - servicedescriptorlog.Info("validate delete", "name", r.Name) - - // TODO(user): fill in your validation logic upon object deletion. - return nil, nil -} diff --git a/apis/apps/v1alpha1/webhook_suite_test.go b/apis/apps/v1alpha1/webhook_suite_test.go deleted file mode 100644 index c30f570e0cd..00000000000 --- a/apis/apps/v1alpha1/webhook_suite_test.go +++ /dev/null @@ -1,138 +0,0 @@ -/* -Copyright (C) 2022-2024 ApeCloud Co., Ltd - -This file is part of KubeBlocks project - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Affero General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Affero General Public License for more details. - -You should have received a copy of the GNU Affero General Public License -along with this program. If not, see . -*/ - -package v1alpha1 - -import ( - "context" - "crypto/tls" - "fmt" - "net" - "path/filepath" - "testing" - "time" - - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - - //+kubebuilder:scaffold:imports - admissionv1beta1 "k8s.io/api/admission/v1beta1" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/client-go/rest" - ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/envtest" - logf "sigs.k8s.io/controller-runtime/pkg/log" - "sigs.k8s.io/controller-runtime/pkg/log/zap" -) - -// These tests use Ginkgo (BDD-style Go testing framework). Refer to -// http://onsi.github.io/ginkgo/ to learn more about Ginkgo. - -var cfg *rest.Config -var k8sClient client.Client -var testEnv *envtest.Environment -var ctx context.Context -var cancel context.CancelFunc - -func TestAPIs(t *testing.T) { - RegisterFailHandler(Fail) - - RunSpecs(t, "Webhook Suite") -} - -var _ = BeforeSuite(func() { - logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))) - - ctx, cancel = context.WithCancel(context.TODO()) - - By("bootstrapping test environment") - testEnv = &envtest.Environment{ - CRDDirectoryPaths: []string{filepath.Join("..", "..", "..", "config", "crd", "bases")}, - ErrorIfCRDPathMissing: false, - WebhookInstallOptions: envtest.WebhookInstallOptions{ - Paths: []string{filepath.Join("..", "..", "..", "config", "webhook")}, - }, - } - - var err error - // cfg is defined in this file globally. - cfg, err = testEnv.Start() - Expect(err).NotTo(HaveOccurred()) - Expect(cfg).NotTo(BeNil()) - - scheme := runtime.NewScheme() - err = AddToScheme(scheme) - Expect(err).NotTo(HaveOccurred()) - - err = admissionv1beta1.AddToScheme(scheme) - Expect(err).NotTo(HaveOccurred()) - - //+kubebuilder:scaffold:scheme - - k8sClient, err = client.New(cfg, client.Options{Scheme: scheme}) - Expect(err).NotTo(HaveOccurred()) - Expect(k8sClient).NotTo(BeNil()) - - // start webhook server using Manager - webhookInstallOptions := &testEnv.WebhookInstallOptions - mgr, err := ctrl.NewManager(cfg, ctrl.Options{ - Scheme: scheme, - // Host: webhookInstallOptions.LocalServingHost, - // Port: webhookInstallOptions.LocalServingPort, - // CertDir: webhookInstallOptions.LocalServingCertDir, - LeaderElection: false, - // MetricsBindAddress: "0", - }) - Expect(err).NotTo(HaveOccurred()) - - err = (&ClusterDefinition{}).SetupWebhookWithManager(mgr) - Expect(err).NotTo(HaveOccurred()) - - err = (&ServiceDescriptor{}).SetupWebhookWithManager(mgr) - Expect(err).NotTo(HaveOccurred()) - - //+kubebuilder:scaffold:webhook - - go func() { - defer GinkgoRecover() - err = mgr.Start(ctx) - Expect(err).NotTo(HaveOccurred()) - }() - - // wait for the webhook server to get ready - dialer := &net.Dialer{Timeout: time.Second} - addrPort := fmt.Sprintf("%s:%d", webhookInstallOptions.LocalServingHost, webhookInstallOptions.LocalServingPort) - Eventually(func() error { - conn, err := tls.DialWithDialer(dialer, "tcp", addrPort, &tls.Config{InsecureSkipVerify: true}) - if err != nil { - return err - } - conn.Close() - return nil - }).Should(Succeed()) - -}) - -var _ = AfterSuite(func() { - cancel() - By("tearing down the test environment") - err := testEnv.Stop() - Expect(err).NotTo(HaveOccurred()) -}) diff --git a/apis/apps/v1alpha1/zz_generated.deepcopy.go b/apis/apps/v1alpha1/zz_generated.deepcopy.go index 6619fae6820..f86aaa75efd 100644 --- a/apis/apps/v1alpha1/zz_generated.deepcopy.go +++ b/apis/apps/v1alpha1/zz_generated.deepcopy.go @@ -31,7 +31,7 @@ import ( "k8s.io/api/core/v1" rbacv1 "k8s.io/api/rbac/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" + runtime "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/util/intstr" ) diff --git a/cmd/manager/main.go b/cmd/manager/main.go index 10943940ef3..115b0e78040 100644 --- a/cmd/manager/main.go +++ b/cmd/manager/main.go @@ -525,16 +525,24 @@ func main() { } if os.Getenv("ENABLE_WEBHOOKS") == "true" { - if err = (&appsv1alpha1.ClusterDefinition{}).SetupWebhookWithManager(mgr); err != nil { + if err = (&appsv1.ClusterDefinition{}).SetupWebhookWithManager(mgr); err != nil { setupLog.Error(err, "unable to create webhook", "webhook", "ClusterDefinition") os.Exit(1) } - if err = (&appsv1.ClusterDefinition{}).SetupWebhookWithManager(mgr); err != nil { - setupLog.Error(err, "unable to create webhook", "webhook", "ClusterDefinition") + if err = (&appsv1.ComponentDefinition{}).SetupWebhookWithManager(mgr); err != nil { + setupLog.Error(err, "unable to create webhook", "webhook", "ComponentDefinition") os.Exit(1) } - if err = (&appsv1alpha1.ServiceDescriptor{}).SetupWebhookWithManager(mgr); err != nil { - setupLog.Error(err, "unable to create webhook", "webhook", "ServiceDescriptor") + if err = (&appsv1.ComponentVersion{}).SetupWebhookWithManager(mgr); err != nil { + setupLog.Error(err, "unable to create webhook", "webhook", "ComponentVersion") + os.Exit(1) + } + if err = (&appsv1.Cluster{}).SetupWebhookWithManager(mgr); err != nil { + setupLog.Error(err, "unable to create webhook", "webhook", "Cluster") + os.Exit(1) + } + if err = (&appsv1.Component{}).SetupWebhookWithManager(mgr); err != nil { + setupLog.Error(err, "unable to create webhook", "webhook", "Component") os.Exit(1) } if err = (&appsv1.ServiceDescriptor{}).SetupWebhookWithManager(mgr); err != nil { diff --git a/config/crd/bases/apps.kubeblocks.io_clusters.yaml b/config/crd/bases/apps.kubeblocks.io_clusters.yaml index 696a0ca9ca2..2cdcc981f4d 100644 --- a/config/crd/bases/apps.kubeblocks.io_clusters.yaml +++ b/config/crd/bases/apps.kubeblocks.io_clusters.yaml @@ -18,6 +18,92 @@ spec: singular: cluster scope: Namespaced versions: + - additionalPrinterColumns: + - description: ClusterDefinition referenced by cluster. + jsonPath: .spec.clusterDefinitionRef + name: CLUSTER-DEFINITION + type: string + - description: Cluster Application Version. + jsonPath: .spec.clusterVersionRef + name: VERSION + type: string + - description: Cluster termination policy. + jsonPath: .spec.terminationPolicy + name: TERMINATION-POLICY + type: string + - description: Cluster Status. + jsonPath: .status.phase + name: STATUS + type: string + - jsonPath: .metadata.creationTimestamp + name: AGE + type: date + name: v1 + schema: + openAPIV3Schema: + description: |- + Cluster offers a unified management interface for a wide variety of database and storage systems: + + + - Relational databases: MySQL, PostgreSQL, MariaDB + - NoSQL databases: Redis, MongoDB + - KV stores: ZooKeeper, etcd + - Analytics systems: ElasticSearch, OpenSearch, ClickHouse, Doris, StarRocks, Solr + - Message queues: Kafka, Pulsar + - Distributed SQL: TiDB, OceanBase + - Vector databases: Qdrant, Milvus, Weaviate + - Object storage: Minio + + + KubeBlocks utilizes an abstraction layer to encapsulate the characteristics of these diverse systems. + A Cluster is composed of multiple Components, each defined by vendors or KubeBlocks Addon developers via ComponentDefinition, + arranged in Directed Acyclic Graph (DAG) topologies. + The topologies, defined in a ClusterDefinition, coordinate reconciliation across Cluster's lifecycle phases: + Creating, Running, Updating, Stopping, Stopped, Deleting. + Lifecycle management ensures that each Component operates in harmony, executing appropriate actions at each lifecycle stage. + + + For sharded-nothing architecture, the Cluster supports managing multiple shards, + each shard managed by a separate Component, supporting dynamic resharding. + + + The Cluster object is aimed to maintain the overall integrity and availability of a database cluster, + serves as the central control point, abstracting the complexity of multiple-component management, + and providing a unified interface for cluster-wide operations. + 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: ClusterSpec defines the desired state of Cluster + properties: + foo: + description: Foo is an example field of Cluster. Edit cluster_types.go + to remove/update + type: string + type: object + status: + description: ClusterStatus defines the observed state of Cluster + type: object + type: object + served: true + storage: true + subresources: + status: {} - additionalPrinterColumns: - description: ClusterDefinition referenced by cluster. jsonPath: .spec.clusterDefinitionRef @@ -17230,6 +17316,6 @@ spec: type: object type: object served: true - storage: true + storage: false subresources: status: {} diff --git a/config/crd/bases/apps.kubeblocks.io_componentdefinitions.yaml b/config/crd/bases/apps.kubeblocks.io_componentdefinitions.yaml index bd9064e8e9f..6ee9d7c1abb 100644 --- a/config/crd/bases/apps.kubeblocks.io_componentdefinitions.yaml +++ b/config/crd/bases/apps.kubeblocks.io_componentdefinitions.yaml @@ -19,6 +19,88 @@ spec: singular: componentdefinition scope: Cluster versions: + - additionalPrinterColumns: + - description: service + jsonPath: .spec.serviceKind + name: SERVICE + type: string + - description: service version + jsonPath: .spec.serviceVersion + name: SERVICE-VERSION + type: string + - description: status phase + jsonPath: .status.phase + name: STATUS + type: string + - jsonPath: .metadata.creationTimestamp + name: AGE + type: date + name: v1 + schema: + openAPIV3Schema: + description: |- + ComponentDefinition serves as a reusable blueprint for creating Components, + encapsulating essential static settings such as Component description, + Pod templates, configuration file templates, scripts, parameter lists, + injected environment variables and their sources, and event handlers. + ComponentDefinition works in conjunction with dynamic settings from the ClusterComponentSpec, + to instantiate Components during Cluster creation. + + + Key aspects that can be defined in a ComponentDefinition include: + + + - PodSpec template: Specifies the PodSpec template used by the Component. + - Configuration templates: Specify the configuration file templates required by the Component. + - Scripts: Provide the necessary scripts for Component management and operations. + - Storage volumes: Specify the storage volumes and their configurations for the Component. + - Pod roles: Outlines various roles of Pods within the Component along with their capabilities. + - Exposed Kubernetes Services: Specify the Services that need to be exposed by the Component. + - System accounts: Define the system accounts required for the Component. + - Monitoring and logging: Configure the exporter and logging settings for the Component. + + + ComponentDefinitions also enable defining reactive behaviors of the Component in response to events, + such as member join/leave, Component addition/deletion, role changes, switch over, and more. + This allows for automatic event handling, thus encapsulating complex behaviors within the Component. + + + Referencing a ComponentDefinition when creating individual Components ensures inheritance of predefined configurations, + promoting reusability and consistency across different deployments and cluster topologies. + 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: ComponentDefinitionSpec defines the desired state of ComponentDefinition + properties: + foo: + description: Foo is an example field of ComponentDefinition. Edit + componentdefinition_types.go to remove/update + type: string + type: object + status: + description: ComponentDefinitionStatus defines the observed state of ComponentDefinition + type: object + type: object + served: true + storage: true + subresources: + status: {} - additionalPrinterColumns: - description: service jsonPath: .spec.serviceKind @@ -13123,6 +13205,6 @@ spec: type: object type: object served: true - storage: true + storage: false subresources: status: {} diff --git a/config/crd/bases/apps.kubeblocks.io_components.yaml b/config/crd/bases/apps.kubeblocks.io_components.yaml index fbe8afc4f84..6d18c4c7e6e 100644 --- a/config/crd/bases/apps.kubeblocks.io_components.yaml +++ b/config/crd/bases/apps.kubeblocks.io_components.yaml @@ -11,7 +11,6 @@ spec: names: categories: - kubeblocks - - all kind: Component listKind: ComponentList plural: components @@ -20,6 +19,74 @@ spec: singular: component scope: Namespaced versions: + - additionalPrinterColumns: + - description: component definition + jsonPath: .spec.compDef + name: DEFINITION + type: string + - description: service version + jsonPath: .spec.serviceVersion + name: SERVICE-VERSION + type: string + - description: status phase + jsonPath: .status.phase + name: STATUS + type: string + - jsonPath: .metadata.creationTimestamp + name: AGE + type: date + name: v1 + schema: + openAPIV3Schema: + description: |- + Component is a fundamental building block of a Cluster object. + For example, a Redis Cluster can include Components like 'redis', 'sentinel', and potentially a proxy like 'twemproxy'. + + + The Component object is responsible for managing the lifecycle of all replicas within a Cluster component, + It supports a wide range of operations including provisioning, stopping, restarting, termination, upgrading, + configuration changes, vertical and horizontal scaling, failover, switchover, cross-node migration, + scheduling configuration, exposing Services, managing system accounts, enabling/disabling exporter, + and configuring log collection. + + + Component is an internal sub-object derived from the user-submitted Cluster object. + It is designed primarily to be used by the KubeBlocks controllers, + users are discouraged from modifying Component objects directly and should use them only for monitoring Component statuses. + 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: ComponentSpec defines the desired state of Component + properties: + foo: + description: Foo is an example field of Component. Edit component_types.go + to remove/update + type: string + type: object + status: + description: ComponentStatus defines the observed state of Component + type: object + type: object + served: true + storage: true + subresources: + status: {} - additionalPrinterColumns: - description: component definition jsonPath: .spec.compDef @@ -7654,6 +7721,6 @@ spec: type: object type: object served: true - storage: true + storage: false subresources: status: {} diff --git a/config/crd/bases/apps.kubeblocks.io_componentversions.yaml b/config/crd/bases/apps.kubeblocks.io_componentversions.yaml index f5fbe385600..bb9cd05805a 100644 --- a/config/crd/bases/apps.kubeblocks.io_componentversions.yaml +++ b/config/crd/bases/apps.kubeblocks.io_componentversions.yaml @@ -19,6 +19,56 @@ spec: singular: componentversion scope: Cluster versions: + - additionalPrinterColumns: + - description: service versions + jsonPath: .status.serviceVersions + name: Versions + type: string + - description: status phase + jsonPath: .status.phase + name: Status + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: ComponentVersion is the Schema for the componentversions 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: ComponentVersionSpec defines the desired state of ComponentVersion + properties: + foo: + description: Foo is an example field of ComponentVersion. Edit componentversion_types.go + to remove/update + type: string + type: object + status: + description: ComponentVersionStatus defines the observed state of ComponentVersion + type: object + type: object + served: true + storage: true + subresources: + status: {} - additionalPrinterColumns: - description: service versions jsonPath: .status.serviceVersions @@ -171,6 +221,6 @@ spec: type: object type: object served: true - storage: true + storage: false subresources: status: {} diff --git a/config/crd/bases/apps.kubeblocks.io_servicedescriptors.yaml b/config/crd/bases/apps.kubeblocks.io_servicedescriptors.yaml index 3b84dcb3e59..99d33d9eaff 100644 --- a/config/crd/bases/apps.kubeblocks.io_servicedescriptors.yaml +++ b/config/crd/bases/apps.kubeblocks.io_servicedescriptors.yaml @@ -11,6 +11,7 @@ spec: names: categories: - kubeblocks + - all kind: ServiceDescriptor listKind: ServiceDescriptorList plural: servicedescriptors diff --git a/config/samples/apps_v1_cluster.yaml b/config/samples/apps_v1_cluster.yaml new file mode 100644 index 00000000000..5caec9a1c71 --- /dev/null +++ b/config/samples/apps_v1_cluster.yaml @@ -0,0 +1,12 @@ +apiVersion: apps.kubeblocks.io/v1 +kind: Cluster +metadata: + labels: + app.kubernetes.io/name: cluster + app.kubernetes.io/instance: cluster-sample + app.kubernetes.io/part-of: kubeblocks + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/created-by: kubeblocks + name: cluster-sample +spec: + # TODO(user): Add fields here diff --git a/config/samples/apps_v1_component.yaml b/config/samples/apps_v1_component.yaml new file mode 100644 index 00000000000..2a9f55bd5a4 --- /dev/null +++ b/config/samples/apps_v1_component.yaml @@ -0,0 +1,12 @@ +apiVersion: apps.kubeblocks.io/v1 +kind: Component +metadata: + labels: + app.kubernetes.io/name: component + app.kubernetes.io/instance: component-sample + app.kubernetes.io/part-of: kubeblocks + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/created-by: kubeblocks + name: component-sample +spec: + # TODO(user): Add fields here diff --git a/config/samples/apps_v1_componentdefinition.yaml b/config/samples/apps_v1_componentdefinition.yaml new file mode 100644 index 00000000000..316bbbb4c2c --- /dev/null +++ b/config/samples/apps_v1_componentdefinition.yaml @@ -0,0 +1,12 @@ +apiVersion: apps.kubeblocks.io/v1 +kind: ComponentDefinition +metadata: + labels: + app.kubernetes.io/name: componentdefinition + app.kubernetes.io/instance: componentdefinition-sample + app.kubernetes.io/part-of: kubeblocks + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/created-by: kubeblocks + name: componentdefinition-sample +spec: + # TODO(user): Add fields here diff --git a/config/samples/apps_v1_componentversion.yaml b/config/samples/apps_v1_componentversion.yaml new file mode 100644 index 00000000000..2b5a1dc0dec --- /dev/null +++ b/config/samples/apps_v1_componentversion.yaml @@ -0,0 +1,12 @@ +apiVersion: apps.kubeblocks.io/v1 +kind: ComponentVersion +metadata: + labels: + app.kubernetes.io/name: componentversion + app.kubernetes.io/instance: componentversion-sample + app.kubernetes.io/part-of: kubeblocks + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/created-by: kubeblocks + name: componentversion-sample +spec: + # TODO(user): Add fields here diff --git a/deploy/helm/crds/apps.kubeblocks.io_clusters.yaml b/deploy/helm/crds/apps.kubeblocks.io_clusters.yaml index 696a0ca9ca2..2cdcc981f4d 100644 --- a/deploy/helm/crds/apps.kubeblocks.io_clusters.yaml +++ b/deploy/helm/crds/apps.kubeblocks.io_clusters.yaml @@ -18,6 +18,92 @@ spec: singular: cluster scope: Namespaced versions: + - additionalPrinterColumns: + - description: ClusterDefinition referenced by cluster. + jsonPath: .spec.clusterDefinitionRef + name: CLUSTER-DEFINITION + type: string + - description: Cluster Application Version. + jsonPath: .spec.clusterVersionRef + name: VERSION + type: string + - description: Cluster termination policy. + jsonPath: .spec.terminationPolicy + name: TERMINATION-POLICY + type: string + - description: Cluster Status. + jsonPath: .status.phase + name: STATUS + type: string + - jsonPath: .metadata.creationTimestamp + name: AGE + type: date + name: v1 + schema: + openAPIV3Schema: + description: |- + Cluster offers a unified management interface for a wide variety of database and storage systems: + + + - Relational databases: MySQL, PostgreSQL, MariaDB + - NoSQL databases: Redis, MongoDB + - KV stores: ZooKeeper, etcd + - Analytics systems: ElasticSearch, OpenSearch, ClickHouse, Doris, StarRocks, Solr + - Message queues: Kafka, Pulsar + - Distributed SQL: TiDB, OceanBase + - Vector databases: Qdrant, Milvus, Weaviate + - Object storage: Minio + + + KubeBlocks utilizes an abstraction layer to encapsulate the characteristics of these diverse systems. + A Cluster is composed of multiple Components, each defined by vendors or KubeBlocks Addon developers via ComponentDefinition, + arranged in Directed Acyclic Graph (DAG) topologies. + The topologies, defined in a ClusterDefinition, coordinate reconciliation across Cluster's lifecycle phases: + Creating, Running, Updating, Stopping, Stopped, Deleting. + Lifecycle management ensures that each Component operates in harmony, executing appropriate actions at each lifecycle stage. + + + For sharded-nothing architecture, the Cluster supports managing multiple shards, + each shard managed by a separate Component, supporting dynamic resharding. + + + The Cluster object is aimed to maintain the overall integrity and availability of a database cluster, + serves as the central control point, abstracting the complexity of multiple-component management, + and providing a unified interface for cluster-wide operations. + 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: ClusterSpec defines the desired state of Cluster + properties: + foo: + description: Foo is an example field of Cluster. Edit cluster_types.go + to remove/update + type: string + type: object + status: + description: ClusterStatus defines the observed state of Cluster + type: object + type: object + served: true + storage: true + subresources: + status: {} - additionalPrinterColumns: - description: ClusterDefinition referenced by cluster. jsonPath: .spec.clusterDefinitionRef @@ -17230,6 +17316,6 @@ spec: type: object type: object served: true - storage: true + storage: false subresources: status: {} diff --git a/deploy/helm/crds/apps.kubeblocks.io_componentdefinitions.yaml b/deploy/helm/crds/apps.kubeblocks.io_componentdefinitions.yaml index bd9064e8e9f..6ee9d7c1abb 100644 --- a/deploy/helm/crds/apps.kubeblocks.io_componentdefinitions.yaml +++ b/deploy/helm/crds/apps.kubeblocks.io_componentdefinitions.yaml @@ -19,6 +19,88 @@ spec: singular: componentdefinition scope: Cluster versions: + - additionalPrinterColumns: + - description: service + jsonPath: .spec.serviceKind + name: SERVICE + type: string + - description: service version + jsonPath: .spec.serviceVersion + name: SERVICE-VERSION + type: string + - description: status phase + jsonPath: .status.phase + name: STATUS + type: string + - jsonPath: .metadata.creationTimestamp + name: AGE + type: date + name: v1 + schema: + openAPIV3Schema: + description: |- + ComponentDefinition serves as a reusable blueprint for creating Components, + encapsulating essential static settings such as Component description, + Pod templates, configuration file templates, scripts, parameter lists, + injected environment variables and their sources, and event handlers. + ComponentDefinition works in conjunction with dynamic settings from the ClusterComponentSpec, + to instantiate Components during Cluster creation. + + + Key aspects that can be defined in a ComponentDefinition include: + + + - PodSpec template: Specifies the PodSpec template used by the Component. + - Configuration templates: Specify the configuration file templates required by the Component. + - Scripts: Provide the necessary scripts for Component management and operations. + - Storage volumes: Specify the storage volumes and their configurations for the Component. + - Pod roles: Outlines various roles of Pods within the Component along with their capabilities. + - Exposed Kubernetes Services: Specify the Services that need to be exposed by the Component. + - System accounts: Define the system accounts required for the Component. + - Monitoring and logging: Configure the exporter and logging settings for the Component. + + + ComponentDefinitions also enable defining reactive behaviors of the Component in response to events, + such as member join/leave, Component addition/deletion, role changes, switch over, and more. + This allows for automatic event handling, thus encapsulating complex behaviors within the Component. + + + Referencing a ComponentDefinition when creating individual Components ensures inheritance of predefined configurations, + promoting reusability and consistency across different deployments and cluster topologies. + 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: ComponentDefinitionSpec defines the desired state of ComponentDefinition + properties: + foo: + description: Foo is an example field of ComponentDefinition. Edit + componentdefinition_types.go to remove/update + type: string + type: object + status: + description: ComponentDefinitionStatus defines the observed state of ComponentDefinition + type: object + type: object + served: true + storage: true + subresources: + status: {} - additionalPrinterColumns: - description: service jsonPath: .spec.serviceKind @@ -13123,6 +13205,6 @@ spec: type: object type: object served: true - storage: true + storage: false subresources: status: {} diff --git a/deploy/helm/crds/apps.kubeblocks.io_components.yaml b/deploy/helm/crds/apps.kubeblocks.io_components.yaml index fbe8afc4f84..6d18c4c7e6e 100644 --- a/deploy/helm/crds/apps.kubeblocks.io_components.yaml +++ b/deploy/helm/crds/apps.kubeblocks.io_components.yaml @@ -11,7 +11,6 @@ spec: names: categories: - kubeblocks - - all kind: Component listKind: ComponentList plural: components @@ -20,6 +19,74 @@ spec: singular: component scope: Namespaced versions: + - additionalPrinterColumns: + - description: component definition + jsonPath: .spec.compDef + name: DEFINITION + type: string + - description: service version + jsonPath: .spec.serviceVersion + name: SERVICE-VERSION + type: string + - description: status phase + jsonPath: .status.phase + name: STATUS + type: string + - jsonPath: .metadata.creationTimestamp + name: AGE + type: date + name: v1 + schema: + openAPIV3Schema: + description: |- + Component is a fundamental building block of a Cluster object. + For example, a Redis Cluster can include Components like 'redis', 'sentinel', and potentially a proxy like 'twemproxy'. + + + The Component object is responsible for managing the lifecycle of all replicas within a Cluster component, + It supports a wide range of operations including provisioning, stopping, restarting, termination, upgrading, + configuration changes, vertical and horizontal scaling, failover, switchover, cross-node migration, + scheduling configuration, exposing Services, managing system accounts, enabling/disabling exporter, + and configuring log collection. + + + Component is an internal sub-object derived from the user-submitted Cluster object. + It is designed primarily to be used by the KubeBlocks controllers, + users are discouraged from modifying Component objects directly and should use them only for monitoring Component statuses. + 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: ComponentSpec defines the desired state of Component + properties: + foo: + description: Foo is an example field of Component. Edit component_types.go + to remove/update + type: string + type: object + status: + description: ComponentStatus defines the observed state of Component + type: object + type: object + served: true + storage: true + subresources: + status: {} - additionalPrinterColumns: - description: component definition jsonPath: .spec.compDef @@ -7654,6 +7721,6 @@ spec: type: object type: object served: true - storage: true + storage: false subresources: status: {} diff --git a/deploy/helm/crds/apps.kubeblocks.io_componentversions.yaml b/deploy/helm/crds/apps.kubeblocks.io_componentversions.yaml index f5fbe385600..bb9cd05805a 100644 --- a/deploy/helm/crds/apps.kubeblocks.io_componentversions.yaml +++ b/deploy/helm/crds/apps.kubeblocks.io_componentversions.yaml @@ -19,6 +19,56 @@ spec: singular: componentversion scope: Cluster versions: + - additionalPrinterColumns: + - description: service versions + jsonPath: .status.serviceVersions + name: Versions + type: string + - description: status phase + jsonPath: .status.phase + name: Status + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: ComponentVersion is the Schema for the componentversions 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: ComponentVersionSpec defines the desired state of ComponentVersion + properties: + foo: + description: Foo is an example field of ComponentVersion. Edit componentversion_types.go + to remove/update + type: string + type: object + status: + description: ComponentVersionStatus defines the observed state of ComponentVersion + type: object + type: object + served: true + storage: true + subresources: + status: {} - additionalPrinterColumns: - description: service versions jsonPath: .status.serviceVersions @@ -171,6 +221,6 @@ spec: type: object type: object served: true - storage: true + storage: false subresources: status: {} diff --git a/deploy/helm/crds/apps.kubeblocks.io_servicedescriptors.yaml b/deploy/helm/crds/apps.kubeblocks.io_servicedescriptors.yaml index 3b84dcb3e59..99d33d9eaff 100644 --- a/deploy/helm/crds/apps.kubeblocks.io_servicedescriptors.yaml +++ b/deploy/helm/crds/apps.kubeblocks.io_servicedescriptors.yaml @@ -11,6 +11,7 @@ spec: names: categories: - kubeblocks + - all kind: ServiceDescriptor listKind: ServiceDescriptorList plural: servicedescriptors diff --git a/docs/developer_docs/api-reference/cluster.md b/docs/developer_docs/api-reference/cluster.md index a65cc264249..1046003bc7c 100644 --- a/docs/developer_docs/api-reference/cluster.md +++ b/docs/developer_docs/api-reference/cluster.md @@ -26,10 +26,122 @@ sidebar_label: Cluster
Resource Types: +

Cluster +

+
+

Cluster offers a unified management interface for a wide variety of database and storage systems:

+
    +
  • Relational databases: MySQL, PostgreSQL, MariaDB
  • +
  • NoSQL databases: Redis, MongoDB
  • +
  • KV stores: ZooKeeper, etcd
  • +
  • Analytics systems: ElasticSearch, OpenSearch, ClickHouse, Doris, StarRocks, Solr
  • +
  • Message queues: Kafka, Pulsar
  • +
  • Distributed SQL: TiDB, OceanBase
  • +
  • Vector databases: Qdrant, Milvus, Weaviate
  • +
  • Object storage: Minio
  • +
+

KubeBlocks utilizes an abstraction layer to encapsulate the characteristics of these diverse systems. +A Cluster is composed of multiple Components, each defined by vendors or KubeBlocks Addon developers via ComponentDefinition, +arranged in Directed Acyclic Graph (DAG) topologies. +The topologies, defined in a ClusterDefinition, coordinate reconciliation across Cluster’s lifecycle phases: +Creating, Running, Updating, Stopping, Stopped, Deleting. +Lifecycle management ensures that each Component operates in harmony, executing appropriate actions at each lifecycle stage.

+

For sharded-nothing architecture, the Cluster supports managing multiple shards, +each shard managed by a separate Component, supporting dynamic resharding.

+

The Cluster object is aimed to maintain the overall integrity and availability of a database cluster, +serves as the central control point, abstracting the complexity of multiple-component management, +and providing a unified interface for cluster-wide operations.

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+apiVersion
+string
+apps.kubeblocks.io/v1 +
+kind
+string +
Cluster
+metadata
+ + +Kubernetes meta/v1.ObjectMeta + + +
+Refer to the Kubernetes API documentation for the fields of the +metadata field. +
+spec
+ + +ClusterSpec + + +
+
+
+ + + + + +
+foo
+ +string + +
+

Foo is an example field of Cluster. Edit cluster_types.go to remove/update

+
+
+status
+ + +ClusterStatus + + +
+

ClusterDefinition

@@ -122,6 +234,285 @@ ClusterDefinitionStatus +

Component +

+
+

Component is a fundamental building block of a Cluster object. +For example, a Redis Cluster can include Components like ‘redis’, ‘sentinel’, and potentially a proxy like ‘twemproxy’.

+

The Component object is responsible for managing the lifecycle of all replicas within a Cluster component, +It supports a wide range of operations including provisioning, stopping, restarting, termination, upgrading, +configuration changes, vertical and horizontal scaling, failover, switchover, cross-node migration, +scheduling configuration, exposing Services, managing system accounts, enabling/disabling exporter, +and configuring log collection.

+

Component is an internal sub-object derived from the user-submitted Cluster object. +It is designed primarily to be used by the KubeBlocks controllers, +users are discouraged from modifying Component objects directly and should use them only for monitoring Component statuses.

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+apiVersion
+string
+apps.kubeblocks.io/v1 +
+kind
+string +
Component
+metadata
+ + +Kubernetes meta/v1.ObjectMeta + + +
+Refer to the Kubernetes API documentation for the fields of the +metadata field. +
+spec
+ + +ComponentSpec + + +
+
+
+ + + + + +
+foo
+ +string + +
+

Foo is an example field of Component. Edit component_types.go to remove/update

+
+
+status
+ + +ComponentStatus + + +
+
+

ComponentDefinition +

+
+

ComponentDefinition serves as a reusable blueprint for creating Components, +encapsulating essential static settings such as Component description, +Pod templates, configuration file templates, scripts, parameter lists, +injected environment variables and their sources, and event handlers. +ComponentDefinition works in conjunction with dynamic settings from the ClusterComponentSpec, +to instantiate Components during Cluster creation.

+

Key aspects that can be defined in a ComponentDefinition include:

+
    +
  • PodSpec template: Specifies the PodSpec template used by the Component.
  • +
  • Configuration templates: Specify the configuration file templates required by the Component.
  • +
  • Scripts: Provide the necessary scripts for Component management and operations.
  • +
  • Storage volumes: Specify the storage volumes and their configurations for the Component.
  • +
  • Pod roles: Outlines various roles of Pods within the Component along with their capabilities.
  • +
  • Exposed Kubernetes Services: Specify the Services that need to be exposed by the Component.
  • +
  • System accounts: Define the system accounts required for the Component.
  • +
  • Monitoring and logging: Configure the exporter and logging settings for the Component.
  • +
+

ComponentDefinitions also enable defining reactive behaviors of the Component in response to events, +such as member join/leave, Component addition/deletion, role changes, switch over, and more. +This allows for automatic event handling, thus encapsulating complex behaviors within the Component.

+

Referencing a ComponentDefinition when creating individual Components ensures inheritance of predefined configurations, +promoting reusability and consistency across different deployments and cluster topologies.

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+apiVersion
+string
+apps.kubeblocks.io/v1 +
+kind
+string +
ComponentDefinition
+metadata
+ + +Kubernetes meta/v1.ObjectMeta + + +
+Refer to the Kubernetes API documentation for the fields of the +metadata field. +
+spec
+ + +ComponentDefinitionSpec + + +
+
+
+ + + + + +
+foo
+ +string + +
+

Foo is an example field of ComponentDefinition. Edit componentdefinition_types.go to remove/update

+
+
+status
+ + +ComponentDefinitionStatus + + +
+
+

ComponentVersion +

+
+

ComponentVersion is the Schema for the componentversions API

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+apiVersion
+string
+apps.kubeblocks.io/v1 +
+kind
+string +
ComponentVersion
+metadata
+ + +Kubernetes meta/v1.ObjectMeta + + +
+Refer to the Kubernetes API documentation for the fields of the +metadata field. +
+spec
+ + +ComponentVersionSpec + + +
+
+
+ + + + + +
+foo
+ +string + +
+

Foo is an example field of ComponentVersion. Edit componentversion_types.go to remove/update

+
+
+status
+ + +ComponentVersionStatus + + +
+

ServiceDescriptor

@@ -388,6 +779,43 @@ string +

ClusterSpec +

+

+(Appears on:Cluster) +

+
+

ClusterSpec defines the desired state of Cluster

+
+ + + + + + + + + + + + + +
FieldDescription
+foo
+ +string + +
+

Foo is an example field of Cluster. Edit cluster_types.go to remove/update

+
+

ClusterStatus +

+

+(Appears on:Cluster) +

+
+

ClusterStatus defines the observed state of Cluster

+

ClusterTopology

@@ -579,6 +1007,117 @@ separated by commas.

+

ComponentDefinitionSpec +

+

+(Appears on:ComponentDefinition) +

+
+

ComponentDefinitionSpec defines the desired state of ComponentDefinition

+
+ + + + + + + + + + + + + +
FieldDescription
+foo
+ +string + +
+

Foo is an example field of ComponentDefinition. Edit componentdefinition_types.go to remove/update

+
+

ComponentDefinitionStatus +

+

+(Appears on:ComponentDefinition) +

+
+

ComponentDefinitionStatus defines the observed state of ComponentDefinition

+
+

ComponentSpec +

+

+(Appears on:Component) +

+
+

ComponentSpec defines the desired state of Component

+
+ + + + + + + + + + + + + +
FieldDescription
+foo
+ +string + +
+

Foo is an example field of Component. Edit component_types.go to remove/update

+
+

ComponentStatus +

+

+(Appears on:Component) +

+
+

ComponentStatus defines the observed state of Component

+
+

ComponentVersionSpec +

+

+(Appears on:ComponentVersion) +

+
+

ComponentVersionSpec defines the desired state of ComponentVersion

+
+ + + + + + + + + + + + + +
FieldDescription
+foo
+ +string + +
+

Foo is an example field of ComponentVersion. Edit componentversion_types.go to remove/update

+
+

ComponentVersionStatus +

+

+(Appears on:ComponentVersion) +

+
+

ComponentVersionStatus defines the observed state of ComponentVersion

+

ConnectionCredentialAuth

diff --git a/pkg/client/clientset/versioned/typed/apps/v1/apps_client.go b/pkg/client/clientset/versioned/typed/apps/v1/apps_client.go index 0686d328598..109a7967cd3 100644 --- a/pkg/client/clientset/versioned/typed/apps/v1/apps_client.go +++ b/pkg/client/clientset/versioned/typed/apps/v1/apps_client.go @@ -28,7 +28,11 @@ import ( type AppsV1Interface interface { RESTClient() rest.Interface + ClustersGetter ClusterDefinitionsGetter + ComponentsGetter + ComponentDefinitionsGetter + ComponentVersionsGetter ServiceDescriptorsGetter } @@ -37,10 +41,26 @@ type AppsV1Client struct { restClient rest.Interface } +func (c *AppsV1Client) Clusters(namespace string) ClusterInterface { + return newClusters(c, namespace) +} + func (c *AppsV1Client) ClusterDefinitions() ClusterDefinitionInterface { return newClusterDefinitions(c) } +func (c *AppsV1Client) Components(namespace string) ComponentInterface { + return newComponents(c, namespace) +} + +func (c *AppsV1Client) ComponentDefinitions() ComponentDefinitionInterface { + return newComponentDefinitions(c) +} + +func (c *AppsV1Client) ComponentVersions() ComponentVersionInterface { + return newComponentVersions(c) +} + func (c *AppsV1Client) ServiceDescriptors(namespace string) ServiceDescriptorInterface { return newServiceDescriptors(c, namespace) } diff --git a/pkg/client/clientset/versioned/typed/apps/v1/cluster.go b/pkg/client/clientset/versioned/typed/apps/v1/cluster.go new file mode 100644 index 00000000000..09a8dc02796 --- /dev/null +++ b/pkg/client/clientset/versioned/typed/apps/v1/cluster.go @@ -0,0 +1,195 @@ +/* +Copyright (C) 2022-2024 ApeCloud Co., Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1 + +import ( + "context" + "time" + + v1 "github.com/apecloud/kubeblocks/apis/apps/v1" + scheme "github.com/apecloud/kubeblocks/pkg/client/clientset/versioned/scheme" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + rest "k8s.io/client-go/rest" +) + +// ClustersGetter has a method to return a ClusterInterface. +// A group's client should implement this interface. +type ClustersGetter interface { + Clusters(namespace string) ClusterInterface +} + +// ClusterInterface has methods to work with Cluster resources. +type ClusterInterface interface { + Create(ctx context.Context, cluster *v1.Cluster, opts metav1.CreateOptions) (*v1.Cluster, error) + Update(ctx context.Context, cluster *v1.Cluster, opts metav1.UpdateOptions) (*v1.Cluster, error) + UpdateStatus(ctx context.Context, cluster *v1.Cluster, opts metav1.UpdateOptions) (*v1.Cluster, error) + Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error + Get(ctx context.Context, name string, opts metav1.GetOptions) (*v1.Cluster, error) + List(ctx context.Context, opts metav1.ListOptions) (*v1.ClusterList, error) + Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.Cluster, err error) + ClusterExpansion +} + +// clusters implements ClusterInterface +type clusters struct { + client rest.Interface + ns string +} + +// newClusters returns a Clusters +func newClusters(c *AppsV1Client, namespace string) *clusters { + return &clusters{ + client: c.RESTClient(), + ns: namespace, + } +} + +// Get takes name of the cluster, and returns the corresponding cluster object, and an error if there is any. +func (c *clusters) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.Cluster, err error) { + result = &v1.Cluster{} + err = c.client.Get(). + Namespace(c.ns). + Resource("clusters"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(ctx). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of Clusters that match those selectors. +func (c *clusters) List(ctx context.Context, opts metav1.ListOptions) (result *v1.ClusterList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1.ClusterList{} + err = c.client.Get(). + Namespace(c.ns). + Resource("clusters"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(ctx). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested clusters. +func (c *clusters) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + opts.Watch = true + return c.client.Get(). + Namespace(c.ns). + Resource("clusters"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch(ctx) +} + +// Create takes the representation of a cluster and creates it. Returns the server's representation of the cluster, and an error, if there is any. +func (c *clusters) Create(ctx context.Context, cluster *v1.Cluster, opts metav1.CreateOptions) (result *v1.Cluster, err error) { + result = &v1.Cluster{} + err = c.client.Post(). + Namespace(c.ns). + Resource("clusters"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(cluster). + Do(ctx). + Into(result) + return +} + +// Update takes the representation of a cluster and updates it. Returns the server's representation of the cluster, and an error, if there is any. +func (c *clusters) Update(ctx context.Context, cluster *v1.Cluster, opts metav1.UpdateOptions) (result *v1.Cluster, err error) { + result = &v1.Cluster{} + err = c.client.Put(). + Namespace(c.ns). + Resource("clusters"). + Name(cluster.Name). + VersionedParams(&opts, scheme.ParameterCodec). + Body(cluster). + Do(ctx). + Into(result) + return +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *clusters) UpdateStatus(ctx context.Context, cluster *v1.Cluster, opts metav1.UpdateOptions) (result *v1.Cluster, err error) { + result = &v1.Cluster{} + err = c.client.Put(). + Namespace(c.ns). + Resource("clusters"). + Name(cluster.Name). + SubResource("status"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(cluster). + Do(ctx). + Into(result) + return +} + +// Delete takes name of the cluster and deletes it. Returns an error if one occurs. +func (c *clusters) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { + return c.client.Delete(). + Namespace(c.ns). + Resource("clusters"). + Name(name). + Body(&opts). + Do(ctx). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *clusters) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { + var timeout time.Duration + if listOpts.TimeoutSeconds != nil { + timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Namespace(c.ns). + Resource("clusters"). + VersionedParams(&listOpts, scheme.ParameterCodec). + Timeout(timeout). + Body(&opts). + Do(ctx). + Error() +} + +// Patch applies the patch and returns the patched cluster. +func (c *clusters) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.Cluster, err error) { + result = &v1.Cluster{} + err = c.client.Patch(pt). + Namespace(c.ns). + Resource("clusters"). + Name(name). + SubResource(subresources...). + VersionedParams(&opts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} diff --git a/pkg/client/clientset/versioned/typed/apps/v1/component.go b/pkg/client/clientset/versioned/typed/apps/v1/component.go new file mode 100644 index 00000000000..9a0936600eb --- /dev/null +++ b/pkg/client/clientset/versioned/typed/apps/v1/component.go @@ -0,0 +1,195 @@ +/* +Copyright (C) 2022-2024 ApeCloud Co., Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1 + +import ( + "context" + "time" + + v1 "github.com/apecloud/kubeblocks/apis/apps/v1" + scheme "github.com/apecloud/kubeblocks/pkg/client/clientset/versioned/scheme" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + rest "k8s.io/client-go/rest" +) + +// ComponentsGetter has a method to return a ComponentInterface. +// A group's client should implement this interface. +type ComponentsGetter interface { + Components(namespace string) ComponentInterface +} + +// ComponentInterface has methods to work with Component resources. +type ComponentInterface interface { + Create(ctx context.Context, component *v1.Component, opts metav1.CreateOptions) (*v1.Component, error) + Update(ctx context.Context, component *v1.Component, opts metav1.UpdateOptions) (*v1.Component, error) + UpdateStatus(ctx context.Context, component *v1.Component, opts metav1.UpdateOptions) (*v1.Component, error) + Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error + Get(ctx context.Context, name string, opts metav1.GetOptions) (*v1.Component, error) + List(ctx context.Context, opts metav1.ListOptions) (*v1.ComponentList, error) + Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.Component, err error) + ComponentExpansion +} + +// components implements ComponentInterface +type components struct { + client rest.Interface + ns string +} + +// newComponents returns a Components +func newComponents(c *AppsV1Client, namespace string) *components { + return &components{ + client: c.RESTClient(), + ns: namespace, + } +} + +// Get takes name of the component, and returns the corresponding component object, and an error if there is any. +func (c *components) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.Component, err error) { + result = &v1.Component{} + err = c.client.Get(). + Namespace(c.ns). + Resource("components"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(ctx). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of Components that match those selectors. +func (c *components) List(ctx context.Context, opts metav1.ListOptions) (result *v1.ComponentList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1.ComponentList{} + err = c.client.Get(). + Namespace(c.ns). + Resource("components"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(ctx). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested components. +func (c *components) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + opts.Watch = true + return c.client.Get(). + Namespace(c.ns). + Resource("components"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch(ctx) +} + +// Create takes the representation of a component and creates it. Returns the server's representation of the component, and an error, if there is any. +func (c *components) Create(ctx context.Context, component *v1.Component, opts metav1.CreateOptions) (result *v1.Component, err error) { + result = &v1.Component{} + err = c.client.Post(). + Namespace(c.ns). + Resource("components"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(component). + Do(ctx). + Into(result) + return +} + +// Update takes the representation of a component and updates it. Returns the server's representation of the component, and an error, if there is any. +func (c *components) Update(ctx context.Context, component *v1.Component, opts metav1.UpdateOptions) (result *v1.Component, err error) { + result = &v1.Component{} + err = c.client.Put(). + Namespace(c.ns). + Resource("components"). + Name(component.Name). + VersionedParams(&opts, scheme.ParameterCodec). + Body(component). + Do(ctx). + Into(result) + return +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *components) UpdateStatus(ctx context.Context, component *v1.Component, opts metav1.UpdateOptions) (result *v1.Component, err error) { + result = &v1.Component{} + err = c.client.Put(). + Namespace(c.ns). + Resource("components"). + Name(component.Name). + SubResource("status"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(component). + Do(ctx). + Into(result) + return +} + +// Delete takes name of the component and deletes it. Returns an error if one occurs. +func (c *components) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { + return c.client.Delete(). + Namespace(c.ns). + Resource("components"). + Name(name). + Body(&opts). + Do(ctx). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *components) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { + var timeout time.Duration + if listOpts.TimeoutSeconds != nil { + timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Namespace(c.ns). + Resource("components"). + VersionedParams(&listOpts, scheme.ParameterCodec). + Timeout(timeout). + Body(&opts). + Do(ctx). + Error() +} + +// Patch applies the patch and returns the patched component. +func (c *components) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.Component, err error) { + result = &v1.Component{} + err = c.client.Patch(pt). + Namespace(c.ns). + Resource("components"). + Name(name). + SubResource(subresources...). + VersionedParams(&opts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} diff --git a/pkg/client/clientset/versioned/typed/apps/v1/componentdefinition.go b/pkg/client/clientset/versioned/typed/apps/v1/componentdefinition.go new file mode 100644 index 00000000000..528ce41c8c8 --- /dev/null +++ b/pkg/client/clientset/versioned/typed/apps/v1/componentdefinition.go @@ -0,0 +1,184 @@ +/* +Copyright (C) 2022-2024 ApeCloud Co., Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1 + +import ( + "context" + "time" + + v1 "github.com/apecloud/kubeblocks/apis/apps/v1" + scheme "github.com/apecloud/kubeblocks/pkg/client/clientset/versioned/scheme" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + rest "k8s.io/client-go/rest" +) + +// ComponentDefinitionsGetter has a method to return a ComponentDefinitionInterface. +// A group's client should implement this interface. +type ComponentDefinitionsGetter interface { + ComponentDefinitions() ComponentDefinitionInterface +} + +// ComponentDefinitionInterface has methods to work with ComponentDefinition resources. +type ComponentDefinitionInterface interface { + Create(ctx context.Context, componentDefinition *v1.ComponentDefinition, opts metav1.CreateOptions) (*v1.ComponentDefinition, error) + Update(ctx context.Context, componentDefinition *v1.ComponentDefinition, opts metav1.UpdateOptions) (*v1.ComponentDefinition, error) + UpdateStatus(ctx context.Context, componentDefinition *v1.ComponentDefinition, opts metav1.UpdateOptions) (*v1.ComponentDefinition, error) + Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error + Get(ctx context.Context, name string, opts metav1.GetOptions) (*v1.ComponentDefinition, error) + List(ctx context.Context, opts metav1.ListOptions) (*v1.ComponentDefinitionList, error) + Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.ComponentDefinition, err error) + ComponentDefinitionExpansion +} + +// componentDefinitions implements ComponentDefinitionInterface +type componentDefinitions struct { + client rest.Interface +} + +// newComponentDefinitions returns a ComponentDefinitions +func newComponentDefinitions(c *AppsV1Client) *componentDefinitions { + return &componentDefinitions{ + client: c.RESTClient(), + } +} + +// Get takes name of the componentDefinition, and returns the corresponding componentDefinition object, and an error if there is any. +func (c *componentDefinitions) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.ComponentDefinition, err error) { + result = &v1.ComponentDefinition{} + err = c.client.Get(). + Resource("componentdefinitions"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(ctx). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of ComponentDefinitions that match those selectors. +func (c *componentDefinitions) List(ctx context.Context, opts metav1.ListOptions) (result *v1.ComponentDefinitionList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1.ComponentDefinitionList{} + err = c.client.Get(). + Resource("componentdefinitions"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(ctx). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested componentDefinitions. +func (c *componentDefinitions) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + opts.Watch = true + return c.client.Get(). + Resource("componentdefinitions"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch(ctx) +} + +// Create takes the representation of a componentDefinition and creates it. Returns the server's representation of the componentDefinition, and an error, if there is any. +func (c *componentDefinitions) Create(ctx context.Context, componentDefinition *v1.ComponentDefinition, opts metav1.CreateOptions) (result *v1.ComponentDefinition, err error) { + result = &v1.ComponentDefinition{} + err = c.client.Post(). + Resource("componentdefinitions"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(componentDefinition). + Do(ctx). + Into(result) + return +} + +// Update takes the representation of a componentDefinition and updates it. Returns the server's representation of the componentDefinition, and an error, if there is any. +func (c *componentDefinitions) Update(ctx context.Context, componentDefinition *v1.ComponentDefinition, opts metav1.UpdateOptions) (result *v1.ComponentDefinition, err error) { + result = &v1.ComponentDefinition{} + err = c.client.Put(). + Resource("componentdefinitions"). + Name(componentDefinition.Name). + VersionedParams(&opts, scheme.ParameterCodec). + Body(componentDefinition). + Do(ctx). + Into(result) + return +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *componentDefinitions) UpdateStatus(ctx context.Context, componentDefinition *v1.ComponentDefinition, opts metav1.UpdateOptions) (result *v1.ComponentDefinition, err error) { + result = &v1.ComponentDefinition{} + err = c.client.Put(). + Resource("componentdefinitions"). + Name(componentDefinition.Name). + SubResource("status"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(componentDefinition). + Do(ctx). + Into(result) + return +} + +// Delete takes name of the componentDefinition and deletes it. Returns an error if one occurs. +func (c *componentDefinitions) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { + return c.client.Delete(). + Resource("componentdefinitions"). + Name(name). + Body(&opts). + Do(ctx). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *componentDefinitions) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { + var timeout time.Duration + if listOpts.TimeoutSeconds != nil { + timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Resource("componentdefinitions"). + VersionedParams(&listOpts, scheme.ParameterCodec). + Timeout(timeout). + Body(&opts). + Do(ctx). + Error() +} + +// Patch applies the patch and returns the patched componentDefinition. +func (c *componentDefinitions) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.ComponentDefinition, err error) { + result = &v1.ComponentDefinition{} + err = c.client.Patch(pt). + Resource("componentdefinitions"). + Name(name). + SubResource(subresources...). + VersionedParams(&opts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} diff --git a/pkg/client/clientset/versioned/typed/apps/v1/componentversion.go b/pkg/client/clientset/versioned/typed/apps/v1/componentversion.go new file mode 100644 index 00000000000..e2be9b02cdd --- /dev/null +++ b/pkg/client/clientset/versioned/typed/apps/v1/componentversion.go @@ -0,0 +1,184 @@ +/* +Copyright (C) 2022-2024 ApeCloud Co., Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1 + +import ( + "context" + "time" + + v1 "github.com/apecloud/kubeblocks/apis/apps/v1" + scheme "github.com/apecloud/kubeblocks/pkg/client/clientset/versioned/scheme" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + rest "k8s.io/client-go/rest" +) + +// ComponentVersionsGetter has a method to return a ComponentVersionInterface. +// A group's client should implement this interface. +type ComponentVersionsGetter interface { + ComponentVersions() ComponentVersionInterface +} + +// ComponentVersionInterface has methods to work with ComponentVersion resources. +type ComponentVersionInterface interface { + Create(ctx context.Context, componentVersion *v1.ComponentVersion, opts metav1.CreateOptions) (*v1.ComponentVersion, error) + Update(ctx context.Context, componentVersion *v1.ComponentVersion, opts metav1.UpdateOptions) (*v1.ComponentVersion, error) + UpdateStatus(ctx context.Context, componentVersion *v1.ComponentVersion, opts metav1.UpdateOptions) (*v1.ComponentVersion, error) + Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error + Get(ctx context.Context, name string, opts metav1.GetOptions) (*v1.ComponentVersion, error) + List(ctx context.Context, opts metav1.ListOptions) (*v1.ComponentVersionList, error) + Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.ComponentVersion, err error) + ComponentVersionExpansion +} + +// componentVersions implements ComponentVersionInterface +type componentVersions struct { + client rest.Interface +} + +// newComponentVersions returns a ComponentVersions +func newComponentVersions(c *AppsV1Client) *componentVersions { + return &componentVersions{ + client: c.RESTClient(), + } +} + +// Get takes name of the componentVersion, and returns the corresponding componentVersion object, and an error if there is any. +func (c *componentVersions) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.ComponentVersion, err error) { + result = &v1.ComponentVersion{} + err = c.client.Get(). + Resource("componentversions"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(ctx). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of ComponentVersions that match those selectors. +func (c *componentVersions) List(ctx context.Context, opts metav1.ListOptions) (result *v1.ComponentVersionList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1.ComponentVersionList{} + err = c.client.Get(). + Resource("componentversions"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(ctx). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested componentVersions. +func (c *componentVersions) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + opts.Watch = true + return c.client.Get(). + Resource("componentversions"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch(ctx) +} + +// Create takes the representation of a componentVersion and creates it. Returns the server's representation of the componentVersion, and an error, if there is any. +func (c *componentVersions) Create(ctx context.Context, componentVersion *v1.ComponentVersion, opts metav1.CreateOptions) (result *v1.ComponentVersion, err error) { + result = &v1.ComponentVersion{} + err = c.client.Post(). + Resource("componentversions"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(componentVersion). + Do(ctx). + Into(result) + return +} + +// Update takes the representation of a componentVersion and updates it. Returns the server's representation of the componentVersion, and an error, if there is any. +func (c *componentVersions) Update(ctx context.Context, componentVersion *v1.ComponentVersion, opts metav1.UpdateOptions) (result *v1.ComponentVersion, err error) { + result = &v1.ComponentVersion{} + err = c.client.Put(). + Resource("componentversions"). + Name(componentVersion.Name). + VersionedParams(&opts, scheme.ParameterCodec). + Body(componentVersion). + Do(ctx). + Into(result) + return +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *componentVersions) UpdateStatus(ctx context.Context, componentVersion *v1.ComponentVersion, opts metav1.UpdateOptions) (result *v1.ComponentVersion, err error) { + result = &v1.ComponentVersion{} + err = c.client.Put(). + Resource("componentversions"). + Name(componentVersion.Name). + SubResource("status"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(componentVersion). + Do(ctx). + Into(result) + return +} + +// Delete takes name of the componentVersion and deletes it. Returns an error if one occurs. +func (c *componentVersions) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { + return c.client.Delete(). + Resource("componentversions"). + Name(name). + Body(&opts). + Do(ctx). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *componentVersions) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { + var timeout time.Duration + if listOpts.TimeoutSeconds != nil { + timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Resource("componentversions"). + VersionedParams(&listOpts, scheme.ParameterCodec). + Timeout(timeout). + Body(&opts). + Do(ctx). + Error() +} + +// Patch applies the patch and returns the patched componentVersion. +func (c *componentVersions) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.ComponentVersion, err error) { + result = &v1.ComponentVersion{} + err = c.client.Patch(pt). + Resource("componentversions"). + Name(name). + SubResource(subresources...). + VersionedParams(&opts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} diff --git a/pkg/client/clientset/versioned/typed/apps/v1/fake/fake_apps_client.go b/pkg/client/clientset/versioned/typed/apps/v1/fake/fake_apps_client.go index 8af07ad5e70..67a097c21cd 100644 --- a/pkg/client/clientset/versioned/typed/apps/v1/fake/fake_apps_client.go +++ b/pkg/client/clientset/versioned/typed/apps/v1/fake/fake_apps_client.go @@ -28,10 +28,26 @@ type FakeAppsV1 struct { *testing.Fake } +func (c *FakeAppsV1) Clusters(namespace string) v1.ClusterInterface { + return &FakeClusters{c, namespace} +} + func (c *FakeAppsV1) ClusterDefinitions() v1.ClusterDefinitionInterface { return &FakeClusterDefinitions{c} } +func (c *FakeAppsV1) Components(namespace string) v1.ComponentInterface { + return &FakeComponents{c, namespace} +} + +func (c *FakeAppsV1) ComponentDefinitions() v1.ComponentDefinitionInterface { + return &FakeComponentDefinitions{c} +} + +func (c *FakeAppsV1) ComponentVersions() v1.ComponentVersionInterface { + return &FakeComponentVersions{c} +} + func (c *FakeAppsV1) ServiceDescriptors(namespace string) v1.ServiceDescriptorInterface { return &FakeServiceDescriptors{c, namespace} } diff --git a/pkg/client/clientset/versioned/typed/apps/v1/fake/fake_cluster.go b/pkg/client/clientset/versioned/typed/apps/v1/fake/fake_cluster.go new file mode 100644 index 00000000000..990cf3573c4 --- /dev/null +++ b/pkg/client/clientset/versioned/typed/apps/v1/fake/fake_cluster.go @@ -0,0 +1,141 @@ +/* +Copyright (C) 2022-2024 ApeCloud Co., Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + "context" + + v1 "github.com/apecloud/kubeblocks/apis/apps/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + labels "k8s.io/apimachinery/pkg/labels" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + testing "k8s.io/client-go/testing" +) + +// FakeClusters implements ClusterInterface +type FakeClusters struct { + Fake *FakeAppsV1 + ns string +} + +var clustersResource = v1.SchemeGroupVersion.WithResource("clusters") + +var clustersKind = v1.SchemeGroupVersion.WithKind("Cluster") + +// Get takes name of the cluster, and returns the corresponding cluster object, and an error if there is any. +func (c *FakeClusters) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.Cluster, err error) { + obj, err := c.Fake. + Invokes(testing.NewGetAction(clustersResource, c.ns, name), &v1.Cluster{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.Cluster), err +} + +// List takes label and field selectors, and returns the list of Clusters that match those selectors. +func (c *FakeClusters) List(ctx context.Context, opts metav1.ListOptions) (result *v1.ClusterList, err error) { + obj, err := c.Fake. + Invokes(testing.NewListAction(clustersResource, clustersKind, c.ns, opts), &v1.ClusterList{}) + + if obj == nil { + return nil, err + } + + label, _, _ := testing.ExtractFromListOptions(opts) + if label == nil { + label = labels.Everything() + } + list := &v1.ClusterList{ListMeta: obj.(*v1.ClusterList).ListMeta} + for _, item := range obj.(*v1.ClusterList).Items { + if label.Matches(labels.Set(item.Labels)) { + list.Items = append(list.Items, item) + } + } + return list, err +} + +// Watch returns a watch.Interface that watches the requested clusters. +func (c *FakeClusters) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { + return c.Fake. + InvokesWatch(testing.NewWatchAction(clustersResource, c.ns, opts)) + +} + +// Create takes the representation of a cluster and creates it. Returns the server's representation of the cluster, and an error, if there is any. +func (c *FakeClusters) Create(ctx context.Context, cluster *v1.Cluster, opts metav1.CreateOptions) (result *v1.Cluster, err error) { + obj, err := c.Fake. + Invokes(testing.NewCreateAction(clustersResource, c.ns, cluster), &v1.Cluster{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.Cluster), err +} + +// Update takes the representation of a cluster and updates it. Returns the server's representation of the cluster, and an error, if there is any. +func (c *FakeClusters) Update(ctx context.Context, cluster *v1.Cluster, opts metav1.UpdateOptions) (result *v1.Cluster, err error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateAction(clustersResource, c.ns, cluster), &v1.Cluster{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.Cluster), err +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *FakeClusters) UpdateStatus(ctx context.Context, cluster *v1.Cluster, opts metav1.UpdateOptions) (*v1.Cluster, error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateSubresourceAction(clustersResource, "status", c.ns, cluster), &v1.Cluster{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.Cluster), err +} + +// Delete takes name of the cluster and deletes it. Returns an error if one occurs. +func (c *FakeClusters) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { + _, err := c.Fake. + Invokes(testing.NewDeleteActionWithOptions(clustersResource, c.ns, name, opts), &v1.Cluster{}) + + return err +} + +// DeleteCollection deletes a collection of objects. +func (c *FakeClusters) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { + action := testing.NewDeleteCollectionAction(clustersResource, c.ns, listOpts) + + _, err := c.Fake.Invokes(action, &v1.ClusterList{}) + return err +} + +// Patch applies the patch and returns the patched cluster. +func (c *FakeClusters) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.Cluster, err error) { + obj, err := c.Fake. + Invokes(testing.NewPatchSubresourceAction(clustersResource, c.ns, name, pt, data, subresources...), &v1.Cluster{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.Cluster), err +} diff --git a/pkg/client/clientset/versioned/typed/apps/v1/fake/fake_component.go b/pkg/client/clientset/versioned/typed/apps/v1/fake/fake_component.go new file mode 100644 index 00000000000..cbf51312c1a --- /dev/null +++ b/pkg/client/clientset/versioned/typed/apps/v1/fake/fake_component.go @@ -0,0 +1,141 @@ +/* +Copyright (C) 2022-2024 ApeCloud Co., Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + "context" + + v1 "github.com/apecloud/kubeblocks/apis/apps/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + labels "k8s.io/apimachinery/pkg/labels" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + testing "k8s.io/client-go/testing" +) + +// FakeComponents implements ComponentInterface +type FakeComponents struct { + Fake *FakeAppsV1 + ns string +} + +var componentsResource = v1.SchemeGroupVersion.WithResource("components") + +var componentsKind = v1.SchemeGroupVersion.WithKind("Component") + +// Get takes name of the component, and returns the corresponding component object, and an error if there is any. +func (c *FakeComponents) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.Component, err error) { + obj, err := c.Fake. + Invokes(testing.NewGetAction(componentsResource, c.ns, name), &v1.Component{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.Component), err +} + +// List takes label and field selectors, and returns the list of Components that match those selectors. +func (c *FakeComponents) List(ctx context.Context, opts metav1.ListOptions) (result *v1.ComponentList, err error) { + obj, err := c.Fake. + Invokes(testing.NewListAction(componentsResource, componentsKind, c.ns, opts), &v1.ComponentList{}) + + if obj == nil { + return nil, err + } + + label, _, _ := testing.ExtractFromListOptions(opts) + if label == nil { + label = labels.Everything() + } + list := &v1.ComponentList{ListMeta: obj.(*v1.ComponentList).ListMeta} + for _, item := range obj.(*v1.ComponentList).Items { + if label.Matches(labels.Set(item.Labels)) { + list.Items = append(list.Items, item) + } + } + return list, err +} + +// Watch returns a watch.Interface that watches the requested components. +func (c *FakeComponents) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { + return c.Fake. + InvokesWatch(testing.NewWatchAction(componentsResource, c.ns, opts)) + +} + +// Create takes the representation of a component and creates it. Returns the server's representation of the component, and an error, if there is any. +func (c *FakeComponents) Create(ctx context.Context, component *v1.Component, opts metav1.CreateOptions) (result *v1.Component, err error) { + obj, err := c.Fake. + Invokes(testing.NewCreateAction(componentsResource, c.ns, component), &v1.Component{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.Component), err +} + +// Update takes the representation of a component and updates it. Returns the server's representation of the component, and an error, if there is any. +func (c *FakeComponents) Update(ctx context.Context, component *v1.Component, opts metav1.UpdateOptions) (result *v1.Component, err error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateAction(componentsResource, c.ns, component), &v1.Component{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.Component), err +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *FakeComponents) UpdateStatus(ctx context.Context, component *v1.Component, opts metav1.UpdateOptions) (*v1.Component, error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateSubresourceAction(componentsResource, "status", c.ns, component), &v1.Component{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.Component), err +} + +// Delete takes name of the component and deletes it. Returns an error if one occurs. +func (c *FakeComponents) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { + _, err := c.Fake. + Invokes(testing.NewDeleteActionWithOptions(componentsResource, c.ns, name, opts), &v1.Component{}) + + return err +} + +// DeleteCollection deletes a collection of objects. +func (c *FakeComponents) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { + action := testing.NewDeleteCollectionAction(componentsResource, c.ns, listOpts) + + _, err := c.Fake.Invokes(action, &v1.ComponentList{}) + return err +} + +// Patch applies the patch and returns the patched component. +func (c *FakeComponents) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.Component, err error) { + obj, err := c.Fake. + Invokes(testing.NewPatchSubresourceAction(componentsResource, c.ns, name, pt, data, subresources...), &v1.Component{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.Component), err +} diff --git a/pkg/client/clientset/versioned/typed/apps/v1/fake/fake_componentdefinition.go b/pkg/client/clientset/versioned/typed/apps/v1/fake/fake_componentdefinition.go new file mode 100644 index 00000000000..c8780b8ef7e --- /dev/null +++ b/pkg/client/clientset/versioned/typed/apps/v1/fake/fake_componentdefinition.go @@ -0,0 +1,132 @@ +/* +Copyright (C) 2022-2024 ApeCloud Co., Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + "context" + + v1 "github.com/apecloud/kubeblocks/apis/apps/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + labels "k8s.io/apimachinery/pkg/labels" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + testing "k8s.io/client-go/testing" +) + +// FakeComponentDefinitions implements ComponentDefinitionInterface +type FakeComponentDefinitions struct { + Fake *FakeAppsV1 +} + +var componentdefinitionsResource = v1.SchemeGroupVersion.WithResource("componentdefinitions") + +var componentdefinitionsKind = v1.SchemeGroupVersion.WithKind("ComponentDefinition") + +// Get takes name of the componentDefinition, and returns the corresponding componentDefinition object, and an error if there is any. +func (c *FakeComponentDefinitions) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.ComponentDefinition, err error) { + obj, err := c.Fake. + Invokes(testing.NewRootGetAction(componentdefinitionsResource, name), &v1.ComponentDefinition{}) + if obj == nil { + return nil, err + } + return obj.(*v1.ComponentDefinition), err +} + +// List takes label and field selectors, and returns the list of ComponentDefinitions that match those selectors. +func (c *FakeComponentDefinitions) List(ctx context.Context, opts metav1.ListOptions) (result *v1.ComponentDefinitionList, err error) { + obj, err := c.Fake. + Invokes(testing.NewRootListAction(componentdefinitionsResource, componentdefinitionsKind, opts), &v1.ComponentDefinitionList{}) + if obj == nil { + return nil, err + } + + label, _, _ := testing.ExtractFromListOptions(opts) + if label == nil { + label = labels.Everything() + } + list := &v1.ComponentDefinitionList{ListMeta: obj.(*v1.ComponentDefinitionList).ListMeta} + for _, item := range obj.(*v1.ComponentDefinitionList).Items { + if label.Matches(labels.Set(item.Labels)) { + list.Items = append(list.Items, item) + } + } + return list, err +} + +// Watch returns a watch.Interface that watches the requested componentDefinitions. +func (c *FakeComponentDefinitions) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { + return c.Fake. + InvokesWatch(testing.NewRootWatchAction(componentdefinitionsResource, opts)) +} + +// Create takes the representation of a componentDefinition and creates it. Returns the server's representation of the componentDefinition, and an error, if there is any. +func (c *FakeComponentDefinitions) Create(ctx context.Context, componentDefinition *v1.ComponentDefinition, opts metav1.CreateOptions) (result *v1.ComponentDefinition, err error) { + obj, err := c.Fake. + Invokes(testing.NewRootCreateAction(componentdefinitionsResource, componentDefinition), &v1.ComponentDefinition{}) + if obj == nil { + return nil, err + } + return obj.(*v1.ComponentDefinition), err +} + +// Update takes the representation of a componentDefinition and updates it. Returns the server's representation of the componentDefinition, and an error, if there is any. +func (c *FakeComponentDefinitions) Update(ctx context.Context, componentDefinition *v1.ComponentDefinition, opts metav1.UpdateOptions) (result *v1.ComponentDefinition, err error) { + obj, err := c.Fake. + Invokes(testing.NewRootUpdateAction(componentdefinitionsResource, componentDefinition), &v1.ComponentDefinition{}) + if obj == nil { + return nil, err + } + return obj.(*v1.ComponentDefinition), err +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *FakeComponentDefinitions) UpdateStatus(ctx context.Context, componentDefinition *v1.ComponentDefinition, opts metav1.UpdateOptions) (*v1.ComponentDefinition, error) { + obj, err := c.Fake. + Invokes(testing.NewRootUpdateSubresourceAction(componentdefinitionsResource, "status", componentDefinition), &v1.ComponentDefinition{}) + if obj == nil { + return nil, err + } + return obj.(*v1.ComponentDefinition), err +} + +// Delete takes name of the componentDefinition and deletes it. Returns an error if one occurs. +func (c *FakeComponentDefinitions) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { + _, err := c.Fake. + Invokes(testing.NewRootDeleteActionWithOptions(componentdefinitionsResource, name, opts), &v1.ComponentDefinition{}) + return err +} + +// DeleteCollection deletes a collection of objects. +func (c *FakeComponentDefinitions) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { + action := testing.NewRootDeleteCollectionAction(componentdefinitionsResource, listOpts) + + _, err := c.Fake.Invokes(action, &v1.ComponentDefinitionList{}) + return err +} + +// Patch applies the patch and returns the patched componentDefinition. +func (c *FakeComponentDefinitions) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.ComponentDefinition, err error) { + obj, err := c.Fake. + Invokes(testing.NewRootPatchSubresourceAction(componentdefinitionsResource, name, pt, data, subresources...), &v1.ComponentDefinition{}) + if obj == nil { + return nil, err + } + return obj.(*v1.ComponentDefinition), err +} diff --git a/pkg/client/clientset/versioned/typed/apps/v1/fake/fake_componentversion.go b/pkg/client/clientset/versioned/typed/apps/v1/fake/fake_componentversion.go new file mode 100644 index 00000000000..5b25194aaa3 --- /dev/null +++ b/pkg/client/clientset/versioned/typed/apps/v1/fake/fake_componentversion.go @@ -0,0 +1,132 @@ +/* +Copyright (C) 2022-2024 ApeCloud Co., Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + "context" + + v1 "github.com/apecloud/kubeblocks/apis/apps/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + labels "k8s.io/apimachinery/pkg/labels" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + testing "k8s.io/client-go/testing" +) + +// FakeComponentVersions implements ComponentVersionInterface +type FakeComponentVersions struct { + Fake *FakeAppsV1 +} + +var componentversionsResource = v1.SchemeGroupVersion.WithResource("componentversions") + +var componentversionsKind = v1.SchemeGroupVersion.WithKind("ComponentVersion") + +// Get takes name of the componentVersion, and returns the corresponding componentVersion object, and an error if there is any. +func (c *FakeComponentVersions) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.ComponentVersion, err error) { + obj, err := c.Fake. + Invokes(testing.NewRootGetAction(componentversionsResource, name), &v1.ComponentVersion{}) + if obj == nil { + return nil, err + } + return obj.(*v1.ComponentVersion), err +} + +// List takes label and field selectors, and returns the list of ComponentVersions that match those selectors. +func (c *FakeComponentVersions) List(ctx context.Context, opts metav1.ListOptions) (result *v1.ComponentVersionList, err error) { + obj, err := c.Fake. + Invokes(testing.NewRootListAction(componentversionsResource, componentversionsKind, opts), &v1.ComponentVersionList{}) + if obj == nil { + return nil, err + } + + label, _, _ := testing.ExtractFromListOptions(opts) + if label == nil { + label = labels.Everything() + } + list := &v1.ComponentVersionList{ListMeta: obj.(*v1.ComponentVersionList).ListMeta} + for _, item := range obj.(*v1.ComponentVersionList).Items { + if label.Matches(labels.Set(item.Labels)) { + list.Items = append(list.Items, item) + } + } + return list, err +} + +// Watch returns a watch.Interface that watches the requested componentVersions. +func (c *FakeComponentVersions) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { + return c.Fake. + InvokesWatch(testing.NewRootWatchAction(componentversionsResource, opts)) +} + +// Create takes the representation of a componentVersion and creates it. Returns the server's representation of the componentVersion, and an error, if there is any. +func (c *FakeComponentVersions) Create(ctx context.Context, componentVersion *v1.ComponentVersion, opts metav1.CreateOptions) (result *v1.ComponentVersion, err error) { + obj, err := c.Fake. + Invokes(testing.NewRootCreateAction(componentversionsResource, componentVersion), &v1.ComponentVersion{}) + if obj == nil { + return nil, err + } + return obj.(*v1.ComponentVersion), err +} + +// Update takes the representation of a componentVersion and updates it. Returns the server's representation of the componentVersion, and an error, if there is any. +func (c *FakeComponentVersions) Update(ctx context.Context, componentVersion *v1.ComponentVersion, opts metav1.UpdateOptions) (result *v1.ComponentVersion, err error) { + obj, err := c.Fake. + Invokes(testing.NewRootUpdateAction(componentversionsResource, componentVersion), &v1.ComponentVersion{}) + if obj == nil { + return nil, err + } + return obj.(*v1.ComponentVersion), err +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *FakeComponentVersions) UpdateStatus(ctx context.Context, componentVersion *v1.ComponentVersion, opts metav1.UpdateOptions) (*v1.ComponentVersion, error) { + obj, err := c.Fake. + Invokes(testing.NewRootUpdateSubresourceAction(componentversionsResource, "status", componentVersion), &v1.ComponentVersion{}) + if obj == nil { + return nil, err + } + return obj.(*v1.ComponentVersion), err +} + +// Delete takes name of the componentVersion and deletes it. Returns an error if one occurs. +func (c *FakeComponentVersions) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { + _, err := c.Fake. + Invokes(testing.NewRootDeleteActionWithOptions(componentversionsResource, name, opts), &v1.ComponentVersion{}) + return err +} + +// DeleteCollection deletes a collection of objects. +func (c *FakeComponentVersions) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { + action := testing.NewRootDeleteCollectionAction(componentversionsResource, listOpts) + + _, err := c.Fake.Invokes(action, &v1.ComponentVersionList{}) + return err +} + +// Patch applies the patch and returns the patched componentVersion. +func (c *FakeComponentVersions) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.ComponentVersion, err error) { + obj, err := c.Fake. + Invokes(testing.NewRootPatchSubresourceAction(componentversionsResource, name, pt, data, subresources...), &v1.ComponentVersion{}) + if obj == nil { + return nil, err + } + return obj.(*v1.ComponentVersion), err +} diff --git a/pkg/client/clientset/versioned/typed/apps/v1/generated_expansion.go b/pkg/client/clientset/versioned/typed/apps/v1/generated_expansion.go index dc737a1279c..8683f2bcd0a 100644 --- a/pkg/client/clientset/versioned/typed/apps/v1/generated_expansion.go +++ b/pkg/client/clientset/versioned/typed/apps/v1/generated_expansion.go @@ -18,6 +18,14 @@ limitations under the License. package v1 +type ClusterExpansion interface{} + type ClusterDefinitionExpansion interface{} +type ComponentExpansion interface{} + +type ComponentDefinitionExpansion interface{} + +type ComponentVersionExpansion interface{} + type ServiceDescriptorExpansion interface{} diff --git a/pkg/client/informers/externalversions/apps/v1/cluster.go b/pkg/client/informers/externalversions/apps/v1/cluster.go new file mode 100644 index 00000000000..f1dcfd52931 --- /dev/null +++ b/pkg/client/informers/externalversions/apps/v1/cluster.go @@ -0,0 +1,90 @@ +/* +Copyright (C) 2022-2024 ApeCloud Co., Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1 + +import ( + "context" + time "time" + + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" + versioned "github.com/apecloud/kubeblocks/pkg/client/clientset/versioned" + internalinterfaces "github.com/apecloud/kubeblocks/pkg/client/informers/externalversions/internalinterfaces" + v1 "github.com/apecloud/kubeblocks/pkg/client/listers/apps/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + cache "k8s.io/client-go/tools/cache" +) + +// ClusterInformer provides access to a shared informer and lister for +// Clusters. +type ClusterInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1.ClusterLister +} + +type clusterInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewClusterInformer constructs a new informer for Cluster type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewClusterInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredClusterInformer(client, namespace, resyncPeriod, indexers, nil) +} + +// NewFilteredClusterInformer constructs a new informer for Cluster type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredClusterInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.AppsV1().Clusters(namespace).List(context.TODO(), options) + }, + WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.AppsV1().Clusters(namespace).Watch(context.TODO(), options) + }, + }, + &appsv1.Cluster{}, + resyncPeriod, + indexers, + ) +} + +func (f *clusterInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredClusterInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *clusterInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&appsv1.Cluster{}, f.defaultInformer) +} + +func (f *clusterInformer) Lister() v1.ClusterLister { + return v1.NewClusterLister(f.Informer().GetIndexer()) +} diff --git a/pkg/client/informers/externalversions/apps/v1/component.go b/pkg/client/informers/externalversions/apps/v1/component.go new file mode 100644 index 00000000000..d15ec715479 --- /dev/null +++ b/pkg/client/informers/externalversions/apps/v1/component.go @@ -0,0 +1,90 @@ +/* +Copyright (C) 2022-2024 ApeCloud Co., Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1 + +import ( + "context" + time "time" + + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" + versioned "github.com/apecloud/kubeblocks/pkg/client/clientset/versioned" + internalinterfaces "github.com/apecloud/kubeblocks/pkg/client/informers/externalversions/internalinterfaces" + v1 "github.com/apecloud/kubeblocks/pkg/client/listers/apps/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + cache "k8s.io/client-go/tools/cache" +) + +// ComponentInformer provides access to a shared informer and lister for +// Components. +type ComponentInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1.ComponentLister +} + +type componentInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewComponentInformer constructs a new informer for Component type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewComponentInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredComponentInformer(client, namespace, resyncPeriod, indexers, nil) +} + +// NewFilteredComponentInformer constructs a new informer for Component type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredComponentInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.AppsV1().Components(namespace).List(context.TODO(), options) + }, + WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.AppsV1().Components(namespace).Watch(context.TODO(), options) + }, + }, + &appsv1.Component{}, + resyncPeriod, + indexers, + ) +} + +func (f *componentInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredComponentInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *componentInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&appsv1.Component{}, f.defaultInformer) +} + +func (f *componentInformer) Lister() v1.ComponentLister { + return v1.NewComponentLister(f.Informer().GetIndexer()) +} diff --git a/pkg/client/informers/externalversions/apps/v1/componentdefinition.go b/pkg/client/informers/externalversions/apps/v1/componentdefinition.go new file mode 100644 index 00000000000..33e565453d3 --- /dev/null +++ b/pkg/client/informers/externalversions/apps/v1/componentdefinition.go @@ -0,0 +1,89 @@ +/* +Copyright (C) 2022-2024 ApeCloud Co., Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1 + +import ( + "context" + time "time" + + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" + versioned "github.com/apecloud/kubeblocks/pkg/client/clientset/versioned" + internalinterfaces "github.com/apecloud/kubeblocks/pkg/client/informers/externalversions/internalinterfaces" + v1 "github.com/apecloud/kubeblocks/pkg/client/listers/apps/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + cache "k8s.io/client-go/tools/cache" +) + +// ComponentDefinitionInformer provides access to a shared informer and lister for +// ComponentDefinitions. +type ComponentDefinitionInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1.ComponentDefinitionLister +} + +type componentDefinitionInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// NewComponentDefinitionInformer constructs a new informer for ComponentDefinition type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewComponentDefinitionInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredComponentDefinitionInformer(client, resyncPeriod, indexers, nil) +} + +// NewFilteredComponentDefinitionInformer constructs a new informer for ComponentDefinition type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredComponentDefinitionInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.AppsV1().ComponentDefinitions().List(context.TODO(), options) + }, + WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.AppsV1().ComponentDefinitions().Watch(context.TODO(), options) + }, + }, + &appsv1.ComponentDefinition{}, + resyncPeriod, + indexers, + ) +} + +func (f *componentDefinitionInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredComponentDefinitionInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *componentDefinitionInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&appsv1.ComponentDefinition{}, f.defaultInformer) +} + +func (f *componentDefinitionInformer) Lister() v1.ComponentDefinitionLister { + return v1.NewComponentDefinitionLister(f.Informer().GetIndexer()) +} diff --git a/pkg/client/informers/externalversions/apps/v1/componentversion.go b/pkg/client/informers/externalversions/apps/v1/componentversion.go new file mode 100644 index 00000000000..401ce4ce252 --- /dev/null +++ b/pkg/client/informers/externalversions/apps/v1/componentversion.go @@ -0,0 +1,89 @@ +/* +Copyright (C) 2022-2024 ApeCloud Co., Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1 + +import ( + "context" + time "time" + + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" + versioned "github.com/apecloud/kubeblocks/pkg/client/clientset/versioned" + internalinterfaces "github.com/apecloud/kubeblocks/pkg/client/informers/externalversions/internalinterfaces" + v1 "github.com/apecloud/kubeblocks/pkg/client/listers/apps/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + cache "k8s.io/client-go/tools/cache" +) + +// ComponentVersionInformer provides access to a shared informer and lister for +// ComponentVersions. +type ComponentVersionInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1.ComponentVersionLister +} + +type componentVersionInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// NewComponentVersionInformer constructs a new informer for ComponentVersion type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewComponentVersionInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredComponentVersionInformer(client, resyncPeriod, indexers, nil) +} + +// NewFilteredComponentVersionInformer constructs a new informer for ComponentVersion type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredComponentVersionInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.AppsV1().ComponentVersions().List(context.TODO(), options) + }, + WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.AppsV1().ComponentVersions().Watch(context.TODO(), options) + }, + }, + &appsv1.ComponentVersion{}, + resyncPeriod, + indexers, + ) +} + +func (f *componentVersionInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredComponentVersionInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *componentVersionInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&appsv1.ComponentVersion{}, f.defaultInformer) +} + +func (f *componentVersionInformer) Lister() v1.ComponentVersionLister { + return v1.NewComponentVersionLister(f.Informer().GetIndexer()) +} diff --git a/pkg/client/informers/externalversions/apps/v1/interface.go b/pkg/client/informers/externalversions/apps/v1/interface.go index 0c45a6e9c0c..f30020f7b18 100644 --- a/pkg/client/informers/externalversions/apps/v1/interface.go +++ b/pkg/client/informers/externalversions/apps/v1/interface.go @@ -24,8 +24,16 @@ import ( // Interface provides access to all the informers in this group version. type Interface interface { + // Clusters returns a ClusterInformer. + Clusters() ClusterInformer // ClusterDefinitions returns a ClusterDefinitionInformer. ClusterDefinitions() ClusterDefinitionInformer + // Components returns a ComponentInformer. + Components() ComponentInformer + // ComponentDefinitions returns a ComponentDefinitionInformer. + ComponentDefinitions() ComponentDefinitionInformer + // ComponentVersions returns a ComponentVersionInformer. + ComponentVersions() ComponentVersionInformer // ServiceDescriptors returns a ServiceDescriptorInformer. ServiceDescriptors() ServiceDescriptorInformer } @@ -41,11 +49,31 @@ func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakList return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} } +// Clusters returns a ClusterInformer. +func (v *version) Clusters() ClusterInformer { + return &clusterInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +} + // ClusterDefinitions returns a ClusterDefinitionInformer. func (v *version) ClusterDefinitions() ClusterDefinitionInformer { return &clusterDefinitionInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} } +// Components returns a ComponentInformer. +func (v *version) Components() ComponentInformer { + return &componentInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +} + +// ComponentDefinitions returns a ComponentDefinitionInformer. +func (v *version) ComponentDefinitions() ComponentDefinitionInformer { + return &componentDefinitionInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} +} + +// ComponentVersions returns a ComponentVersionInformer. +func (v *version) ComponentVersions() ComponentVersionInformer { + return &componentVersionInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} +} + // ServiceDescriptors returns a ServiceDescriptorInformer. func (v *version) ServiceDescriptors() ServiceDescriptorInformer { return &serviceDescriptorInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} diff --git a/pkg/client/informers/externalversions/generic.go b/pkg/client/informers/externalversions/generic.go index c7677b5e66d..3a4ac3a9eab 100644 --- a/pkg/client/informers/externalversions/generic.go +++ b/pkg/client/informers/externalversions/generic.go @@ -58,8 +58,16 @@ func (f *genericInformer) Lister() cache.GenericLister { func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource) (GenericInformer, error) { switch resource { // Group=apps.kubeblocks.io, Version=v1 + case v1.SchemeGroupVersion.WithResource("clusters"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Apps().V1().Clusters().Informer()}, nil case v1.SchemeGroupVersion.WithResource("clusterdefinitions"): return &genericInformer{resource: resource.GroupResource(), informer: f.Apps().V1().ClusterDefinitions().Informer()}, nil + case v1.SchemeGroupVersion.WithResource("components"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Apps().V1().Components().Informer()}, nil + case v1.SchemeGroupVersion.WithResource("componentdefinitions"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Apps().V1().ComponentDefinitions().Informer()}, nil + case v1.SchemeGroupVersion.WithResource("componentversions"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Apps().V1().ComponentVersions().Informer()}, nil case v1.SchemeGroupVersion.WithResource("servicedescriptors"): return &genericInformer{resource: resource.GroupResource(), informer: f.Apps().V1().ServiceDescriptors().Informer()}, nil diff --git a/pkg/client/listers/apps/v1/cluster.go b/pkg/client/listers/apps/v1/cluster.go new file mode 100644 index 00000000000..277977459b6 --- /dev/null +++ b/pkg/client/listers/apps/v1/cluster.go @@ -0,0 +1,99 @@ +/* +Copyright (C) 2022-2024 ApeCloud Co., Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1 + +import ( + v1 "github.com/apecloud/kubeblocks/apis/apps/v1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// ClusterLister helps list Clusters. +// All objects returned here must be treated as read-only. +type ClusterLister interface { + // List lists all Clusters in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1.Cluster, err error) + // Clusters returns an object that can list and get Clusters. + Clusters(namespace string) ClusterNamespaceLister + ClusterListerExpansion +} + +// clusterLister implements the ClusterLister interface. +type clusterLister struct { + indexer cache.Indexer +} + +// NewClusterLister returns a new ClusterLister. +func NewClusterLister(indexer cache.Indexer) ClusterLister { + return &clusterLister{indexer: indexer} +} + +// List lists all Clusters in the indexer. +func (s *clusterLister) List(selector labels.Selector) (ret []*v1.Cluster, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1.Cluster)) + }) + return ret, err +} + +// Clusters returns an object that can list and get Clusters. +func (s *clusterLister) Clusters(namespace string) ClusterNamespaceLister { + return clusterNamespaceLister{indexer: s.indexer, namespace: namespace} +} + +// ClusterNamespaceLister helps list and get Clusters. +// All objects returned here must be treated as read-only. +type ClusterNamespaceLister interface { + // List lists all Clusters in the indexer for a given namespace. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1.Cluster, err error) + // Get retrieves the Cluster from the indexer for a given namespace and name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1.Cluster, error) + ClusterNamespaceListerExpansion +} + +// clusterNamespaceLister implements the ClusterNamespaceLister +// interface. +type clusterNamespaceLister struct { + indexer cache.Indexer + namespace string +} + +// List lists all Clusters in the indexer for a given namespace. +func (s clusterNamespaceLister) List(selector labels.Selector) (ret []*v1.Cluster, err error) { + err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { + ret = append(ret, m.(*v1.Cluster)) + }) + return ret, err +} + +// Get retrieves the Cluster from the indexer for a given namespace and name. +func (s clusterNamespaceLister) Get(name string) (*v1.Cluster, error) { + obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1.Resource("cluster"), name) + } + return obj.(*v1.Cluster), nil +} diff --git a/pkg/client/listers/apps/v1/component.go b/pkg/client/listers/apps/v1/component.go new file mode 100644 index 00000000000..310a50e2743 --- /dev/null +++ b/pkg/client/listers/apps/v1/component.go @@ -0,0 +1,99 @@ +/* +Copyright (C) 2022-2024 ApeCloud Co., Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1 + +import ( + v1 "github.com/apecloud/kubeblocks/apis/apps/v1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// ComponentLister helps list Components. +// All objects returned here must be treated as read-only. +type ComponentLister interface { + // List lists all Components in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1.Component, err error) + // Components returns an object that can list and get Components. + Components(namespace string) ComponentNamespaceLister + ComponentListerExpansion +} + +// componentLister implements the ComponentLister interface. +type componentLister struct { + indexer cache.Indexer +} + +// NewComponentLister returns a new ComponentLister. +func NewComponentLister(indexer cache.Indexer) ComponentLister { + return &componentLister{indexer: indexer} +} + +// List lists all Components in the indexer. +func (s *componentLister) List(selector labels.Selector) (ret []*v1.Component, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1.Component)) + }) + return ret, err +} + +// Components returns an object that can list and get Components. +func (s *componentLister) Components(namespace string) ComponentNamespaceLister { + return componentNamespaceLister{indexer: s.indexer, namespace: namespace} +} + +// ComponentNamespaceLister helps list and get Components. +// All objects returned here must be treated as read-only. +type ComponentNamespaceLister interface { + // List lists all Components in the indexer for a given namespace. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1.Component, err error) + // Get retrieves the Component from the indexer for a given namespace and name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1.Component, error) + ComponentNamespaceListerExpansion +} + +// componentNamespaceLister implements the ComponentNamespaceLister +// interface. +type componentNamespaceLister struct { + indexer cache.Indexer + namespace string +} + +// List lists all Components in the indexer for a given namespace. +func (s componentNamespaceLister) List(selector labels.Selector) (ret []*v1.Component, err error) { + err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { + ret = append(ret, m.(*v1.Component)) + }) + return ret, err +} + +// Get retrieves the Component from the indexer for a given namespace and name. +func (s componentNamespaceLister) Get(name string) (*v1.Component, error) { + obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1.Resource("component"), name) + } + return obj.(*v1.Component), nil +} diff --git a/pkg/client/listers/apps/v1/componentdefinition.go b/pkg/client/listers/apps/v1/componentdefinition.go new file mode 100644 index 00000000000..d8b0f7cd5a3 --- /dev/null +++ b/pkg/client/listers/apps/v1/componentdefinition.go @@ -0,0 +1,68 @@ +/* +Copyright (C) 2022-2024 ApeCloud Co., Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1 + +import ( + v1 "github.com/apecloud/kubeblocks/apis/apps/v1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// ComponentDefinitionLister helps list ComponentDefinitions. +// All objects returned here must be treated as read-only. +type ComponentDefinitionLister interface { + // List lists all ComponentDefinitions in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1.ComponentDefinition, err error) + // Get retrieves the ComponentDefinition from the index for a given name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1.ComponentDefinition, error) + ComponentDefinitionListerExpansion +} + +// componentDefinitionLister implements the ComponentDefinitionLister interface. +type componentDefinitionLister struct { + indexer cache.Indexer +} + +// NewComponentDefinitionLister returns a new ComponentDefinitionLister. +func NewComponentDefinitionLister(indexer cache.Indexer) ComponentDefinitionLister { + return &componentDefinitionLister{indexer: indexer} +} + +// List lists all ComponentDefinitions in the indexer. +func (s *componentDefinitionLister) List(selector labels.Selector) (ret []*v1.ComponentDefinition, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1.ComponentDefinition)) + }) + return ret, err +} + +// Get retrieves the ComponentDefinition from the index for a given name. +func (s *componentDefinitionLister) Get(name string) (*v1.ComponentDefinition, error) { + obj, exists, err := s.indexer.GetByKey(name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1.Resource("componentdefinition"), name) + } + return obj.(*v1.ComponentDefinition), nil +} diff --git a/pkg/client/listers/apps/v1/componentversion.go b/pkg/client/listers/apps/v1/componentversion.go new file mode 100644 index 00000000000..e96a2243009 --- /dev/null +++ b/pkg/client/listers/apps/v1/componentversion.go @@ -0,0 +1,68 @@ +/* +Copyright (C) 2022-2024 ApeCloud Co., Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1 + +import ( + v1 "github.com/apecloud/kubeblocks/apis/apps/v1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// ComponentVersionLister helps list ComponentVersions. +// All objects returned here must be treated as read-only. +type ComponentVersionLister interface { + // List lists all ComponentVersions in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1.ComponentVersion, err error) + // Get retrieves the ComponentVersion from the index for a given name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1.ComponentVersion, error) + ComponentVersionListerExpansion +} + +// componentVersionLister implements the ComponentVersionLister interface. +type componentVersionLister struct { + indexer cache.Indexer +} + +// NewComponentVersionLister returns a new ComponentVersionLister. +func NewComponentVersionLister(indexer cache.Indexer) ComponentVersionLister { + return &componentVersionLister{indexer: indexer} +} + +// List lists all ComponentVersions in the indexer. +func (s *componentVersionLister) List(selector labels.Selector) (ret []*v1.ComponentVersion, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1.ComponentVersion)) + }) + return ret, err +} + +// Get retrieves the ComponentVersion from the index for a given name. +func (s *componentVersionLister) Get(name string) (*v1.ComponentVersion, error) { + obj, exists, err := s.indexer.GetByKey(name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1.Resource("componentversion"), name) + } + return obj.(*v1.ComponentVersion), nil +} diff --git a/pkg/client/listers/apps/v1/expansion_generated.go b/pkg/client/listers/apps/v1/expansion_generated.go index 6e13e0b4f33..105d72c4e53 100644 --- a/pkg/client/listers/apps/v1/expansion_generated.go +++ b/pkg/client/listers/apps/v1/expansion_generated.go @@ -18,10 +18,34 @@ limitations under the License. package v1 +// ClusterListerExpansion allows custom methods to be added to +// ClusterLister. +type ClusterListerExpansion interface{} + +// ClusterNamespaceListerExpansion allows custom methods to be added to +// ClusterNamespaceLister. +type ClusterNamespaceListerExpansion interface{} + // ClusterDefinitionListerExpansion allows custom methods to be added to // ClusterDefinitionLister. type ClusterDefinitionListerExpansion interface{} +// ComponentListerExpansion allows custom methods to be added to +// ComponentLister. +type ComponentListerExpansion interface{} + +// ComponentNamespaceListerExpansion allows custom methods to be added to +// ComponentNamespaceLister. +type ComponentNamespaceListerExpansion interface{} + +// ComponentDefinitionListerExpansion allows custom methods to be added to +// ComponentDefinitionLister. +type ComponentDefinitionListerExpansion interface{} + +// ComponentVersionListerExpansion allows custom methods to be added to +// ComponentVersionLister. +type ComponentVersionListerExpansion interface{} + // ServiceDescriptorListerExpansion allows custom methods to be added to // ServiceDescriptorLister. type ServiceDescriptorListerExpansion interface{} From d19a28d1ed4b33f460abfe995d220f6e87c897d1 Mon Sep 17 00:00:00 2001 From: Leon Date: Mon, 2 Sep 2024 15:15:14 +0800 Subject: [PATCH 05/15] cmpv --- apis/apps/v1/cluster_webhook.go | 3 +- apis/apps/v1/clusterdefinition_webhook.go | 3 +- apis/apps/v1/component_webhook.go | 3 +- apis/apps/v1/componentdefinition_webhook.go | 3 +- apis/apps/v1/componentversion_types.go | 96 +++++++- apis/apps/v1/componentversion_webhook.go | 3 +- apis/apps/v1/servicedescriptor_webhook.go | 3 +- apis/apps/v1/zz_generated.deepcopy.go | 63 ++++- .../v1alpha1/componentversion_conversion.go | 92 ++++++++ .../bases/apps.kubeblocks.io_components.yaml | 1 + .../apps.kubeblocks.io_componentversions.yaml | 113 ++++++++- ...apps.kubeblocks.io_servicedescriptors.yaml | 1 - controllers/apps/cluster_controller_test.go | 12 +- controllers/apps/component_controller_test.go | 11 +- .../apps/componentversion_controller.go | 39 ++-- .../apps/componentversion_controller_test.go | 59 ++--- controllers/apps/operations/upgrade_test.go | 11 +- .../crds/apps.kubeblocks.io_components.yaml | 1 + .../apps.kubeblocks.io_componentversions.yaml | 113 ++++++++- ...apps.kubeblocks.io_servicedescriptors.yaml | 1 - docs/developer_docs/api-reference/cluster.md | 218 +++++++++++++++++- pkg/controller/component/component_version.go | 13 +- .../component/component_version_test.go | 16 +- pkg/generics/type.go | 8 +- pkg/testutil/apps/componentversion_factory.go | 18 +- pkg/testutil/apps/constant.go | 9 +- 26 files changed, 777 insertions(+), 136 deletions(-) diff --git a/apis/apps/v1/cluster_webhook.go b/apis/apps/v1/cluster_webhook.go index de66fce24b0..c616c2fd834 100644 --- a/apis/apps/v1/cluster_webhook.go +++ b/apis/apps/v1/cluster_webhook.go @@ -21,11 +21,10 @@ package v1 import ( ctrl "sigs.k8s.io/controller-runtime" - logf "sigs.k8s.io/controller-runtime/pkg/log" ) // log is for logging in this package. -var clusterlog = logf.Log.WithName("cluster-resource") +// var clusterlog = logf.Log.WithName("cluster-resource") func (r *Cluster) SetupWebhookWithManager(mgr ctrl.Manager) error { return ctrl.NewWebhookManagedBy(mgr). diff --git a/apis/apps/v1/clusterdefinition_webhook.go b/apis/apps/v1/clusterdefinition_webhook.go index 753261f0d49..95b125b8146 100644 --- a/apis/apps/v1/clusterdefinition_webhook.go +++ b/apis/apps/v1/clusterdefinition_webhook.go @@ -21,11 +21,10 @@ package v1 import ( ctrl "sigs.k8s.io/controller-runtime" - logf "sigs.k8s.io/controller-runtime/pkg/log" ) // log is for logging in this package. -var clusterdefinitionlog = logf.Log.WithName("clusterdefinition-resource") +// var clusterdefinitionlog = logf.Log.WithName("clusterdefinition-resource") func (r *ClusterDefinition) SetupWebhookWithManager(mgr ctrl.Manager) error { return ctrl.NewWebhookManagedBy(mgr). diff --git a/apis/apps/v1/component_webhook.go b/apis/apps/v1/component_webhook.go index c20a2e5b871..31747fa334c 100644 --- a/apis/apps/v1/component_webhook.go +++ b/apis/apps/v1/component_webhook.go @@ -21,11 +21,10 @@ package v1 import ( ctrl "sigs.k8s.io/controller-runtime" - logf "sigs.k8s.io/controller-runtime/pkg/log" ) // log is for logging in this package. -var componentlog = logf.Log.WithName("component-resource") +// var componentlog = logf.Log.WithName("component-resource") func (r *Component) SetupWebhookWithManager(mgr ctrl.Manager) error { return ctrl.NewWebhookManagedBy(mgr). diff --git a/apis/apps/v1/componentdefinition_webhook.go b/apis/apps/v1/componentdefinition_webhook.go index 8df50c3b4c3..d4ce67e94c0 100644 --- a/apis/apps/v1/componentdefinition_webhook.go +++ b/apis/apps/v1/componentdefinition_webhook.go @@ -21,11 +21,10 @@ package v1 import ( ctrl "sigs.k8s.io/controller-runtime" - logf "sigs.k8s.io/controller-runtime/pkg/log" ) // log is for logging in this package. -var componentdefinitionlog = logf.Log.WithName("componentdefinition-resource") +// var componentdefinitionlog = logf.Log.WithName("componentdefinition-resource") func (r *ComponentDefinition) SetupWebhookWithManager(mgr ctrl.Manager) error { return ctrl.NewWebhookManagedBy(mgr). diff --git a/apis/apps/v1/componentversion_types.go b/apis/apps/v1/componentversion_types.go index 5d6cb7f21fb..724404763dd 100644 --- a/apis/apps/v1/componentversion_types.go +++ b/apis/apps/v1/componentversion_types.go @@ -56,20 +56,96 @@ func init() { SchemeBuilder.Register(&ComponentVersion{}, &ComponentVersionList{}) } -// 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. - // ComponentVersionSpec defines the desired state of ComponentVersion type ComponentVersionSpec struct { - // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster - // Important: Run "make" to regenerate code after modifying this file - - // Foo is an example field of ComponentVersion. Edit componentversion_types.go to remove/update - Foo string `json:"foo,omitempty"` + // CompatibilityRules defines compatibility rules between sets of component definitions and releases. + // + // +kubebuilder:validation:Required + // +kubebuilder:validation:MinItems=1 + // +kubebuilder:validation:MaxItems=128 + CompatibilityRules []ComponentVersionCompatibilityRule `json:"compatibilityRules"` + + // Releases represents different releases of component instances within this ComponentVersion. + // + // +kubebuilder:validation:Required + // +kubebuilder:validation:MinItems=1 + // +kubebuilder:validation:MaxItems=128 + Releases []ComponentVersionRelease `json:"releases"` } // ComponentVersionStatus defines the observed state of ComponentVersion type ComponentVersionStatus 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 ComponentVersion. + // +optional + ObservedGeneration int64 `json:"observedGeneration,omitempty"` + + // Phase valid values are ``, `Available`, 'Unavailable`. + // Available is ComponentVersion become available, and can be used for co-related objects. + // +optional + Phase Phase `json:"phase,omitempty"` + + // Extra message for current phase. + // +optional + Message string `json:"message,omitempty"` + + // ServiceVersions represent the supported service versions of this ComponentVersion. + // +optional + ServiceVersions string `json:"serviceVersions,omitempty"` +} + +// ComponentVersionCompatibilityRule defines the compatibility between a set of component definitions and a set of releases. +type ComponentVersionCompatibilityRule struct { + // CompDefs specifies names for the component definitions associated with this ComponentVersion. + // Each name in the list can represent an exact name, or a name prefix. + // + // For example: + // + // - "mysql-8.0.30-v1alpha1": Matches the exact name "mysql-8.0.30-v1alpha1" + // - "mysql-8.0.30": Matches all names starting with "mysql-8.0.30" + // + // +kubebuilder:validation:Required + // +kubebuilder:validation:MinItems=1 + // +kubebuilder:validation:MaxItems=128 + CompDefs []string `json:"compDefs"` + + // Releases is a list of identifiers for the releases. + // + // +kubebuilder:validation:Required + // +kubebuilder:validation:MinItems=1 + // +kubebuilder:validation:MaxItems=128 + Releases []string `json:"releases"` +} + +// ComponentVersionRelease represents a release of component instances within a ComponentVersion. +type ComponentVersionRelease struct { + // Name is a unique identifier for this release. + // Cannot be updated. + // + // +kubebuilder:validation:Required + // +kubebuilder:validation:MaxLength=32 + Name string `json:"name"` + + // Changes provides information about the changes made in this release. + // + // +kubebuilder:validation:MaxLength=256 + // +optional + Changes string `json:"changes,omitempty"` + + // ServiceVersion defines the version of the well-known service that the component provides. + // The version should follow the syntax and semantics of the "Semantic Versioning" specification (http://semver.org/). + // If the release is used, it will serve as the service version for component instances, overriding the one defined in the component definition. + // Cannot be updated. + // + // +kubebuilder:validation:Required + // +kubebuilder:validation:MaxLength=32 + ServiceVersion string `json:"serviceVersion"` + + // Images define the new images for different containers within the release. + // + // +kubebuilder:validation:Required + // +kubebuilder:validation:MinProperties=1 + // +kubebuilder:validation:MaxProperties=128 + // +kubebuilder:validation:XValidation:rule="self.all(key, size(key) <= 32)",message="Container name may not exceed maximum length of 32 characters" + // +kubebuilder:validation:XValidation:rule="self.all(key, size(self[key]) <= 256)",message="Image name may not exceed maximum length of 256 characters" + Images map[string]string `json:"images"` } diff --git a/apis/apps/v1/componentversion_webhook.go b/apis/apps/v1/componentversion_webhook.go index 28f36e7afee..a39bb068011 100644 --- a/apis/apps/v1/componentversion_webhook.go +++ b/apis/apps/v1/componentversion_webhook.go @@ -21,11 +21,10 @@ package v1 import ( ctrl "sigs.k8s.io/controller-runtime" - logf "sigs.k8s.io/controller-runtime/pkg/log" ) // log is for logging in this package. -var componentversionlog = logf.Log.WithName("componentversion-resource") +// var componentversionlog = logf.Log.WithName("componentversion-resource") func (r *ComponentVersion) SetupWebhookWithManager(mgr ctrl.Manager) error { return ctrl.NewWebhookManagedBy(mgr). diff --git a/apis/apps/v1/servicedescriptor_webhook.go b/apis/apps/v1/servicedescriptor_webhook.go index e2abc9cc592..36d0ab1bde7 100644 --- a/apis/apps/v1/servicedescriptor_webhook.go +++ b/apis/apps/v1/servicedescriptor_webhook.go @@ -21,11 +21,10 @@ package v1 import ( ctrl "sigs.k8s.io/controller-runtime" - logf "sigs.k8s.io/controller-runtime/pkg/log" ) // log is for logging in this package. -var servicedescriptorlog = logf.Log.WithName("servicedescriptor-resource") +// var servicedescriptorlog = logf.Log.WithName("servicedescriptor-resource") func (r *ServiceDescriptor) SetupWebhookWithManager(mgr ctrl.Manager) error { return ctrl.NewWebhookManagedBy(mgr). diff --git a/apis/apps/v1/zz_generated.deepcopy.go b/apis/apps/v1/zz_generated.deepcopy.go index 40dd9325a80..ede99714e5b 100644 --- a/apis/apps/v1/zz_generated.deepcopy.go +++ b/apis/apps/v1/zz_generated.deepcopy.go @@ -466,7 +466,7 @@ func (in *ComponentVersion) DeepCopyInto(out *ComponentVersion) { *out = *in out.TypeMeta = in.TypeMeta in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - out.Spec = in.Spec + in.Spec.DeepCopyInto(&out.Spec) out.Status = in.Status } @@ -488,6 +488,31 @@ func (in *ComponentVersion) DeepCopyObject() runtime.Object { return nil } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ComponentVersionCompatibilityRule) DeepCopyInto(out *ComponentVersionCompatibilityRule) { + *out = *in + if in.CompDefs != nil { + in, out := &in.CompDefs, &out.CompDefs + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.Releases != nil { + in, out := &in.Releases, &out.Releases + *out = make([]string, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ComponentVersionCompatibilityRule. +func (in *ComponentVersionCompatibilityRule) DeepCopy() *ComponentVersionCompatibilityRule { + if in == nil { + return nil + } + out := new(ComponentVersionCompatibilityRule) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ComponentVersionList) DeepCopyInto(out *ComponentVersionList) { *out = *in @@ -520,9 +545,45 @@ func (in *ComponentVersionList) DeepCopyObject() runtime.Object { return nil } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ComponentVersionRelease) DeepCopyInto(out *ComponentVersionRelease) { + *out = *in + if in.Images != nil { + in, out := &in.Images, &out.Images + *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 ComponentVersionRelease. +func (in *ComponentVersionRelease) DeepCopy() *ComponentVersionRelease { + if in == nil { + return nil + } + out := new(ComponentVersionRelease) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ComponentVersionSpec) DeepCopyInto(out *ComponentVersionSpec) { *out = *in + if in.CompatibilityRules != nil { + in, out := &in.CompatibilityRules, &out.CompatibilityRules + *out = make([]ComponentVersionCompatibilityRule, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.Releases != nil { + in, out := &in.Releases, &out.Releases + *out = make([]ComponentVersionRelease, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ComponentVersionSpec. diff --git a/apis/apps/v1alpha1/componentversion_conversion.go b/apis/apps/v1alpha1/componentversion_conversion.go index f7f40366d9b..f5a493b1f65 100644 --- a/apis/apps/v1alpha1/componentversion_conversion.go +++ b/apis/apps/v1alpha1/componentversion_conversion.go @@ -21,14 +21,106 @@ package v1alpha1 import ( "sigs.k8s.io/controller-runtime/pkg/conversion" + + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" ) // ConvertTo converts this ComponentVersion to the Hub version (v1). func (r *ComponentVersion) ConvertTo(dstRaw conversion.Hub) error { + dst := dstRaw.(*appsv1.ComponentVersion) + + // objectMeta + dst.ObjectMeta = r.ObjectMeta + + // spec + dst.Spec.CompatibilityRules = r.compatibilityRulesTo(r.Spec.CompatibilityRules) + dst.Spec.Releases = r.releasesTo(r.Spec.Releases) + + // status + dst.Status.ObservedGeneration = r.Status.ObservedGeneration + dst.Status.Phase = appsv1.Phase(r.Status.Phase) + dst.Status.Message = r.Status.Message + dst.Status.ServiceVersions = r.Status.ServiceVersions + return nil } // ConvertFrom converts from the Hub version (v1) to this version. func (r *ComponentVersion) ConvertFrom(srcRaw conversion.Hub) error { + src := srcRaw.(*appsv1.ComponentVersion) + + // objectMeta + r.ObjectMeta = src.ObjectMeta + + // spec + r.Spec.CompatibilityRules = r.compatibilityRulesFrom(src.Spec.CompatibilityRules) + r.Spec.Releases = r.releasesFrom(src.Spec.Releases) + + // status + r.Status.ObservedGeneration = src.Status.ObservedGeneration + r.Status.Phase = Phase(src.Status.Phase) + r.Status.Message = src.Status.Message + r.Status.ServiceVersions = src.Status.ServiceVersions + + return nil +} + +func (r *ComponentVersion) compatibilityRulesTo(src []ComponentVersionCompatibilityRule) []appsv1.ComponentVersionCompatibilityRule { + if src != nil { + rules := make([]appsv1.ComponentVersionCompatibilityRule, 0) + for _, rule := range src { + rules = append(rules, appsv1.ComponentVersionCompatibilityRule{ + CompDefs: rule.CompDefs, + Releases: rule.Releases, + }) + } + return rules + } + return nil +} + +func (r *ComponentVersion) compatibilityRulesFrom(src []appsv1.ComponentVersionCompatibilityRule) []ComponentVersionCompatibilityRule { + if src != nil { + rules := make([]ComponentVersionCompatibilityRule, 0) + for _, rule := range src { + rules = append(rules, ComponentVersionCompatibilityRule{ + CompDefs: rule.CompDefs, + Releases: rule.Releases, + }) + } + return rules + } + return nil +} + +func (r *ComponentVersion) releasesTo(src []ComponentVersionRelease) []appsv1.ComponentVersionRelease { + if src != nil { + releases := make([]appsv1.ComponentVersionRelease, 0) + for _, release := range src { + releases = append(releases, appsv1.ComponentVersionRelease{ + Name: release.Name, + Changes: release.Changes, + ServiceVersion: release.ServiceVersion, + Images: release.Images, + }) + } + return releases + } + return nil +} + +func (r *ComponentVersion) releasesFrom(src []appsv1.ComponentVersionRelease) []ComponentVersionRelease { + if src != nil { + releases := make([]ComponentVersionRelease, 0) + for _, release := range src { + releases = append(releases, ComponentVersionRelease{ + Name: release.Name, + Changes: release.Changes, + ServiceVersion: release.ServiceVersion, + Images: release.Images, + }) + } + return releases + } return nil } diff --git a/config/crd/bases/apps.kubeblocks.io_components.yaml b/config/crd/bases/apps.kubeblocks.io_components.yaml index 6d18c4c7e6e..1aade3253e2 100644 --- a/config/crd/bases/apps.kubeblocks.io_components.yaml +++ b/config/crd/bases/apps.kubeblocks.io_components.yaml @@ -11,6 +11,7 @@ spec: names: categories: - kubeblocks + - all kind: Component listKind: ComponentList plural: components diff --git a/config/crd/bases/apps.kubeblocks.io_componentversions.yaml b/config/crd/bases/apps.kubeblocks.io_componentversions.yaml index bb9cd05805a..47d4f98fecb 100644 --- a/config/crd/bases/apps.kubeblocks.io_componentversions.yaml +++ b/config/crd/bases/apps.kubeblocks.io_componentversions.yaml @@ -56,13 +56,118 @@ spec: spec: description: ComponentVersionSpec defines the desired state of ComponentVersion properties: - foo: - description: Foo is an example field of ComponentVersion. Edit componentversion_types.go - to remove/update - type: string + compatibilityRules: + description: CompatibilityRules defines compatibility rules between + sets of component definitions and releases. + items: + description: ComponentVersionCompatibilityRule defines the compatibility + between a set of component definitions and a set of releases. + properties: + compDefs: + description: |- + CompDefs specifies names for the component definitions associated with this ComponentVersion. + Each name in the list can represent an exact name, or a name prefix. + + + For example: + + + - "mysql-8.0.30-v1alpha1": Matches the exact name "mysql-8.0.30-v1alpha1" + - "mysql-8.0.30": Matches all names starting with "mysql-8.0.30" + items: + type: string + maxItems: 128 + minItems: 1 + type: array + releases: + description: Releases is a list of identifiers for the releases. + items: + type: string + maxItems: 128 + minItems: 1 + type: array + required: + - compDefs + - releases + type: object + maxItems: 128 + minItems: 1 + type: array + releases: + description: Releases represents different releases of component instances + within this ComponentVersion. + items: + description: ComponentVersionRelease represents a release of component + instances within a ComponentVersion. + properties: + changes: + description: Changes provides information about the changes + made in this release. + maxLength: 256 + type: string + images: + additionalProperties: + type: string + description: Images define the new images for different containers + within the release. + maxProperties: 128 + minProperties: 1 + type: object + x-kubernetes-validations: + - message: Container name may not exceed maximum length of 32 + characters + rule: self.all(key, size(key) <= 32) + - message: Image name may not exceed maximum length of 256 characters + rule: self.all(key, size(self[key]) <= 256) + name: + description: |- + Name is a unique identifier for this release. + Cannot be updated. + maxLength: 32 + type: string + serviceVersion: + description: |- + ServiceVersion defines the version of the well-known service that the component provides. + The version should follow the syntax and semantics of the "Semantic Versioning" specification (http://semver.org/). + If the release is used, it will serve as the service version for component instances, overriding the one defined in the component definition. + Cannot be updated. + maxLength: 32 + type: string + required: + - images + - name + - serviceVersion + type: object + maxItems: 128 + minItems: 1 + type: array + required: + - compatibilityRules + - releases type: object status: description: ComponentVersionStatus defines the observed state of ComponentVersion + properties: + message: + description: Extra message for current phase. + type: string + observedGeneration: + description: ObservedGeneration is the most recent generation observed + for this ComponentVersion. + format: int64 + type: integer + phase: + description: |- + Phase valid values are ``, `Available`, 'Unavailable`. + Available is ComponentVersion become available, and can be used for co-related objects. + enum: + - Available + - Unavailable + type: string + serviceVersions: + description: ServiceVersions represent the supported service versions + of this ComponentVersion. + type: string type: object type: object served: true diff --git a/config/crd/bases/apps.kubeblocks.io_servicedescriptors.yaml b/config/crd/bases/apps.kubeblocks.io_servicedescriptors.yaml index 99d33d9eaff..3b84dcb3e59 100644 --- a/config/crd/bases/apps.kubeblocks.io_servicedescriptors.yaml +++ b/config/crd/bases/apps.kubeblocks.io_servicedescriptors.yaml @@ -11,7 +11,6 @@ spec: names: categories: - kubeblocks - - all kind: ServiceDescriptor listKind: ServiceDescriptorList plural: servicedescriptors diff --git a/controllers/apps/cluster_controller_test.go b/controllers/apps/cluster_controller_test.go index fe401fcc9f5..0b1df57a5cf 100644 --- a/controllers/apps/cluster_controller_test.go +++ b/controllers/apps/cluster_controller_test.go @@ -62,7 +62,7 @@ var _ = Describe("Cluster Controller", func() { var ( clusterDefObj *appsv1.ClusterDefinition compDefObj *appsv1alpha1.ComponentDefinition - compVersionObj *appsv1alpha1.ComponentVersion + compVersionObj *appsv1.ComponentVersion clusterObj *appsv1alpha1.Cluster clusterKey types.NamespacedName allSettings map[string]interface{} @@ -142,14 +142,14 @@ var _ = Describe("Cluster Controller", func() { By("Create a componentVersion obj") compVersionObj = testapps.NewComponentVersionFactory(compVersionName). - SetSpec(appsv1alpha1.ComponentVersionSpec{ - CompatibilityRules: []appsv1alpha1.ComponentVersionCompatibilityRule{ + SetSpec(appsv1.ComponentVersionSpec{ + CompatibilityRules: []appsv1.ComponentVersionCompatibilityRule{ { CompDefs: []string{compDefName}, // prefix Releases: []string{"v0.1.0", "v0.2.0"}, }, }, - Releases: []appsv1alpha1.ComponentVersionRelease{ + Releases: []appsv1.ComponentVersionRelease{ { Name: "v0.1.0", Changes: "init release", @@ -187,9 +187,9 @@ var _ = Describe("Cluster Controller", func() { g.Expect(compDef.Status.Phase).Should(Equal(appsv1alpha1.AvailablePhase)) })).Should(Succeed()) Eventually(testapps.CheckObj(&testCtx, client.ObjectKeyFromObject(compVersionObj), - func(g Gomega, compVersion *appsv1alpha1.ComponentVersion) { + func(g Gomega, compVersion *appsv1.ComponentVersion) { g.Expect(compVersion.Status.ObservedGeneration).Should(Equal(compVersion.Generation)) - g.Expect(compVersion.Status.Phase).Should(Equal(appsv1alpha1.AvailablePhase)) + g.Expect(compVersion.Status.Phase).Should(Equal(appsv1.AvailablePhase)) })).Should(Succeed()) Eventually(testapps.CheckObj(&testCtx, client.ObjectKeyFromObject(clusterDefObj), func(g Gomega, clusterDef *appsv1.ClusterDefinition) { diff --git a/controllers/apps/component_controller_test.go b/controllers/apps/component_controller_test.go index c974af10cfb..66256a35d90 100644 --- a/controllers/apps/component_controller_test.go +++ b/controllers/apps/component_controller_test.go @@ -48,6 +48,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" + kbappsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" dpv1alpha1 "github.com/apecloud/kubeblocks/apis/dataprotection/v1alpha1" workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" @@ -136,7 +137,7 @@ var _ = Describe("Component Controller", func() { var ( compDefObj *appsv1alpha1.ComponentDefinition - compVerObj *appsv1alpha1.ComponentVersion + compVerObj *kbappsv1.ComponentVersion clusterObj *appsv1alpha1.Cluster clusterKey types.NamespacedName compObj *appsv1alpha1.Component @@ -2297,7 +2298,7 @@ var _ = Describe("Component Controller", func() { createAllDefinitionObjects() }) - testImageUnchangedAfterNewReleasePublished := func(release appsv1alpha1.ComponentVersionRelease) { + testImageUnchangedAfterNewReleasePublished := func(release kbappsv1.ComponentVersionRelease) { prevRelease := compVerObj.Spec.Releases[0] By("check new release") @@ -2324,7 +2325,7 @@ var _ = Describe("Component Controller", func() { By("publish a new release") compVerKey := client.ObjectKeyFromObject(compVerObj) - Expect(testapps.GetAndChangeObj(&testCtx, compVerKey, func(compVer *appsv1alpha1.ComponentVersion) { + Expect(testapps.GetAndChangeObj(&testCtx, compVerKey, func(compVer *kbappsv1.ComponentVersion) { compVer.Spec.Releases = append(compVer.Spec.Releases, release) compVer.Spec.CompatibilityRules[0].Releases = append(compVer.Spec.CompatibilityRules[0].Releases, release.Name) })()).Should(Succeed()) @@ -2350,7 +2351,7 @@ var _ = Describe("Component Controller", func() { } It("publish new release with different service version", func() { - release := appsv1alpha1.ComponentVersionRelease{ + release := kbappsv1.ComponentVersionRelease{ Name: "8.0.30-r2", ServiceVersion: "8.0.31", // different service version Images: map[string]string{ @@ -2361,7 +2362,7 @@ var _ = Describe("Component Controller", func() { }) It("publish new release with same service version", func() { - release := appsv1alpha1.ComponentVersionRelease{ + release := kbappsv1.ComponentVersionRelease{ Name: "8.0.30-r2", ServiceVersion: "8.0.30", // same service version Images: map[string]string{ diff --git a/controllers/apps/componentversion_controller.go b/controllers/apps/componentversion_controller.go index b78320dc8d1..2621e1637e6 100644 --- a/controllers/apps/componentversion_controller.go +++ b/controllers/apps/componentversion_controller.go @@ -39,6 +39,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/log" "sigs.k8s.io/controller-runtime/pkg/reconcile" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" "github.com/apecloud/kubeblocks/pkg/constant" "github.com/apecloud/kubeblocks/pkg/controller/component" @@ -80,7 +81,7 @@ func (r *ComponentVersionReconciler) Reconcile(ctx context.Context, req ctrl.Req rctx.Log.V(1).Info("reconcile", "componentVersion", req.NamespacedName) - compVersion := &appsv1alpha1.ComponentVersion{} + compVersion := &appsv1.ComponentVersion{} if err := r.Client.Get(rctx.Ctx, rctx.Req.NamespacedName, compVersion); err != nil { return intctrlutil.CheckedRequeueWithError(err, rctx.Log, "") } @@ -91,7 +92,7 @@ func (r *ComponentVersionReconciler) Reconcile(ctx context.Context, req ctrl.Req // SetupWithManager sets up the controller with the Manager. func (r *ComponentVersionReconciler) SetupWithManager(mgr ctrl.Manager) error { return ctrl.NewControllerManagedBy(mgr). - For(&appsv1alpha1.ComponentVersion{}). + For(&appsv1.ComponentVersion{}). Watches(&appsv1alpha1.ComponentDefinition{}, handler.EnqueueRequestsFromMapFunc(r.compatibleCompVersion)). Complete(r) } @@ -101,7 +102,7 @@ func (r *ComponentVersionReconciler) compatibleCompVersion(ctx context.Context, if !ok { return nil } - versions := &appsv1alpha1.ComponentVersionList{} + versions := &appsv1.ComponentVersionList{} if err := r.Client.List(ctx, versions); err != nil { return nil } @@ -118,7 +119,7 @@ func (r *ComponentVersionReconciler) compatibleCompVersion(ctx context.Context, return requests } -func (r *ComponentVersionReconciler) isCompatibleWith(compDef appsv1alpha1.ComponentDefinition, compVer appsv1alpha1.ComponentVersion) bool { +func (r *ComponentVersionReconciler) isCompatibleWith(compDef appsv1alpha1.ComponentDefinition, compVer appsv1.ComponentVersion) bool { for _, rule := range compVer.Spec.CompatibilityRules { for _, name := range rule.CompDefs { if strings.HasPrefix(compDef.Name, name) { @@ -130,7 +131,7 @@ func (r *ComponentVersionReconciler) isCompatibleWith(compDef appsv1alpha1.Compo } func (r *ComponentVersionReconciler) reconcile(rctx intctrlutil.RequestCtx, - compVersion *appsv1alpha1.ComponentVersion) (ctrl.Result, error) { + compVersion *appsv1.ComponentVersion) (ctrl.Result, error) { res, err := intctrlutil.HandleCRDeletion(rctx, r, compVersion, componentVersionFinalizerName, r.deletionHandler(rctx, compVersion)) if res != nil { return *res, err @@ -170,7 +171,7 @@ func (r *ComponentVersionReconciler) reconcile(rctx intctrlutil.RequestCtx, } func (r *ComponentVersionReconciler) buildReleaseToCompDefinitionMapping(cli client.Client, rctx intctrlutil.RequestCtx, - compVersion *appsv1alpha1.ComponentVersion) (map[string]map[string]*appsv1alpha1.ComponentDefinition, error) { + compVersion *appsv1.ComponentVersion) (map[string]map[string]*appsv1alpha1.ComponentDefinition, error) { compDefs := make(map[string][]*appsv1alpha1.ComponentDefinition) for _, rule := range compVersion.Spec.CompatibilityRules { for _, compDef := range rule.CompDefs { @@ -204,7 +205,7 @@ func (r *ComponentVersionReconciler) buildReleaseToCompDefinitionMapping(cli cli } func (r *ComponentVersionReconciler) deletionHandler(rctx intctrlutil.RequestCtx, - compVersion *appsv1alpha1.ComponentVersion) func() (*ctrl.Result, error) { + compVersion *appsv1.ComponentVersion) func() (*ctrl.Result, error) { return func() (*ctrl.Result, error) { recordEvent := func() { r.Recorder.Event(compVersion, corev1.EventTypeWarning, constant.ReasonRefCRUnavailable, @@ -219,17 +220,17 @@ func (r *ComponentVersionReconciler) deletionHandler(rctx intctrlutil.RequestCtx } func (r *ComponentVersionReconciler) available(cli client.Client, rctx intctrlutil.RequestCtx, - compVersion *appsv1alpha1.ComponentVersion) error { - return r.status(cli, rctx, compVersion, appsv1alpha1.AvailablePhase, "") + compVersion *appsv1.ComponentVersion) error { + return r.status(cli, rctx, compVersion, appsv1.AvailablePhase, "") } func (r *ComponentVersionReconciler) unavailable(cli client.Client, rctx intctrlutil.RequestCtx, - compVersion *appsv1alpha1.ComponentVersion, err error) error { - return r.status(cli, rctx, compVersion, appsv1alpha1.UnavailablePhase, err.Error()) + compVersion *appsv1.ComponentVersion, err error) error { + return r.status(cli, rctx, compVersion, appsv1.UnavailablePhase, err.Error()) } func (r *ComponentVersionReconciler) status(cli client.Client, rctx intctrlutil.RequestCtx, - compVersion *appsv1alpha1.ComponentVersion, phase appsv1alpha1.Phase, message string) error { + compVersion *appsv1.ComponentVersion, phase appsv1.Phase, message string) error { patch := client.MergeFrom(compVersion.DeepCopy()) compVersion.Status.ObservedGeneration = compVersion.Generation compVersion.Status.Phase = phase @@ -238,7 +239,7 @@ func (r *ComponentVersionReconciler) status(cli client.Client, rctx intctrlutil. return cli.Status().Patch(rctx.Ctx, compVersion, patch) } -func (r *ComponentVersionReconciler) supportedServiceVersions(compVersion *appsv1alpha1.ComponentVersion) string { +func (r *ComponentVersionReconciler) supportedServiceVersions(compVersion *appsv1.ComponentVersion) string { versions := map[string]bool{} for _, release := range compVersion.Spec.Releases { if len(release.ServiceVersion) > 0 { @@ -251,7 +252,7 @@ func (r *ComponentVersionReconciler) supportedServiceVersions(compVersion *appsv } func (r *ComponentVersionReconciler) updateSupportedCompDefLabels(cli client.Client, rctx intctrlutil.RequestCtx, - compVersion *appsv1alpha1.ComponentVersion, releaseToCompDefinitions map[string]map[string]*appsv1alpha1.ComponentDefinition) error { + compVersion *appsv1.ComponentVersion, releaseToCompDefinitions map[string]map[string]*appsv1alpha1.ComponentDefinition) error { if compVersion.Annotations == nil { compVersion.Annotations = make(map[string]string) } @@ -282,7 +283,7 @@ func (r *ComponentVersionReconciler) updateSupportedCompDefLabels(cli client.Cli return cli.Update(rctx.Ctx, compVersion) } -func (r *ComponentVersionReconciler) validate(compVersion *appsv1alpha1.ComponentVersion, +func (r *ComponentVersionReconciler) validate(compVersion *appsv1.ComponentVersion, releaseToCompDefinitions map[string]map[string]*appsv1alpha1.ComponentDefinition) error { for _, release := range compVersion.Spec.Releases { if err := r.validateRelease(release, releaseToCompDefinitions); err != nil { @@ -292,7 +293,7 @@ func (r *ComponentVersionReconciler) validate(compVersion *appsv1alpha1.Componen return nil } -func (r *ComponentVersionReconciler) validateRelease(release appsv1alpha1.ComponentVersionRelease, +func (r *ComponentVersionReconciler) validateRelease(release appsv1.ComponentVersionRelease, releaseToCompDefinitions map[string]map[string]*appsv1alpha1.ComponentDefinition) error { cmpds, ok := releaseToCompDefinitions[release.Name] notNil := func(cmpd *appsv1alpha1.ComponentDefinition) bool { @@ -310,11 +311,11 @@ func (r *ComponentVersionReconciler) validateRelease(release appsv1alpha1.Compon return nil } -func (r *ComponentVersionReconciler) validateServiceVersion(release appsv1alpha1.ComponentVersionRelease) error { +func (r *ComponentVersionReconciler) validateServiceVersion(release appsv1.ComponentVersionRelease) error { return validateServiceVersion(release.ServiceVersion) } -func (r *ComponentVersionReconciler) validateImages(release appsv1alpha1.ComponentVersionRelease, cmpds map[string]*appsv1alpha1.ComponentDefinition) error { +func (r *ComponentVersionReconciler) validateImages(release appsv1.ComponentVersionRelease, cmpds map[string]*appsv1alpha1.ComponentDefinition) error { validateContainer := func(cmpd appsv1alpha1.ComponentDefinition, name string) error { cmp := func(c corev1.Container) bool { return c.Name == name @@ -423,7 +424,7 @@ func serviceVersionToCompDefinitions(ctx context.Context, cli client.Reader, } // compatibleServiceVersions4Definition returns all service versions that are compatible with specified component definition. -func compatibleServiceVersions4Definition(compDef *appsv1alpha1.ComponentDefinition, compVersion *appsv1alpha1.ComponentVersion) sets.Set[string] { +func compatibleServiceVersions4Definition(compDef *appsv1alpha1.ComponentDefinition, compVersion *appsv1.ComponentVersion) sets.Set[string] { prefixMatch := func(prefix string) bool { return strings.HasPrefix(compDef.Name, prefix) } diff --git a/controllers/apps/componentversion_controller_test.go b/controllers/apps/componentversion_controller_test.go index 16e1a063d4a..2619436d43b 100644 --- a/controllers/apps/componentversion_controller_test.go +++ b/controllers/apps/componentversion_controller_test.go @@ -30,6 +30,7 @@ import ( "k8s.io/apimachinery/pkg/util/sets" "sigs.k8s.io/controller-runtime/pkg/client" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" "github.com/apecloud/kubeblocks/pkg/controller/component" "github.com/apecloud/kubeblocks/pkg/generics" @@ -39,7 +40,7 @@ import ( var _ = Describe("ComponentVersion Controller", func() { var ( // compDefinitionObjs []*appsv1alpha1.ComponentDefinition - compVersionObj *appsv1alpha1.ComponentVersion + compVersionObj *appsv1.ComponentVersion compDefNames = []string{testapps.CompDefName("v1.0"), testapps.CompDefName("v1.1"), testapps.CompDefName("v2.0"), testapps.CompDefName("v3.0")} serviceVersions = []string{testapps.ServiceVersion("v1"), testapps.ServiceVersion("v2"), testapps.ServiceVersion("v3")} @@ -92,11 +93,11 @@ var _ = Describe("ComponentVersion Controller", func() { return objs } - createCompVersionObj := func() *appsv1alpha1.ComponentVersion { + createCompVersionObj := func() *appsv1.ComponentVersion { By("create a default ComponentVersion obj with multiple releases") obj := testapps.NewComponentVersionFactory(testapps.CompVersionName). - SetSpec(appsv1alpha1.ComponentVersionSpec{ - CompatibilityRules: []appsv1alpha1.ComponentVersionCompatibilityRule{ + SetSpec(appsv1.ComponentVersionSpec{ + CompatibilityRules: []appsv1.ComponentVersionCompatibilityRule{ { // use prefix CompDefs: []string{testapps.CompDefName("v1"), testapps.CompDefName("v2")}, @@ -108,7 +109,7 @@ var _ = Describe("ComponentVersion Controller", func() { Releases: []string{testapps.ReleaseID("r5")}, // sv: v3 }, }, - Releases: []appsv1alpha1.ComponentVersionRelease{ + Releases: []appsv1.ComponentVersionRelease{ { Name: testapps.ReleaseID("r0"), Changes: "init release", @@ -166,7 +167,7 @@ var _ = Describe("ComponentVersion Controller", func() { Create(&testCtx). GetObject() Eventually(testapps.CheckObj(&testCtx, client.ObjectKeyFromObject(obj), - func(g Gomega, compVersion *appsv1alpha1.ComponentVersion) { + func(g Gomega, compVersion *appsv1.ComponentVersion) { g.Expect(compVersion.Status.ObservedGeneration).Should(Equal(compVersion.Generation)) })).Should(Succeed()) @@ -195,10 +196,10 @@ var _ = Describe("ComponentVersion Controller", func() { It("ok", func() { By("checking the object available") Eventually(testapps.CheckObj(&testCtx, client.ObjectKeyFromObject(compVersionObj), - func(g Gomega, cmpv *appsv1alpha1.ComponentVersion) { + func(g Gomega, cmpv *appsv1.ComponentVersion) { g.Expect(cmpv.Finalizers).ShouldNot(BeEmpty()) g.Expect(cmpv.Status.ObservedGeneration).Should(Equal(cmpv.GetGeneration())) - g.Expect(cmpv.Status.Phase).Should(Equal(appsv1alpha1.AvailablePhase)) + g.Expect(cmpv.Status.Phase).Should(Equal(appsv1.AvailablePhase)) g.Expect(cmpv.Status.ServiceVersions).Should(Equal(strings.Join(serviceVersions, ","))) for i := 0; i < len(compDefNames); i++ { g.Expect(cmpv.Labels).Should(HaveKeyWithValue(compDefNames[i], compDefNames[i])) @@ -214,39 +215,39 @@ var _ = Describe("ComponentVersion Controller", func() { By("checking the object unavailable") Eventually(testapps.CheckObj(&testCtx, client.ObjectKeyFromObject(compVersionObj), - func(g Gomega, cmpv *appsv1alpha1.ComponentVersion) { + func(g Gomega, cmpv *appsv1.ComponentVersion) { g.Expect(cmpv.Status.ObservedGeneration).Should(Equal(cmpv.GetGeneration())) - g.Expect(cmpv.Status.Phase).Should(Equal(appsv1alpha1.UnavailablePhase)) + g.Expect(cmpv.Status.Phase).Should(Equal(appsv1.UnavailablePhase)) })).Should(Succeed()) }) It("w/o container defined", func() { By("update component version to add a non-exist app") compVersionKey := client.ObjectKeyFromObject(compVersionObj) - Eventually(testapps.GetAndChangeObj(&testCtx, compVersionKey, func(compVersion *appsv1alpha1.ComponentVersion) { + Eventually(testapps.GetAndChangeObj(&testCtx, compVersionKey, func(compVersion *appsv1.ComponentVersion) { compVersion.Spec.Releases[0].Images["app-non-exist"] = "app-image-non-exist" })).Should(Succeed()) By("checking the object unavailable") Eventually(testapps.CheckObj(&testCtx, client.ObjectKeyFromObject(compVersionObj), - func(g Gomega, cmpv *appsv1alpha1.ComponentVersion) { + func(g Gomega, cmpv *appsv1.ComponentVersion) { g.Expect(cmpv.Status.ObservedGeneration).Should(Equal(cmpv.GetGeneration())) - g.Expect(cmpv.Status.Phase).Should(Equal(appsv1alpha1.UnavailablePhase)) + g.Expect(cmpv.Status.Phase).Should(Equal(appsv1.UnavailablePhase)) })).Should(Succeed()) }) It("delete component definition", func() { By("update component version to delete definition v1.*") compVersionKey := client.ObjectKeyFromObject(compVersionObj) - Eventually(testapps.GetAndChangeObj(&testCtx, compVersionKey, func(compVersion *appsv1alpha1.ComponentVersion) { + Eventually(testapps.GetAndChangeObj(&testCtx, compVersionKey, func(compVersion *appsv1.ComponentVersion) { compVersion.Spec.CompatibilityRules[0].CompDefs = []string{testapps.CompDefName("v2")} })).Should(Succeed()) By("checking the object available") Eventually(testapps.CheckObj(&testCtx, client.ObjectKeyFromObject(compVersionObj), - func(g Gomega, cmpv *appsv1alpha1.ComponentVersion) { + func(g Gomega, cmpv *appsv1.ComponentVersion) { g.Expect(cmpv.Status.ObservedGeneration).Should(Equal(cmpv.GetGeneration())) - g.Expect(cmpv.Status.Phase).Should(Equal(appsv1alpha1.AvailablePhase)) + g.Expect(cmpv.Status.Phase).Should(Equal(appsv1.AvailablePhase)) g.Expect(cmpv.Status.ServiceVersions).Should(Equal(strings.Join(serviceVersions, ","))) for i := 0; i < len(compDefNames); i++ { if strings.HasPrefix(compDefNames[i], testapps.CompDefName("v1")) { @@ -269,9 +270,9 @@ var _ = Describe("ComponentVersion Controller", func() { By("checking the object available") Eventually(testapps.CheckObj(&testCtx, client.ObjectKeyFromObject(compVersionObj), - func(g Gomega, cmpv *appsv1alpha1.ComponentVersion) { + func(g Gomega, cmpv *appsv1.ComponentVersion) { g.Expect(cmpv.Status.ObservedGeneration).Should(Equal(cmpv.GetGeneration())) - g.Expect(cmpv.Status.Phase).Should(Equal(appsv1alpha1.AvailablePhase)) + g.Expect(cmpv.Status.Phase).Should(Equal(appsv1.AvailablePhase)) g.Expect(cmpv.Status.ServiceVersions).Should(Equal(strings.Join(serviceVersions, ","))) for i := 0; i < len(compDefNames); i++ { if strings.HasPrefix(compDefNames[i], testapps.CompDefName("v1")) { @@ -286,16 +287,16 @@ var _ = Describe("ComponentVersion Controller", func() { It("delete a release", func() { By("update component version to delete first release") compVersionKey := client.ObjectKeyFromObject(compVersionObj) - Eventually(testapps.GetAndChangeObj(&testCtx, compVersionKey, func(compVersion *appsv1alpha1.ComponentVersion) { + Eventually(testapps.GetAndChangeObj(&testCtx, compVersionKey, func(compVersion *appsv1.ComponentVersion) { compVersion.Spec.Releases = compVersion.Spec.Releases[1:] compVersion.Spec.CompatibilityRules[0].Releases = compVersion.Spec.CompatibilityRules[0].Releases[1:] })).Should(Succeed()) By("checking the object available") Eventually(testapps.CheckObj(&testCtx, client.ObjectKeyFromObject(compVersionObj), - func(g Gomega, cmpv *appsv1alpha1.ComponentVersion) { + func(g Gomega, cmpv *appsv1.ComponentVersion) { g.Expect(cmpv.Status.ObservedGeneration).Should(Equal(cmpv.GetGeneration())) - g.Expect(cmpv.Status.Phase).Should(Equal(appsv1alpha1.AvailablePhase)) + g.Expect(cmpv.Status.Phase).Should(Equal(appsv1.AvailablePhase)) g.Expect(cmpv.Status.ServiceVersions).Should(Equal(strings.Join(serviceVersions, ","))) for i := 0; i < len(compDefNames); i++ { g.Expect(cmpv.Labels).Should(HaveKeyWithValue(compDefNames[i], compDefNames[i])) @@ -306,9 +307,9 @@ var _ = Describe("ComponentVersion Controller", func() { It("delete a service version", func() { By("update component version to delete releases for service version v1") compVersionKey := client.ObjectKeyFromObject(compVersionObj) - Eventually(testapps.GetAndChangeObj(&testCtx, compVersionKey, func(compVersion *appsv1alpha1.ComponentVersion) { + Eventually(testapps.GetAndChangeObj(&testCtx, compVersionKey, func(compVersion *appsv1.ComponentVersion) { releaseToDelete := sets.New[string]() - releases := make([]appsv1alpha1.ComponentVersionRelease, 0) + releases := make([]appsv1.ComponentVersionRelease, 0) for i, release := range compVersion.Spec.Releases { if release.ServiceVersion == testapps.ServiceVersion("v2") { releaseToDelete.Insert(release.Name) @@ -332,9 +333,9 @@ var _ = Describe("ComponentVersion Controller", func() { By("checking the object available") Eventually(testapps.CheckObj(&testCtx, client.ObjectKeyFromObject(compVersionObj), - func(g Gomega, cmpv *appsv1alpha1.ComponentVersion) { + func(g Gomega, cmpv *appsv1.ComponentVersion) { g.Expect(cmpv.Status.ObservedGeneration).Should(Equal(cmpv.GetGeneration())) - g.Expect(cmpv.Status.Phase).Should(Equal(appsv1alpha1.AvailablePhase)) + g.Expect(cmpv.Status.Phase).Should(Equal(appsv1.AvailablePhase)) g.Expect(cmpv.Status.ServiceVersions).Should(Equal(strings.Join([]string{testapps.ServiceVersion("v1"), testapps.ServiceVersion("v3")}, ","))) for i := 0; i < len(compDefNames); i++ { g.Expect(cmpv.Labels).Should(HaveKeyWithValue(compDefNames[i], compDefNames[i])) @@ -518,8 +519,8 @@ var _ = Describe("ComponentVersion Controller", func() { By("new release for the definition") compVersionKey := client.ObjectKeyFromObject(compVersionObj) - Eventually(testapps.GetAndChangeObj(&testCtx, compVersionKey, func(compVersion *appsv1alpha1.ComponentVersion) { - release := appsv1alpha1.ComponentVersionRelease{ + Eventually(testapps.GetAndChangeObj(&testCtx, compVersionKey, func(compVersion *appsv1.ComponentVersion) { + release := appsv1.ComponentVersionRelease{ Name: testapps.ReleaseID("r6"), Changes: "publish a new service version", ServiceVersion: testapps.ServiceVersion("v4"), @@ -529,14 +530,14 @@ var _ = Describe("ComponentVersion Controller", func() { // testapps.AppNameSamePrefix: testapps.AppImage(testapps.AppNameSamePrefix, testapps.ReleaseID("r6")), }, } - rule := appsv1alpha1.ComponentVersionCompatibilityRule{ + rule := appsv1.ComponentVersionCompatibilityRule{ CompDefs: []string{testapps.CompDefName("v4")}, // use prefix Releases: []string{testapps.ReleaseID("r6")}, } compVersion.Spec.CompatibilityRules = append(compVersion.Spec.CompatibilityRules, rule) compVersion.Spec.Releases = append(compVersion.Spec.Releases, release) })).Should(Succeed()) - Eventually(testapps.CheckObj(&testCtx, compVersionKey, func(g Gomega, compVersion *appsv1alpha1.ComponentVersion) { + Eventually(testapps.CheckObj(&testCtx, compVersionKey, func(g Gomega, compVersion *appsv1.ComponentVersion) { g.Expect(compVersion.Status.ObservedGeneration).Should(Equal(compVersion.Generation)) })).Should(Succeed()) diff --git a/controllers/apps/operations/upgrade_test.go b/controllers/apps/operations/upgrade_test.go index 1c6034fa395..53a57c30f0b 100644 --- a/controllers/apps/operations/upgrade_test.go +++ b/controllers/apps/operations/upgrade_test.go @@ -27,6 +27,7 @@ import ( "k8s.io/utils/pointer" "sigs.k8s.io/controller-runtime/pkg/client" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" intctrlutil "github.com/apecloud/kubeblocks/pkg/controllerutil" "github.com/apecloud/kubeblocks/pkg/generics" @@ -103,8 +104,8 @@ var _ = Describe("Upgrade OpsRequest", func() { }).Create(&testCtx).GetObject() if createCompVersion { compVersion := testapps.NewComponentVersionFactory(testapps.CompVersionName). - SetSpec(appsv1alpha1.ComponentVersionSpec{ - CompatibilityRules: []appsv1alpha1.ComponentVersionCompatibilityRule{ + SetSpec(appsv1.ComponentVersionSpec{ + CompatibilityRules: []appsv1.ComponentVersionCompatibilityRule{ { // use prefix CompDefs: []string{compDef1.Name}, @@ -116,7 +117,7 @@ var _ = Describe("Upgrade OpsRequest", func() { Releases: []string{release2, release3}, // sv: v2 }, }, - Releases: []appsv1alpha1.ComponentVersionRelease{ + Releases: []appsv1.ComponentVersionRelease{ { Name: release0, Changes: "init release", @@ -162,7 +163,7 @@ var _ = Describe("Upgrade OpsRequest", func() { Create(&testCtx). GetObject() // label the componentDef info to the ComponentVersion - Expect(testapps.ChangeObj(&testCtx, compVersion, func(version *appsv1alpha1.ComponentVersion) { + Expect(testapps.ChangeObj(&testCtx, compVersion, func(version *appsv1.ComponentVersion) { if version.Labels == nil { version.Labels = map[string]string{} } @@ -172,7 +173,7 @@ var _ = Describe("Upgrade OpsRequest", func() { // mock ComponentVersion to Available Expect(testapps.ChangeObjStatus(&testCtx, compVersion, func() { - compVersion.Status.Phase = appsv1alpha1.AvailablePhase + compVersion.Status.Phase = appsv1.AvailablePhase compVersion.Status.ObservedGeneration = compVersion.Generation })).Should(Succeed()) } diff --git a/deploy/helm/crds/apps.kubeblocks.io_components.yaml b/deploy/helm/crds/apps.kubeblocks.io_components.yaml index 6d18c4c7e6e..1aade3253e2 100644 --- a/deploy/helm/crds/apps.kubeblocks.io_components.yaml +++ b/deploy/helm/crds/apps.kubeblocks.io_components.yaml @@ -11,6 +11,7 @@ spec: names: categories: - kubeblocks + - all kind: Component listKind: ComponentList plural: components diff --git a/deploy/helm/crds/apps.kubeblocks.io_componentversions.yaml b/deploy/helm/crds/apps.kubeblocks.io_componentversions.yaml index bb9cd05805a..47d4f98fecb 100644 --- a/deploy/helm/crds/apps.kubeblocks.io_componentversions.yaml +++ b/deploy/helm/crds/apps.kubeblocks.io_componentversions.yaml @@ -56,13 +56,118 @@ spec: spec: description: ComponentVersionSpec defines the desired state of ComponentVersion properties: - foo: - description: Foo is an example field of ComponentVersion. Edit componentversion_types.go - to remove/update - type: string + compatibilityRules: + description: CompatibilityRules defines compatibility rules between + sets of component definitions and releases. + items: + description: ComponentVersionCompatibilityRule defines the compatibility + between a set of component definitions and a set of releases. + properties: + compDefs: + description: |- + CompDefs specifies names for the component definitions associated with this ComponentVersion. + Each name in the list can represent an exact name, or a name prefix. + + + For example: + + + - "mysql-8.0.30-v1alpha1": Matches the exact name "mysql-8.0.30-v1alpha1" + - "mysql-8.0.30": Matches all names starting with "mysql-8.0.30" + items: + type: string + maxItems: 128 + minItems: 1 + type: array + releases: + description: Releases is a list of identifiers for the releases. + items: + type: string + maxItems: 128 + minItems: 1 + type: array + required: + - compDefs + - releases + type: object + maxItems: 128 + minItems: 1 + type: array + releases: + description: Releases represents different releases of component instances + within this ComponentVersion. + items: + description: ComponentVersionRelease represents a release of component + instances within a ComponentVersion. + properties: + changes: + description: Changes provides information about the changes + made in this release. + maxLength: 256 + type: string + images: + additionalProperties: + type: string + description: Images define the new images for different containers + within the release. + maxProperties: 128 + minProperties: 1 + type: object + x-kubernetes-validations: + - message: Container name may not exceed maximum length of 32 + characters + rule: self.all(key, size(key) <= 32) + - message: Image name may not exceed maximum length of 256 characters + rule: self.all(key, size(self[key]) <= 256) + name: + description: |- + Name is a unique identifier for this release. + Cannot be updated. + maxLength: 32 + type: string + serviceVersion: + description: |- + ServiceVersion defines the version of the well-known service that the component provides. + The version should follow the syntax and semantics of the "Semantic Versioning" specification (http://semver.org/). + If the release is used, it will serve as the service version for component instances, overriding the one defined in the component definition. + Cannot be updated. + maxLength: 32 + type: string + required: + - images + - name + - serviceVersion + type: object + maxItems: 128 + minItems: 1 + type: array + required: + - compatibilityRules + - releases type: object status: description: ComponentVersionStatus defines the observed state of ComponentVersion + properties: + message: + description: Extra message for current phase. + type: string + observedGeneration: + description: ObservedGeneration is the most recent generation observed + for this ComponentVersion. + format: int64 + type: integer + phase: + description: |- + Phase valid values are ``, `Available`, 'Unavailable`. + Available is ComponentVersion become available, and can be used for co-related objects. + enum: + - Available + - Unavailable + type: string + serviceVersions: + description: ServiceVersions represent the supported service versions + of this ComponentVersion. + type: string type: object type: object served: true diff --git a/deploy/helm/crds/apps.kubeblocks.io_servicedescriptors.yaml b/deploy/helm/crds/apps.kubeblocks.io_servicedescriptors.yaml index 99d33d9eaff..3b84dcb3e59 100644 --- a/deploy/helm/crds/apps.kubeblocks.io_servicedescriptors.yaml +++ b/deploy/helm/crds/apps.kubeblocks.io_servicedescriptors.yaml @@ -11,7 +11,6 @@ spec: names: categories: - kubeblocks - - all kind: ServiceDescriptor listKind: ServiceDescriptorList plural: servicedescriptors diff --git a/docs/developer_docs/api-reference/cluster.md b/docs/developer_docs/api-reference/cluster.md index 1046003bc7c..3bbe9637eee 100644 --- a/docs/developer_docs/api-reference/cluster.md +++ b/docs/developer_docs/api-reference/cluster.md @@ -487,13 +487,28 @@ ComponentVersionSpec + + + +
-foo
+compatibilityRules
-string + +[]ComponentVersionCompatibilityRule + + +
+

CompatibilityRules defines compatibility rules between sets of component definitions and releases.

+
+releases
+ + +[]ComponentVersionRelease +
-

Foo is an example field of ComponentVersion. Edit componentversion_types.go to remove/update

+

Releases represents different releases of component instances within this ComponentVersion.

@@ -1081,6 +1096,119 @@ string

ComponentStatus defines the observed state of Component

+

ComponentVersionCompatibilityRule +

+

+(Appears on:ComponentVersionSpec) +

+
+

ComponentVersionCompatibilityRule defines the compatibility between a set of component definitions and a set of releases.

+
+ + + + + + + + + + + + + + + + + +
FieldDescription
+compDefs
+ +[]string + +
+

CompDefs specifies names for the component definitions associated with this ComponentVersion. +Each name in the list can represent an exact name, or a name prefix.

+

For example:

+
    +
  • “mysql-8.0.30-v1alpha1”: Matches the exact name “mysql-8.0.30-v1alpha1”
  • +
  • “mysql-8.0.30”: Matches all names starting with “mysql-8.0.30”
  • +
+
+releases
+ +[]string + +
+

Releases is a list of identifiers for the releases.

+
+

ComponentVersionRelease +

+

+(Appears on:ComponentVersionSpec) +

+
+

ComponentVersionRelease represents a release of component instances within a ComponentVersion.

+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+name
+ +string + +
+

Name is a unique identifier for this release. +Cannot be updated.

+
+changes
+ +string + +
+(Optional) +

Changes provides information about the changes made in this release.

+
+serviceVersion
+ +string + +
+

ServiceVersion defines the version of the well-known service that the component provides. +The version should follow the syntax and semantics of the “Semantic Versioning” specification (http://semver.org/). +If the release is used, it will serve as the service version for component instances, overriding the one defined in the component definition. +Cannot be updated.

+
+images
+ +map[string]string + +
+

Images define the new images for different containers within the release.

+

ComponentVersionSpec

@@ -1099,13 +1227,28 @@ string -foo
+compatibilityRules
-string + +[]ComponentVersionCompatibilityRule + + + + +

CompatibilityRules defines compatibility rules between sets of component definitions and releases.

+ + + + +releases
+ + +[]ComponentVersionRelease + -

Foo is an example field of ComponentVersion. Edit componentversion_types.go to remove/update

+

Releases represents different releases of component instances within this ComponentVersion.

@@ -1118,6 +1261,67 @@ string

ComponentVersionStatus defines the observed state of ComponentVersion

+ + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+observedGeneration
+ +int64 + +
+(Optional) +

ObservedGeneration is the most recent generation observed for this ComponentVersion.

+
+phase
+ + +Phase + + +
+(Optional) +

Phase valid values are `,Available, 'Unavailable. +Available is ComponentVersion become available, and can be used for co-related objects.

+
+message
+ +string + +
+(Optional) +

Extra message for current phase.

+
+serviceVersions
+ +string + +
+(Optional) +

ServiceVersions represent the supported service versions of this ComponentVersion.

+

ConnectionCredentialAuth

@@ -1223,7 +1427,7 @@ Kubernetes core/v1.EnvVarSource

Phase (string alias)

-(Appears on:ClusterDefinitionStatus, ServiceDescriptorStatus) +(Appears on:ClusterDefinitionStatus, ComponentVersionStatus, ServiceDescriptorStatus)

Phase represents the status of a CR.

diff --git a/pkg/controller/component/component_version.go b/pkg/controller/component/component_version.go index c6ccf9f8753..5f527700235 100644 --- a/pkg/controller/component/component_version.go +++ b/pkg/controller/component/component_version.go @@ -29,12 +29,13 @@ import ( "k8s.io/apimachinery/pkg/util/version" "sigs.k8s.io/controller-runtime/pkg/client" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" ) // CompatibleCompVersions4Definition returns all component versions that are compatible with specified component definition. -func CompatibleCompVersions4Definition(ctx context.Context, cli client.Reader, compDef *appsv1alpha1.ComponentDefinition) ([]*appsv1alpha1.ComponentVersion, error) { - compVersionList := &appsv1alpha1.ComponentVersionList{} +func CompatibleCompVersions4Definition(ctx context.Context, cli client.Reader, compDef *appsv1alpha1.ComponentDefinition) ([]*appsv1.ComponentVersion, error) { + compVersionList := &appsv1.ComponentVersionList{} labels := client.MatchingLabels{ compDef.Name: compDef.Name, } @@ -46,12 +47,12 @@ func CompatibleCompVersions4Definition(ctx context.Context, cli client.Reader, c return nil, nil } - compVersions := make([]*appsv1alpha1.ComponentVersion, 0) + compVersions := make([]*appsv1.ComponentVersion, 0) for i, compVersion := range compVersionList.Items { if compVersion.Generation != compVersion.Status.ObservedGeneration { return nil, fmt.Errorf("the matched ComponentVersion is not up to date: %s", compVersion.Name) } - if compVersion.Status.Phase != appsv1alpha1.AvailablePhase { + if compVersion.Status.Phase != appsv1.AvailablePhase { return nil, fmt.Errorf("the matched ComponentVersion is unavailable: %s", compVersion.Name) } compVersions = append(compVersions, &compVersionList.Items[i]) @@ -98,7 +99,7 @@ func UpdateCompDefinitionImages4ServiceVersion(ctx context.Context, cli client.R } func resolveImagesWithCompVersions(compDef *appsv1alpha1.ComponentDefinition, - compVersions []*appsv1alpha1.ComponentVersion, serviceVersion string) error { + compVersions []*appsv1.ComponentVersion, serviceVersion string) error { appsInDef := covertImagesFromCompDefinition(compDef) appsByUser, err := findMatchedImagesFromCompVersions(compVersions, serviceVersion) if err != nil { @@ -154,7 +155,7 @@ func covertImagesFromCompDefinition(compDef *appsv1alpha1.ComponentDefinition) m return apps } -func findMatchedImagesFromCompVersions(compVersions []*appsv1alpha1.ComponentVersion, serviceVersion string) (map[string]appNameVersionImage, error) { +func findMatchedImagesFromCompVersions(compVersions []*appsv1.ComponentVersion, serviceVersion string) (map[string]appNameVersionImage, error) { appsWithReleases := make(map[string]map[string]appNameVersionImage) for _, compVersion := range compVersions { for _, release := range compVersion.Spec.Releases { diff --git a/pkg/controller/component/component_version_test.go b/pkg/controller/component/component_version_test.go index 27f760be3b9..aad45312614 100644 --- a/pkg/controller/component/component_version_test.go +++ b/pkg/controller/component/component_version_test.go @@ -26,7 +26,7 @@ import ( corev1 "k8s.io/api/core/v1" "sigs.k8s.io/controller-runtime/pkg/client" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" "github.com/apecloud/kubeblocks/pkg/generics" testapps "github.com/apecloud/kubeblocks/pkg/testutil/apps" ) @@ -63,7 +63,7 @@ var _ = Describe("Component Version", func() { Image: testapps.AppImage(testapps.AppName, testapps.ReleaseID(""))}). GetObject() - releases := []appsv1alpha1.ComponentVersionRelease{ + releases := []appsv1.ComponentVersionRelease{ { Name: testapps.ReleaseID("r0"), Changes: "init release in v1", @@ -92,19 +92,19 @@ var _ = Describe("Component Version", func() { By("first release for the definition") compVersionObj := testapps.NewComponentVersionFactory(testapps.CompVersionName). - SetSpec(appsv1alpha1.ComponentVersionSpec{ - CompatibilityRules: []appsv1alpha1.ComponentVersionCompatibilityRule{ + SetSpec(appsv1.ComponentVersionSpec{ + CompatibilityRules: []appsv1.ComponentVersionCompatibilityRule{ { CompDefs: []string{testapps.CompDefName("v1")}, Releases: []string{releases[0].Name}, }, }, - Releases: []appsv1alpha1.ComponentVersionRelease{releases[0]}, + Releases: []appsv1.ComponentVersionRelease{releases[0]}, }). GetObject() By("with app image in r0") - err := resolveImagesWithCompVersions(compDefObj, []*appsv1alpha1.ComponentVersion{compVersionObj}, testapps.ServiceVersion("v1")) + err := resolveImagesWithCompVersions(compDefObj, []*appsv1.ComponentVersion{compVersionObj}, testapps.ServiceVersion("v1")) Expect(err).Should(Succeed()) Expect(compDefObj.Spec.Runtime.Containers[0].Image).Should(Equal(releases[0].Images[testapps.AppName])) @@ -113,7 +113,7 @@ var _ = Describe("Component Version", func() { compVersionObj.Spec.CompatibilityRules[0].Releases = append(compVersionObj.Spec.CompatibilityRules[0].Releases, releases[1].Name) By("with app image still in r0") - err = resolveImagesWithCompVersions(compDefObj, []*appsv1alpha1.ComponentVersion{compVersionObj}, testapps.ServiceVersion("v1")) + err = resolveImagesWithCompVersions(compDefObj, []*appsv1.ComponentVersion{compVersionObj}, testapps.ServiceVersion("v1")) Expect(err).Should(Succeed()) Expect(compDefObj.Spec.Runtime.Containers[0].Image).Should(Equal(releases[0].Images[testapps.AppName])) @@ -122,7 +122,7 @@ var _ = Describe("Component Version", func() { compVersionObj.Spec.CompatibilityRules[0].Releases = append(compVersionObj.Spec.CompatibilityRules[0].Releases, releases[2].Name) By("with app image in r2") - err = resolveImagesWithCompVersions(compDefObj, []*appsv1alpha1.ComponentVersion{compVersionObj}, testapps.ServiceVersion("v1")) + err = resolveImagesWithCompVersions(compDefObj, []*appsv1.ComponentVersion{compVersionObj}, testapps.ServiceVersion("v1")) Expect(err).Should(Succeed()) Expect(compDefObj.Spec.Runtime.Containers[0].Image).Should(Equal(releases[2].Images[testapps.AppName])) }) diff --git a/pkg/generics/type.go b/pkg/generics/type.go index ddc697e5310..dc6ebeb1a8a 100644 --- a/pkg/generics/type.go +++ b/pkg/generics/type.go @@ -29,6 +29,7 @@ import ( "k8s.io/apimachinery/pkg/runtime/schema" "sigs.k8s.io/controller-runtime/pkg/client" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" appsv1beta1 "github.com/apecloud/kubeblocks/apis/apps/v1beta1" dpv1alpha1 "github.com/apecloud/kubeblocks/apis/dataprotection/v1alpha1" @@ -88,13 +89,13 @@ var VolumeSnapshotClassSignature = func(_ snapshotv1.VolumeSnapshotClass, _ *sna var ClusterSignature = func(_ appsv1alpha1.Cluster, _ *appsv1alpha1.Cluster, _ appsv1alpha1.ClusterList, _ *appsv1alpha1.ClusterList) { } -var ClusterDefinitionSignature = func(_ appsv1alpha1.ClusterDefinition, _ *appsv1alpha1.ClusterDefinition, _ appsv1alpha1.ClusterDefinitionList, _ *appsv1alpha1.ClusterDefinitionList) { +var ClusterDefinitionSignature = func(_ appsv1.ClusterDefinition, _ *appsv1.ClusterDefinition, _ appsv1.ClusterDefinitionList, _ *appsv1.ClusterDefinitionList) { } var ComponentSignature = func(appsv1alpha1.Component, *appsv1alpha1.Component, appsv1alpha1.ComponentList, *appsv1alpha1.ComponentList) { } var ComponentDefinitionSignature = func(appsv1alpha1.ComponentDefinition, *appsv1alpha1.ComponentDefinition, appsv1alpha1.ComponentDefinitionList, *appsv1alpha1.ComponentDefinitionList) { } -var ComponentVersionSignature = func(appsv1alpha1.ComponentVersion, *appsv1alpha1.ComponentVersion, appsv1alpha1.ComponentVersionList, *appsv1alpha1.ComponentVersionList) { +var ComponentVersionSignature = func(appsv1.ComponentVersion, *appsv1.ComponentVersion, appsv1.ComponentVersionList, *appsv1.ComponentVersionList) { } var OpsDefinitionSignature = func(_ appsv1alpha1.OpsDefinition, _ *appsv1alpha1.OpsDefinition, _ appsv1alpha1.OpsDefinitionList, _ *appsv1alpha1.OpsDefinitionList) { } @@ -127,9 +128,6 @@ var StorageProviderSignature = func(_ dpv1alpha1.StorageProvider, _ *dpv1alpha1. var ConfigurationSignature = func(_ appsv1alpha1.Configuration, _ *appsv1alpha1.Configuration, _ appsv1alpha1.ConfigurationList, _ *appsv1alpha1.ConfigurationList) { } -var ServiceDescriptorSignature = func(_ appsv1alpha1.ServiceDescriptor, _ *appsv1alpha1.ServiceDescriptor, _ appsv1alpha1.ServiceDescriptorList, _ *appsv1alpha1.ServiceDescriptorList) { -} - func ToGVK(object client.Object) schema.GroupVersionKind { t := reflect.TypeOf(object) if t.Kind() != reflect.Pointer { diff --git a/pkg/testutil/apps/componentversion_factory.go b/pkg/testutil/apps/componentversion_factory.go index 32e7d4419f6..b025f7ad640 100644 --- a/pkg/testutil/apps/componentversion_factory.go +++ b/pkg/testutil/apps/componentversion_factory.go @@ -20,25 +20,25 @@ along with this program. If not, see . package apps import ( - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" ) type MockComponentVersionFactory struct { - BaseFactory[appsv1alpha1.ComponentVersion, *appsv1alpha1.ComponentVersion, MockComponentVersionFactory] + BaseFactory[appsv1.ComponentVersion, *appsv1.ComponentVersion, MockComponentVersionFactory] } func NewComponentVersionFactory(name string) *MockComponentVersionFactory { f := &MockComponentVersionFactory{} - f.Init("", name, &appsv1alpha1.ComponentVersion{ - Spec: appsv1alpha1.ComponentVersionSpec{ - CompatibilityRules: []appsv1alpha1.ComponentVersionCompatibilityRule{}, - Releases: []appsv1alpha1.ComponentVersionRelease{}, + f.Init("", name, &appsv1.ComponentVersion{ + Spec: appsv1.ComponentVersionSpec{ + CompatibilityRules: []appsv1.ComponentVersionCompatibilityRule{}, + Releases: []appsv1.ComponentVersionRelease{}, }, }, f) return f } -func (f *MockComponentVersionFactory) SetSpec(spec appsv1alpha1.ComponentVersionSpec) *MockComponentVersionFactory { +func (f *MockComponentVersionFactory) SetSpec(spec appsv1.ComponentVersionSpec) *MockComponentVersionFactory { f.Get().Spec = spec return f } @@ -49,7 +49,7 @@ func (f *MockComponentVersionFactory) SetDefaultSpec(compDef string) *MockCompon } func (f *MockComponentVersionFactory) AddRelease(name, changes, serviceVersion string, images map[string]string) *MockComponentVersionFactory { - release := appsv1alpha1.ComponentVersionRelease{ + release := appsv1.ComponentVersionRelease{ Name: name, Changes: changes, ServiceVersion: serviceVersion, @@ -60,7 +60,7 @@ func (f *MockComponentVersionFactory) AddRelease(name, changes, serviceVersion s } func (f *MockComponentVersionFactory) AddCompatibilityRule(compDefs, releases []string) *MockComponentVersionFactory { - rule := appsv1alpha1.ComponentVersionCompatibilityRule{ + rule := appsv1.ComponentVersionCompatibilityRule{ CompDefs: compDefs, Releases: releases, } diff --git a/pkg/testutil/apps/constant.go b/pkg/testutil/apps/constant.go index e27e501b25a..50da43c2012 100644 --- a/pkg/testutil/apps/constant.go +++ b/pkg/testutil/apps/constant.go @@ -26,6 +26,7 @@ import ( "k8s.io/apimachinery/pkg/api/resource" "k8s.io/apimachinery/pkg/util/intstr" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" ) @@ -269,15 +270,15 @@ var ( }, } - defaultComponentVerSpec = func(compDef string) appsv1alpha1.ComponentVersionSpec { - return appsv1alpha1.ComponentVersionSpec{ - CompatibilityRules: []appsv1alpha1.ComponentVersionCompatibilityRule{ + defaultComponentVerSpec = func(compDef string) appsv1.ComponentVersionSpec { + return appsv1.ComponentVersionSpec{ + CompatibilityRules: []appsv1.ComponentVersionCompatibilityRule{ { CompDefs: []string{compDef}, Releases: []string{"8.0.30-r1"}, }, }, - Releases: []appsv1alpha1.ComponentVersionRelease{ + Releases: []appsv1.ComponentVersionRelease{ { Name: "8.0.30-r1", Changes: "init release", From ae4d56babdbbb9bf9d218c7bcec2528a5b1e790f Mon Sep 17 00:00:00 2001 From: Leon Date: Tue, 3 Sep 2024 11:31:56 +0800 Subject: [PATCH 06/15] component and cmpd --- apis/apps/v1/component_types.go | 278 +- apis/apps/v1/componentdefinition_types.go | 1790 ++- apis/apps/v1/types.go | 647 + apis/apps/v1/zz_generated.deepcopy.go | 1826 ++- apis/apps/v1alpha1/component_conversion.go | 31 + ...ps.kubeblocks.io_componentdefinitions.yaml | 13035 +++++++++++++++- .../bases/apps.kubeblocks.io_components.yaml | 7429 ++++++++- ...apps.kubeblocks.io_servicedescriptors.yaml | 1 + controllers/apps/cluster_controller_test.go | 46 +- controllers/apps/cluster_plan_builder.go | 2 +- .../apps/clusterdefinition_controller.go | 12 +- .../apps/clusterdefinition_controller_test.go | 5 +- controllers/apps/component_controller_test.go | 114 +- controllers/apps/component_plan_builder.go | 7 +- .../apps/componentdefinition_controller.go | 77 +- .../componentdefinition_controller_test.go | 91 +- .../apps/componentversion_controller.go | 46 +- .../apps/componentversion_controller_test.go | 23 +- controllers/apps/configuration/config_util.go | 42 +- .../apps/configuration/config_util_test.go | 8 +- .../configconstraint_controller.go | 3 +- .../configuration/configuration_controller.go | 3 +- .../apps/configuration/configuration_test.go | 9 +- .../apps/configuration/policy_util_test.go | 3 +- .../apps/configuration/reconcile_task.go | 6 +- controllers/apps/operations/custom.go | 5 +- controllers/apps/operations/custom_test.go | 6 +- .../apps/operations/ops_comp_helper.go | 9 +- controllers/apps/operations/ops_util.go | 5 +- .../apps/operations/reconfigure_test.go | 7 +- controllers/apps/operations/suite_test.go | 3 +- .../apps/operations/switchover_test.go | 3 +- .../apps/operations/switchover_util.go | 3 +- controllers/apps/operations/type.go | 5 +- controllers/apps/operations/upgrade.go | 7 +- controllers/apps/operations/upgrade_test.go | 2 +- .../apps/opsrequest_controller_test.go | 7 +- .../transformer_cluster_api_normalization.go | 10 +- .../apps/transformer_cluster_component.go | 22 +- .../transformer_cluster_component_status.go | 19 +- .../transformer_cluster_component_test.go | 162 +- .../apps/transformer_cluster_deletion.go | 3 +- .../apps/transformer_cluster_service.go | 5 +- .../apps/transformer_component_account.go | 18 +- ...transformer_component_account_provision.go | 12 +- .../apps/transformer_component_deletion.go | 15 +- .../transformer_component_pre_terminate.go | 11 +- .../apps/transformer_component_rbac.go | 9 +- .../apps/transformer_component_rbac_test.go | 5 +- .../apps/transformer_component_service.go | 32 +- .../transformer_component_service_test.go | 12 +- .../apps/transformer_component_status.go | 27 +- controllers/apps/transformer_component_tls.go | 11 +- .../apps/transformer_component_tls_test.go | 9 +- .../apps/transformer_component_utils.go | 8 +- .../apps/transformer_component_validation.go | 12 +- .../apps/transformer_component_workload.go | 5 +- .../transformer_component_workload_upgrade.go | 4 +- ...ps.kubeblocks.io_componentdefinitions.yaml | 13035 +++++++++++++++- .../crds/apps.kubeblocks.io_components.yaml | 7429 ++++++++- ...apps.kubeblocks.io_servicedescriptors.yaml | 1 + docs/developer_docs/api-reference/cluster.md | 8045 +++++++++- pkg/common/monitor.go | 8 +- pkg/common/monitor_test.go | 8 +- pkg/common/types.go | 6 +- pkg/configuration/config_manager/builder.go | 13 +- .../config_manager/builder_test.go | 9 +- .../config_manager/handler_util.go | 3 +- .../config_manager/handler_util_test.go | 26 +- pkg/configuration/config_manager/type.go | 10 +- pkg/configuration/core/config_util.go | 6 +- pkg/configuration/core/config_util_test.go | 20 +- pkg/configuration/core/type.go | 4 +- pkg/configuration/core/type_test.go | 3 +- pkg/controller/builder/builder_component.go | 37 +- .../builder/builder_component_definition.go | 59 +- .../builder/builder_configuration.go | 77 +- .../builder/builder_monitor_service_test.go | 7 +- pkg/controller/component/component.go | 57 +- pkg/controller/component/component_test.go | 18 +- pkg/controller/component/component_version.go | 9 +- pkg/controller/component/its_convertor.go | 33 +- pkg/controller/component/kbagent.go | 16 +- pkg/controller/component/kbagent_test.go | 18 +- pkg/controller/component/lifecycle/kbagent.go | 35 +- .../component/lifecycle/lfa_component.go | 8 +- .../component/lifecycle/lfa_member.go | 3 +- .../component/lifecycle/lifecycle.go | 4 +- .../component/lifecycle/lifecycle_test.go | 25 +- .../component/service_descriptor_utils.go | 21 +- .../service_descriptor_utils_test.go | 67 +- .../component/synthesize_component.go | 123 +- .../component/synthesize_component_test.go | 76 +- pkg/controller/component/type.go | 52 +- pkg/controller/component/utils.go | 8 +- pkg/controller/component/vars.go | 119 +- pkg/controller/component/vars_test.go | 180 +- pkg/controller/component/workload_utils.go | 5 +- .../configuration/annotation_utils.go | 4 +- pkg/controller/configuration/config_utils.go | 9 +- .../configuration/configuration_test.go | 11 +- pkg/controller/configuration/envfrom_utils.go | 30 +- .../configuration/envfrom_utils_test.go | 3 +- pkg/controller/configuration/operator.go | 13 +- pkg/controller/configuration/operator_test.go | 5 +- pkg/controller/configuration/patch_merger.go | 5 +- pkg/controller/configuration/pipeline.go | 11 +- pkg/controller/configuration/pipeline_test.go | 5 +- .../configuration/resource_wrapper.go | 15 +- .../configuration/template_merger.go | 9 +- .../configuration/template_merger_test.go | 7 +- .../configuration/template_wrapper.go | 27 +- .../configuration/template_wrapper_test.go | 5 +- .../configuration/tool_image_builder_test.go | 3 +- pkg/controller/factory/builder.go | 9 +- pkg/controller/factory/builder_test.go | 13 +- pkg/controller/plan/prepare.go | 3 +- pkg/controller/plan/prepare_test.go | 5 +- pkg/controller/plan/restore.go | 21 +- pkg/controller/plan/restore_test.go | 9 +- pkg/controller/plan/tls_utils.go | 4 +- pkg/controller/scheduling/scheduling_utils.go | 29 +- pkg/controllerutil/sharding_utils.go | 5 +- pkg/controllerutil/volume_util.go | 6 +- pkg/generics/type.go | 4 +- .../apps/cluster_instance_set_test_util.go | 5 +- pkg/testutil/apps/component_factory.go | 32 +- pkg/testutil/apps/component_util.go | 19 +- .../apps/componentdefinition_factory.go | 72 +- pkg/testutil/apps/constant.go | 47 +- 130 files changed, 54203 insertions(+), 1932 deletions(-) diff --git a/apis/apps/v1/component_types.go b/apis/apps/v1/component_types.go index 3032f978020..2fb524224b6 100644 --- a/apis/apps/v1/component_types.go +++ b/apis/apps/v1/component_types.go @@ -20,7 +20,9 @@ along with this program. If not, see . package v1 import ( + corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/intstr" ) // +genclient @@ -68,15 +70,277 @@ func init() { // ComponentSpec defines the desired state of Component type ComponentSpec struct { - // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster - // Important: Run "make" to regenerate code after modifying this file + // Specifies the name of the referenced ComponentDefinition. + // + // +kubebuilder:validation:Required + // +kubebuilder:validation:MaxLength=64 + CompDef string `json:"compDef"` - // Foo is an example field of Component. Edit component_types.go to remove/update - Foo string `json:"foo,omitempty"` + // ServiceVersion specifies the version of the Service expected to be provisioned by this Component. + // The version should follow the syntax and semantics of the "Semantic Versioning" specification (http://semver.org/). + // + // +kubebuilder:validation:MaxLength=32 + // +optional + ServiceVersion string `json:"serviceVersion,omitempty"` + + // Defines a list of ServiceRef for a Component, enabling access to both external services and + // Services provided by other Clusters. + // + // Types of services: + // + // - External services: Not managed by KubeBlocks or managed by a different KubeBlocks operator; + // Require a ServiceDescriptor for connection details. + // - Services provided by a Cluster: Managed by the same KubeBlocks operator; + // identified using Cluster, Component and Service names. + // + // ServiceRefs with identical `serviceRef.name` in the same Cluster are considered the same. + // + // Example: + // ```yaml + // serviceRefs: + // - name: "redis-sentinel" + // serviceDescriptor: + // name: "external-redis-sentinel" + // - name: "postgres-cluster" + // clusterServiceSelector: + // cluster: "my-postgres-cluster" + // service: + // component: "postgresql" + // ``` + // The example above includes ServiceRefs to an external Redis Sentinel service and a PostgreSQL Cluster. + // + // +optional + ServiceRefs []ServiceRef `json:"serviceRefs,omitempty"` + + // Specifies Labels to override or add for underlying Pods. + // + // +optional + Labels map[string]string `json:"labels,omitempty"` + + // Specifies Annotations to override or add for underlying Pods. + // + // +optional + Annotations map[string]string `json:"annotations,omitempty"` + + // List of environment variables to add. + // + // +optional + Env []corev1.EnvVar `json:"env,omitempty"` + + // Specifies the resources required by the Component. + // It allows defining the CPU, memory requirements and limits for the Component's containers. + // + // +kubebuilder:pruning:PreserveUnknownFields + // +optional + Resources corev1.ResourceRequirements `json:"resources,omitempty"` + + // Specifies a list of PersistentVolumeClaim templates that define the storage requirements for the Component. + // Each template specifies the desired characteristics of a persistent volume, such as storage class, + // size, and access modes. + // These templates are used to dynamically provision persistent volumes for the Component. + // + // +optional + // +patchMergeKey=name + // +patchStrategy=merge,retainKeys + VolumeClaimTemplates []ClusterComponentVolumeClaimTemplate `json:"volumeClaimTemplates,omitempty" patchStrategy:"merge,retainKeys" patchMergeKey:"name"` + + // List of volumes to override. + // + // +optional + Volumes []corev1.Volume `json:"volumes,omitempty"` + + // Overrides Services defined in referenced ComponentDefinition and exposes endpoints that can be accessed + // by clients. + // + // +optional + Services []ComponentService `json:"services,omitempty"` + + // Overrides system accounts defined in referenced ComponentDefinition. + // + // +optional + SystemAccounts []ComponentSystemAccount `json:"systemAccounts,omitempty"` + + // Specifies the desired number of replicas in the Component for enhancing availability and durability, or load balancing. + // + // +kubebuilder:validation:Required + // +kubebuilder:validation:Minimum=0 + // +kubebuilder:default=1 + Replicas int32 `json:"replicas"` + + // Specifies the configuration content of a config template. + // + // +optional + Configs []ClusterComponentConfig `json:"configs,omitempty"` + + // Specifies which types of logs should be collected for the Cluster. + // The log types are defined in the `componentDefinition.spec.logConfigs` field with the LogConfig entries. + // + // The elements in the `enabledLogs` array correspond to the names of the LogConfig entries. + // For example, if the `componentDefinition.spec.logConfigs` defines LogConfig entries with + // names "slow_query_log" and "error_log", + // you can enable the collection of these logs by including their names in the `enabledLogs` array: + // ```yaml + // enabledLogs: + // - slow_query_log + // - error_log + // ``` + // + // +listType=set + // +optional + EnabledLogs []string `json:"enabledLogs,omitempty"` + + // Specifies the name of the ServiceAccount required by the running Component. + // This ServiceAccount is used to grant necessary permissions for the Component's Pods to interact + // with other Kubernetes resources, such as modifying Pod labels or sending events. + // + // Defaults: + // If not specified, KubeBlocks automatically assigns a default ServiceAccount named "kb-{cluster.name}", + // bound to a default role defined during KubeBlocks installation. + // + // Future Changes: + // Future versions might change the default ServiceAccount creation strategy to one per Component, + // potentially revising the naming to "kb-{cluster.name}-{component.name}". + // + // Users can override the automatic ServiceAccount assignment by explicitly setting the name of + // an existed ServiceAccount in this field. + // + // +optional + ServiceAccountName string `json:"serviceAccountName,omitempty"` + + // Controls the concurrency of pods during initial scale up, when replacing pods on nodes, + // or when scaling down. It only used when `PodManagementPolicy` is set to `Parallel`. + // The default Concurrency is 100%. + // + // +optional + ParallelPodManagementConcurrency *intstr.IntOrString `json:"parallelPodManagementConcurrency,omitempty"` + + // PodUpdatePolicy indicates how pods should be updated + // + // - `StrictInPlace` indicates that only allows in-place upgrades. + // Any attempt to modify other fields will be rejected. + // - `PreferInPlace` indicates that we will first attempt an in-place upgrade of the Pod. + // If that fails, it will fall back to the ReCreate, where pod will be recreated. + // Default value is "PreferInPlace" + // + // +optional + PodUpdatePolicy *PodUpdatePolicyType `json:"podUpdatePolicy,omitempty"` + + // Specifies the scheduling policy for the Component. + // + // +optional + SchedulingPolicy *SchedulingPolicy `json:"schedulingPolicy,omitempty"` + + // Specifies the TLS configuration for the Component, including: + // + // - A boolean flag that indicates whether the Component should use Transport Layer Security (TLS) for secure communication. + // - An optional field that specifies the configuration for the TLS certificates issuer when TLS is enabled. + // It allows defining the issuer name and the reference to the secret containing the TLS certificates and key. + // The secret should contain the CA certificate, TLS certificate, and private key in the specified keys. + // + // +optional + TLSConfig *TLSConfig `json:"tlsConfig,omitempty"` + + // Allows for the customization of configuration values for each instance within a Component. + // An Instance represent a single replica (Pod and associated K8s resources like PVCs, Services, and ConfigMaps). + // While instances typically share a common configuration as defined in the ClusterComponentSpec, + // they can require unique settings in various scenarios: + // + // For example: + // - A database Component might require different resource allocations for primary and secondary instances, + // with primaries needing more resources. + // - During a rolling upgrade, a Component may first update the image for one or a few instances, + // and then update the remaining instances after verifying that the updated instances are functioning correctly. + // + // InstanceTemplate allows for specifying these unique configurations per instance. + // Each instance's name is constructed using the pattern: $(component.name)-$(template.name)-$(ordinal), + // starting with an ordinal of 0. + // It is crucial to maintain unique names for each InstanceTemplate to avoid conflicts. + // + // The sum of replicas across all InstanceTemplates should not exceed the total number of Replicas specified for the Component. + // Any remaining replicas will be generated using the default template and will follow the default naming rules. + // + // +optional + Instances []InstanceTemplate `json:"instances,omitempty" patchStrategy:"merge,retainKeys" patchMergeKey:"name"` + + // Specifies the names of instances to be transitioned to offline status. + // + // Marking an instance as offline results in the following: + // + // 1. The associated Pod is stopped, and its PersistentVolumeClaim (PVC) is retained for potential + // future reuse or data recovery, but it is no longer actively used. + // 2. The ordinal number assigned to this instance is preserved, ensuring it remains unique + // and avoiding conflicts with new instances. + // + // Setting instances to offline allows for a controlled scale-in process, preserving their data and maintaining + // ordinal consistency within the Cluster. + // Note that offline instances and their associated resources, such as PVCs, are not automatically deleted. + // The administrator must manually manage the cleanup and removal of these resources when they are no longer needed. + // + // + // +optional + OfflineInstances []string `json:"offlineInstances,omitempty"` + + // Defines runtimeClassName for all Pods managed by this Component. + // +optional + RuntimeClassName *string `json:"runtimeClassName,omitempty"` + + // Determines whether metrics exporter information is annotated on the Component's headless Service. + // + // If set to true, the following annotations will not be patched into the Service: + // + // - "monitor.kubeblocks.io/path" + // - "monitor.kubeblocks.io/port" + // - "monitor.kubeblocks.io/scheme" + // + // These annotations allow the Prometheus installed by KubeBlocks to discover and scrape metrics from the exporter. + // + // +optional + DisableExporter *bool `json:"disableExporter,omitempty"` + + // Stop the Component. + // If set, all the computing resources will be released. + // + // +optional + Stop *bool `json:"stop,omitempty"` } -// ComponentStatus defines the observed state of Component +// ComponentStatus represents the observed state of a Component within the Cluster. type ComponentStatus struct { - // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster - // Important: Run "make" to regenerate code after modifying this file + // Specifies the most recent generation observed for this Component object. + // + // +optional + ObservedGeneration int64 `json:"observedGeneration,omitempty"` + + // Represents a list of detailed status of the Component object. + // Each condition in the list provides real-time information about certain aspect of the Component object. + // + // This field is crucial for administrators and developers to monitor and respond to changes within the Component. + // It provides a history of state transitions and a snapshot of the current state that can be used for + // automated logic or direct inspection. + // + // +optional + Conditions []metav1.Condition `json:"conditions,omitempty"` + + // Indicates the current phase of the Component, with each phase indicating specific conditions: + // + // - Creating: The initial phase for new Components, transitioning from 'empty'(""). + // - Running: All Pods in a Running state. + // - Updating: The Component is currently being updated, with no failed Pods present. + // - Abnormal: Some Pods have failed, indicating a potentially unstable state. + // However, the cluster remains available as long as a quorum of members is functioning. + // - Failed: A significant number of Pods or critical Pods have failed + // The cluster may be non-functional or may offer only limited services (e.g, read-only). + // - Stopping: All Pods are being terminated, with current replica count at zero. + // - Stopped: All associated Pods have been successfully deleted. + // - Deleting: The Component is being deleted. + Phase ClusterComponentPhase `json:"phase,omitempty"` + + // A map that stores detailed message about the Component. + // Each entry in the map provides insights into specific elements of the Component, such as Pods or workloads. + // + // Keys in this map are formatted as `ObjectKind/Name`, where `ObjectKind` could be a type like Pod, + // and `Name` is the specific name of the object. + // + // +optional + Message map[string]string `json:"message,omitempty"` } diff --git a/apis/apps/v1/componentdefinition_types.go b/apis/apps/v1/componentdefinition_types.go index 4bfa6ca0805..e435373150f 100644 --- a/apis/apps/v1/componentdefinition_types.go +++ b/apis/apps/v1/componentdefinition_types.go @@ -20,6 +20,11 @@ along with this program. If not, see . package v1 import ( + "time" + + appsv1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" + rbacv1 "k8s.io/api/rbac/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -80,17 +85,1786 @@ func init() { SchemeBuilder.Register(&ComponentDefinition{}, &ComponentDefinitionList{}) } -// ComponentDefinitionSpec defines the desired state of ComponentDefinition type ComponentDefinitionSpec struct { - // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster - // Important: Run "make" to regenerate code after modifying this file + // Specifies the name of the Component provider, typically the vendor or developer name. + // It identifies the entity responsible for creating and maintaining the Component. + // + // When specifying the provider name, consider the following guidelines: + // + // - Keep the name concise and relevant to the Component. + // - Use a consistent naming convention across Components from the same provider. + // - Avoid using trademarked or copyrighted names without proper permission. + // + // +kubebuilder:validation:MaxLength=32 + // +optional + Provider string `json:"provider,omitempty"` + + // Provides a brief and concise explanation of the Component's purpose, functionality, and any relevant details. + // It serves as a quick reference for users to understand the Component's role and characteristics. + // + // +kubebuilder:validation:MaxLength=256 + // +optional + Description string `json:"description,omitempty"` + + // Defines the type of well-known service protocol that the Component provides. + // It specifies the standard or widely recognized protocol used by the Component to offer its Services. + // + // The `serviceKind` field allows users to quickly identify the type of Service provided by the Component + // based on common protocols or service types. This information helps in understanding the compatibility, + // interoperability, and usage of the Component within a system. + // + // Some examples of well-known service protocols include: + // + // - "MySQL": Indicates that the Component provides a MySQL database service. + // - "PostgreSQL": Indicates that the Component offers a PostgreSQL database service. + // - "Redis": Signifies that the Component functions as a Redis key-value store. + // - "ETCD": Denotes that the Component serves as an ETCD distributed key-value store. + // + // The `serviceKind` value is case-insensitive, allowing for flexibility in specifying the protocol name. + // + // When specifying the `serviceKind`, consider the following guidelines: + // + // - Use well-established and widely recognized protocol names or service types. + // - Ensure that the `serviceKind` accurately represents the primary service type offered by the Component. + // - If the Component provides multiple services, choose the most prominent or commonly used protocol. + // - Limit the `serviceKind` to a maximum of 32 characters for conciseness and readability. + // + // Note: The `serviceKind` field is optional and can be left empty if the Component does not fit into a well-known + // service category or if the protocol is not widely recognized. It is primarily used to convey information about + // the Component's service type to users and facilitate discovery and integration. + // + // The `serviceKind` field is immutable and cannot be updated. + // + // +kubebuilder:validation:MaxLength=32 + // +optional + ServiceKind string `json:"serviceKind,omitempty"` + + // Specifies the version of the Service provided by the Component. + // It follows the syntax and semantics of the "Semantic Versioning" specification (http://semver.org/). + // + // The Semantic Versioning specification defines a version number format of X.Y.Z (MAJOR.MINOR.PATCH), where: + // + // - X represents the major version and indicates incompatible API changes. + // - Y represents the minor version and indicates added functionality in a backward-compatible manner. + // - Z represents the patch version and indicates backward-compatible bug fixes. + // + // Additional labels for pre-release and build metadata are available as extensions to the X.Y.Z format: + // + // - Use pre-release labels (e.g., -alpha, -beta) for versions that are not yet stable or ready for production use. + // - Use build metadata (e.g., +build.1) for additional version information if needed. + // + // Examples of valid ServiceVersion values: + // + // - "1.0.0" + // - "2.3.1" + // - "3.0.0-alpha.1" + // - "4.5.2+build.1" + // + // The `serviceVersion` field is immutable and cannot be updated. + // + // +kubebuilder:validation:MaxLength=32 + // +optional + ServiceVersion string `json:"serviceVersion,omitempty"` + + // Specifies static labels that will be patched to all Kubernetes resources created for the Component. + // + // Note: If a label key in the `labels` field conflicts with any system labels or user-specified labels, + // it will be silently ignored to avoid overriding higher-priority labels. + // + // This field is immutable. + // + // +optional + Labels map[string]string `json:"labels,omitempty"` + + // Specifies static annotations that will be patched to all Kubernetes resources created for the Component. + // + // Note: If an annotation key in the `annotations` field conflicts with any system annotations + // or user-specified annotations, it will be silently ignored to avoid overriding higher-priority annotations. + // + // This field is immutable. + // + // +optional + Annotations map[string]string `json:"annotations,omitempty"` + + // Specifies the PodSpec template used in the Component. + // It includes the following elements: + // + // - Init containers + // - Containers + // - Image + // - Commands + // - Args + // - Envs + // - Mounts + // - Ports + // - Security context + // - Probes + // - Lifecycle + // - Volumes + // + // This field is intended to define static settings that remain consistent across all instantiated Components. + // Dynamic settings such as CPU and memory resource limits, as well as scheduling settings (affinity, + // toleration, priority), may vary among different instantiated Components. + // They should be specified in the `cluster.spec.componentSpecs` (ClusterComponentSpec). + // + // Specific instances of a Component may override settings defined here, such as using a different container image + // or modifying environment variable values. + // These instance-specific overrides can be specified in `cluster.spec.componentSpecs[*].instances`. + // + // This field is immutable and cannot be updated once set. + // + // +kubebuilder:pruning:PreserveUnknownFields + // +kubebuilder:validation:Required + Runtime corev1.PodSpec `json:"runtime"` + + // Defines variables which are determined after Cluster instantiation and reflect + // dynamic or runtime attributes of instantiated Clusters. + // These variables serve as placeholders for setting environment variables in Pods and Actions, + // or for rendering configuration and script templates before actual values are finalized. + // + // These variables are placed in front of the environment variables declared in the Pod if used as + // environment variables. + // + // Variable values can be sourced from: + // + // - ConfigMap: Select and extract a value from a specific key within a ConfigMap. + // - Secret: Select and extract a value from a specific key within a Secret. + // - HostNetwork: Retrieves values (including ports) from host-network resources. + // - Service: Retrieves values (including address, port, NodePort) from a selected Service. + // Intended to obtain the address of a ComponentService within the same Cluster. + // - Credential: Retrieves account name and password from a SystemAccount variable. + // - ServiceRef: Retrieves address, port, account name and password from a selected ServiceRefDeclaration. + // Designed to obtain the address bound to a ServiceRef, such as a ClusterService or + // ComponentService of another cluster or an external service. + // - Component: Retrieves values from a selected Component, including replicas and instance name list. + // + // This field is immutable. + // + // +optional + Vars []EnvVar `json:"vars,omitempty"` + + // Defines the volumes used by the Component and some static attributes of the volumes. + // After defining the volumes here, user can reference them in the + // `cluster.spec.componentSpecs[*].volumeClaimTemplates` field to configure dynamic properties such as + // volume capacity and storage class. + // + // This field allows you to specify the following: + // + // - Snapshot behavior: Determines whether a snapshot of the volume should be taken when performing + // a snapshot backup of the Component. + // - Disk high watermark: Sets the high watermark for the volume's disk usage. + // When the disk usage reaches the specified threshold, it triggers an alert or action. + // + // By configuring these volume behaviors, you can control how the volumes are managed and monitored within the Component. + // + // This field is immutable. + // + // +optional + Volumes []ComponentVolume `json:"volumes"` + + // Specifies the host network configuration for the Component. + // + // When `hostNetwork` option is enabled, the Pods share the host's network namespace and can directly access + // the host's network interfaces. + // This means that if multiple Pods need to use the same port, they cannot run on the same host simultaneously + // due to port conflicts. + // + // The DNSPolicy field in the Pod spec determines how containers within the Pod perform DNS resolution. + // When using hostNetwork, the operator will set the DNSPolicy to 'ClusterFirstWithHostNet'. + // With this policy, DNS queries will first go through the K8s cluster's DNS service. + // If the query fails, it will fall back to the host's DNS settings. + // + // If set, the DNS policy will be automatically set to "ClusterFirstWithHostNet". + // + // This field is immutable. + // + // +optional + HostNetwork *HostNetwork `json:"hostNetwork,omitempty"` + + // Defines additional Services to expose the Component's endpoints. + // + // A default headless Service, named `{cluster.name}-{component.name}-headless`, is automatically created + // for internal Cluster communication. + // + // This field enables customization of additional Services to expose the Component's endpoints to + // other Components within the same or different Clusters, and to external applications. + // Each Service entry in this list can include properties such as ports, type, and selectors. + // + // - For intra-Cluster access, Components can reference Services using variables declared in + // `componentDefinition.spec.vars[*].valueFrom.serviceVarRef`. + // - For inter-Cluster access, reference Services use variables declared in + // `componentDefinition.spec.vars[*].valueFrom.serviceRefVarRef`, + // and bind Services at Cluster creation time with `clusterComponentSpec.ServiceRef[*].clusterServiceSelector`. + // + // This field is immutable. + // + // +optional + Services []ComponentService `json:"services,omitempty"` + + // Specifies the configuration file templates and volume mount parameters used by the Component. + // It also includes descriptions of the parameters in the ConfigMaps, such as value range limitations. + // + // This field specifies a list of templates that will be rendered into Component containers' configuration files. + // Each template is represented as a ConfigMap and may contain multiple configuration files, + // with each file being a key in the ConfigMap. + // + // The rendered configuration files will be mounted into the Component's containers + // according to the specified volume mount parameters. + // + // This field is immutable. + // + // +patchMergeKey=name + // +patchStrategy=merge,retainKeys + // +listType=map + // +listMapKey=name + // +optional + Configs []ComponentConfigSpec `json:"configs,omitempty"` + + // Defines the types of logs generated by instances of the Component and their corresponding file paths. + // These logs can be collected for further analysis and monitoring. + // + // The `logConfigs` field is an optional list of LogConfig objects, where each object represents + // a specific log type and its configuration. + // It allows you to specify multiple log types and their respective file paths for the Component. + // + // Examples: + // + // ```yaml + // logConfigs: + // - filePathPattern: /data/mysql/log/mysqld-error.log + // name: error + // - filePathPattern: /data/mysql/log/mysqld.log + // name: general + // - filePathPattern: /data/mysql/log/mysqld-slowquery.log + // name: slow + // ``` + // + // This field is immutable. + // + // +patchMergeKey=name + // +patchStrategy=merge,retainKeys + // +listType=map + // +listMapKey=name + // +optional + LogConfigs []LogConfig `json:"logConfigs,omitempty" patchStrategy:"merge,retainKeys" patchMergeKey:"name"` + + // Specifies groups of scripts, each provided via a ConfigMap, to be mounted as volumes in the container. + // These scripts can be executed during container startup or via specific actions. + // + // Each script group is encapsulated in a ComponentTemplateSpec that includes: + // + // - The ConfigMap containing the scripts. + // - The mount point where the scripts will be mounted inside the container. + // + // This field is immutable. + // + // +patchMergeKey=name + // +patchStrategy=merge,retainKeys + // +listType=map + // +listMapKey=name + // +optional + Scripts []ComponentTemplateSpec `json:"scripts,omitempty"` + + // An array of `SystemAccount` objects that define the system accounts needed + // for the management operations of the Component. + // + // Each `SystemAccount` includes: + // + // - Account name. + // - The SQL statement template: Used to create the system account. + // - Password Source: Either generated based on certain rules or retrieved from a Secret. + // + // Use cases for system accounts typically involve tasks like system initialization, backups, monitoring, + // health checks, replication, and other system-level operations. + // + // System accounts are distinct from user accounts, although both are database accounts. + // + // - **System Accounts**: Created during Cluster setup by the KubeBlocks operator, + // these accounts have higher privileges for system management and are fully managed + // through a declarative API by the operator. + // - **User Accounts**: Managed by users or administrator. + // User account permissions should follow the principle of least privilege, + // granting only the necessary access rights to complete their required tasks. + // + // This field is immutable. + // + // +optional + SystemAccounts []SystemAccount `json:"systemAccounts,omitempty"` + + // Defines the upper limit of the number of replicas supported by the Component. + // + // It defines the maximum number of replicas that can be created for the Component. + // This field allows you to set a limit on the scalability of the Component, preventing it from exceeding a certain number of replicas. + // + // This field is immutable. + // + // +optional + ReplicasLimit *ReplicasLimit `json:"replicasLimit,omitempty"` - // Foo is an example field of ComponentDefinition. Edit componentdefinition_types.go to remove/update - Foo string `json:"foo,omitempty"` + // Enumerate all possible roles assigned to each replica of the Component, influencing its behavior. + // + // A replica can have zero to multiple roles. + // KubeBlocks operator determines the roles of each replica by invoking the `lifecycleActions.roleProbe` method. + // This action returns a list of roles for each replica, and the returned roles must be predefined in the `roles` field. + // + // The roles assigned to a replica can influence various aspects of the Component's behavior, such as: + // + // - Service selection: The Component's exposed Services may target replicas based on their roles using `roleSelector`. + // - Update order: The roles can determine the order in which replicas are updated during a Component update. + // For instance, replicas with a "follower" role can be updated first, while the replica with the "leader" + // role is updated last. This helps minimize the number of leader changes during the update process. + // + // This field is immutable. + // + // +optional + Roles []ReplicaRole `json:"roles,omitempty"` + + // `minReadySeconds` is the minimum duration in seconds that a new Pod should remain in the ready + // state without any of its containers crashing to be considered available. + // This ensures the Pod's stability and readiness to serve requests. + // + // A default value of 0 seconds means the Pod is considered available as soon as it enters the ready state. + // + // +kubebuilder:validation:Minimum=0 + // +kubebuilder:default=0 + // +optional + MinReadySeconds int32 `json:"minReadySeconds,omitempty"` + + // Specifies the concurrency strategy for updating multiple instances of the Component. + // Available strategies: + // + // - `Serial`: Updates replicas one at a time, ensuring minimal downtime by waiting for each replica to become ready + // before updating the next. + // - `Parallel`: Updates all replicas simultaneously, optimizing for speed but potentially reducing availability + // during the update. + // - `BestEffortParallel`: Updates replicas concurrently with a limit on simultaneous updates to ensure a minimum + // number of operational replicas for maintaining quorum. + // For example, in a 5-replica component, updating a maximum of 2 replicas simultaneously keeps + // at least 3 operational for quorum. + // + // This field is immutable and defaults to 'Serial'. + // + // +kubebuilder:default=Serial + // +optional + UpdateStrategy *UpdateStrategy `json:"updateStrategy,omitempty"` + + // InstanceSet controls the creation of pods during initial scale up, replacement of pods on nodes, and scaling down. + // + // - `OrderedReady`: Creates pods in increasing order (pod-0, then pod-1, etc). The controller waits until each pod + // is ready before continuing. Pods are removed in reverse order when scaling down. + // - `Parallel`: Creates pods in parallel to match the desired scale without waiting. All pods are deleted at once + // when scaling down. + // + // +optional + PodManagementPolicy *appsv1.PodManagementPolicyType `json:"podManagementPolicy,omitempty"` + + // Defines the namespaced policy rules required by the Component. + // + // The `policyRules` field is an array of `rbacv1.PolicyRule` objects that define the policy rules + // needed by the Component to operate within a namespace. + // These policy rules determine the permissions and verbs the Component is allowed to perform on + // Kubernetes resources within the namespace. + // + // The purpose of this field is to automatically generate the necessary RBAC roles + // for the Component based on the specified policy rules. + // This ensures that the Pods in the Component has appropriate permissions to function. + // + // Note: This field is currently non-functional and is reserved for future implementation. + // + // This field is immutable. + // + // +optional + PolicyRules []rbacv1.PolicyRule `json:"policyRules,omitempty"` + + // Defines a set of hooks and procedures that customize the behavior of a Component throughout its lifecycle. + // Actions are triggered at specific lifecycle stages: + // + // - `postProvision`: Defines the hook to be executed after the creation of a Component, + // with `preCondition` specifying when the action should be fired relative to the Component's lifecycle stages: + // `Immediately`, `RuntimeReady`, `ComponentReady`, and `ClusterReady`. + // - `preTerminate`: Defines the hook to be executed before terminating a Component. + // - `roleProbe`: Defines the procedure which is invoked regularly to assess the role of replicas. + // - `switchover`: Defines the procedure for a controlled transition of leadership from the current leader to a new replica. + // This approach aims to minimize downtime and maintain availability in systems with a leader-follower topology, + // such as before planned maintenance or upgrades on the current leader node. + // - `memberJoin`: Defines the procedure to add a new replica to the replication group. + // - `memberLeave`: Defines the method to remove a replica from the replication group. + // - `readOnly`: Defines the procedure to switch a replica into the read-only state. + // - `readWrite`: transition a replica from the read-only state back to the read-write state. + // - `dataDump`: Defines the procedure to export the data from a replica. + // - `dataLoad`: Defines the procedure to import data into a replica. + // - `reconfigure`: Defines the procedure that update a replica with new configuration file. + // - `accountProvision`: Defines the procedure to generate a new database account. + // + // This field is immutable. + // + // +optional + LifecycleActions *ComponentLifecycleActions `json:"lifecycleActions,omitempty"` + + // Lists external service dependencies of the Component, including services from other Clusters or outside the K8s environment. + // + // This field is immutable. + // + // +optional + ServiceRefDeclarations []ServiceRefDeclaration `json:"serviceRefDeclarations,omitempty"` + + // Defines the built-in metrics exporter container. + // + // +optional + Exporter *Exporter `json:"exporter,omitempty"` } -// ComponentDefinitionStatus defines the observed state of ComponentDefinition +// ComponentDefinitionStatus defines the observed state of ComponentDefinition. type ComponentDefinitionStatus struct { - // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster - // Important: Run "make" to regenerate code after modifying this file + // Refers to the most recent generation that has been observed for the ComponentDefinition. + // + // +optional + ObservedGeneration int64 `json:"observedGeneration,omitempty"` + + // Represents the current status of the ComponentDefinition. Valid values include ``, `Available`, and `Unavailable`. + // When the status is `Available`, the ComponentDefinition is ready and can be utilized by related objects. + // + // +optional + Phase Phase `json:"phase,omitempty"` + + // Provides additional information about the current phase. + // + // +optional + Message string `json:"message,omitempty"` +} + +// EnvVar represents a variable present in the env of Pod/Action or the template of config/script. +type EnvVar struct { + // Name of the variable. Must be a C_IDENTIFIER. + // + // +kubebuilder:validation:Required + Name string `json:"name"` + + // Optional: no more than one of the following may be specified. + + // Variable references `$(VAR_NAME)` are expanded using the previously defined variables in the current context. + // + // If a variable cannot be resolved, the reference in the input string will be unchanged. + // Double `$$` are reduced to a single `$`, which allows for escaping the `$(VAR_NAME)` syntax: i.e. + // + // - `$$(VAR_NAME)` will produce the string literal `$(VAR_NAME)`. + // + // Escaped references will never be expanded, regardless of whether the variable exists or not. + // Defaults to "". + // + // +optional + Value string `json:"value,omitempty"` + + // Source for the variable's value. Cannot be used if value is not empty. + // + // +optional + ValueFrom *VarSource `json:"valueFrom,omitempty"` + + // A Go template expression that will be applied to the resolved value of the var. + // + // The expression will only be evaluated if the var is successfully resolved to a non-credential value. + // + // The resolved value can be accessed by its name within the expression, system vars and other user-defined + // non-credential vars can be used within the expression in the same way. + // Notice that, when accessing vars by its name, you should replace all the "-" in the name with "_", because of + // that "-" is not a valid identifier in Go. + // + // All expressions are evaluated in the order the vars are defined. If a var depends on any vars that also + // have expressions defined, be careful about the evaluation order as it may use intermediate values. + // + // The result of evaluation will be used as the final value of the var. If the expression fails to evaluate, + // the resolving of var will also be considered failed. + // + // +optional + Expression *string `json:"expression,omitempty"` +} + +// VarSource represents a source for the value of an EnvVar. +type VarSource struct { + // Selects a key of a ConfigMap. + // +optional + ConfigMapKeyRef *corev1.ConfigMapKeySelector `json:"configMapKeyRef,omitempty"` + + // Selects a key of a Secret. + // +optional + SecretKeyRef *corev1.SecretKeySelector `json:"secretKeyRef,omitempty"` + + // Selects a defined var of host-network resources. + // +optional + HostNetworkVarRef *HostNetworkVarSelector `json:"hostNetworkVarRef,omitempty"` + + // Selects a defined var of a Service. + // +optional + ServiceVarRef *ServiceVarSelector `json:"serviceVarRef,omitempty"` + + // Selects a defined var of a Credential (SystemAccount). + // +optional + CredentialVarRef *CredentialVarSelector `json:"credentialVarRef,omitempty"` + + // Selects a defined var of a ServiceRef. + // +optional + ServiceRefVarRef *ServiceRefVarSelector `json:"serviceRefVarRef,omitempty"` + + // Selects a defined var of a Component. + // +optional + ComponentVarRef *ComponentVarSelector `json:"componentVarRef,omitempty"` + + // Selects a defined var of a Cluster. + // +optional + ClusterVarRef *ClusterVarSelector `json:"clusterVarRef,omitempty"` +} + +// VarOption defines whether a variable is required or optional. +// +enum +// +kubebuilder:validation:Enum={Required,Optional} +type VarOption string + +var ( + VarRequired VarOption = "Required" + VarOptional VarOption = "Optional" +) + +type NamedVar struct { + // +optional + Name string `json:"name,omitempty"` + + // +optional + Option *VarOption `json:"option,omitempty"` +} + +type RoledVar struct { + // +optional + Role string `json:"role,omitempty"` + + // +optional + Option *VarOption `json:"option,omitempty"` +} + +// ContainerVars defines the vars that can be referenced from a Container. +type ContainerVars struct { + // The name of the container. + // + // +kubebuilder:validation:Required + Name string `json:"name"` + + // Container port to reference. + // + // +optional + Port *NamedVar `json:"port,omitempty"` +} + +// HostNetworkVars defines the vars that can be referenced from host-network resources. +type HostNetworkVars struct { + // +optional + Container *ContainerVars `json:"container,omitempty"` +} + +// ServiceVars defines the vars that can be referenced from a Service. +type ServiceVars struct { + // ServiceType references the type of the service. + // + // +optional + ServiceType *VarOption `json:"serviceType,omitempty"` + + // +optional + Host *VarOption `json:"host,omitempty"` + + // LoadBalancer represents the LoadBalancer ingress point of the service. + // + // If multiple ingress points are available, the first one will be used automatically, choosing between IP and Hostname. + // + // +optional + LoadBalancer *VarOption `json:"loadBalancer,omitempty"` + + // Port references a port or node-port defined in the service. + // + // If the referenced service is a pod-service, there will be multiple service objects matched, + // and the value will be presented in the following format: service1.name:port1,service2.name:port2... + // + // +optional + Port *NamedVar `json:"port,omitempty"` +} + +// CredentialVars defines the vars that can be referenced from a Credential (SystemAccount). +// !!!!! CredentialVars will only be used as environment variables for Pods & Actions, and will not be used to render the templates. +type CredentialVars struct { + // +optional + Username *VarOption `json:"username,omitempty"` + + // +optional + Password *VarOption `json:"password,omitempty"` +} + +// ServiceRefVars defines the vars that can be referenced from a ServiceRef. +type ServiceRefVars struct { + // +optional + Endpoint *VarOption `json:"endpoint,omitempty"` + + // +optional + Host *VarOption `json:"host,omitempty"` + + // +optional + Port *VarOption `json:"port,omitempty"` + + CredentialVars `json:",inline"` +} + +// HostNetworkVarSelector selects a var from host-network resources. +type HostNetworkVarSelector struct { + // The component to select from. + ClusterObjectReference `json:",inline"` + + HostNetworkVars `json:",inline"` +} + +// ServiceVarSelector selects a var from a Service. +type ServiceVarSelector struct { + // The Service to select from. + // It can be referenced from the default headless service by setting the name to "headless". + ClusterObjectReference `json:",inline"` + + ServiceVars `json:",inline"` +} + +// CredentialVarSelector selects a var from a Credential (SystemAccount). +type CredentialVarSelector struct { + // The Credential (SystemAccount) to select from. + ClusterObjectReference `json:",inline"` + + CredentialVars `json:",inline"` +} + +// ServiceRefVarSelector selects a var from a ServiceRefDeclaration. +type ServiceRefVarSelector struct { + // The ServiceRefDeclaration to select from. + ClusterObjectReference `json:",inline"` + + ServiceRefVars `json:",inline"` +} + +// ComponentVarSelector selects a var from a Component. +type ComponentVarSelector struct { + // The Component to select from. + ClusterObjectReference `json:",inline"` + + ComponentVars `json:",inline"` +} + +type ComponentVars struct { + // Reference to the name of the Component object. + // + // +optional + ComponentName *VarOption `json:"componentName,omitempty"` + + // Reference to the short name of the Component object. + // + // +optional + ShortName *VarOption `json:"shortName,omitempty"` + + // Reference to the replicas of the component. + // + // +optional + Replicas *VarOption `json:"replicas,omitempty"` + + // Reference to the pod name list of the component. + // and the value will be presented in the following format: name1,name2,... + // + // +optional + PodNames *VarOption `json:"podNames,omitempty"` + + // Reference to the pod FQDN list of the component. + // The value will be presented in the following format: FQDN1,FQDN2,... + // + // +optional + PodFQDNs *VarOption `json:"podFQDNs,omitempty"` + + // Reference to the pod name list of the component that have a specific role. + // The value will be presented in the following format: name1,name2,... + // + // +optional + PodNamesForRole *RoledVar `json:"podNamesForRole,omitempty"` + + // Reference to the pod FQDN list of the component that have a specific role. + // The value will be presented in the following format: FQDN1,FQDN2,... + // + // +optional + PodFQDNsForRole *RoledVar `json:"podFQDNsForRole,omitempty"` +} + +// ClusterVarSelector selects a var from a Cluster. +type ClusterVarSelector struct { + ClusterVars `json:",inline"` +} + +type ClusterVars struct { + // Reference to the namespace of the Cluster object. + // + // +optional + Namespace *VarOption `json:"namespace,omitempty"` + + // Reference to the name of the Cluster object. + // + // +optional + ClusterName *VarOption `json:"clusterName,omitempty"` + + // Reference to the UID of the Cluster object. + // + // +optional + ClusterUID *VarOption `json:"clusterUID,omitempty"` +} + +// ClusterObjectReference defines information to let you locate the referenced object inside the same Cluster. +type ClusterObjectReference struct { + // CompDef specifies the definition used by the component that the referent object resident in. + // If not specified, the component itself will be used. + // + // +optional + CompDef string `json:"compDef,omitempty"` + + // Name of the referent object. + // + // +optional + Name string `json:"name,omitempty"` + + // Specify whether the object must be defined. + // + // +optional + Optional *bool `json:"optional,omitempty"` + + // This option defines the behavior when multiple component objects match the specified @CompDef. + // If not provided, an error will be raised when handling multiple matches. + // + // +optional + MultipleClusterObjectOption *MultipleClusterObjectOption `json:"multipleClusterObjectOption,omitempty"` +} + +// MultipleClusterObjectOption defines the options for handling multiple cluster objects matched. +type MultipleClusterObjectOption struct { + // Define the strategy for handling multiple cluster objects. + // + // +kubebuilder:validation:Required + Strategy MultipleClusterObjectStrategy `json:"strategy"` + + // Define the options for handling combined variables. + // Valid only when the strategy is set to "combined". + // + // +optional + CombinedOption *MultipleClusterObjectCombinedOption `json:"combinedOption,omitempty"` +} + +// MultipleClusterObjectStrategy defines the strategy for handling multiple cluster objects. +// +enum +// +kubebuilder:validation:Enum={individual,combined} +type MultipleClusterObjectStrategy string + +const ( + // MultipleClusterObjectStrategyIndividual - each matched component will have its individual variable with its name + // as the suffix. + // This is required when referencing credential variables that cannot be passed by values. + MultipleClusterObjectStrategyIndividual MultipleClusterObjectStrategy = "individual" + + // MultipleClusterObjectStrategyCombined - the values from all matched components will be combined into a single + // variable using the specified option. + MultipleClusterObjectStrategyCombined MultipleClusterObjectStrategy = "combined" +) + +// MultipleClusterObjectCombinedOption defines options for handling combined variables. +type MultipleClusterObjectCombinedOption struct { + // If set, the existing variable will be kept, and a new variable will be defined with the specified suffix + // in pattern: $(var.name)_$(suffix). + // The new variable will be auto-created and placed behind the existing one. + // If not set, the existing variable will be reused with the value format defined below. + // + // +optional + NewVarSuffix *string `json:"newVarSuffix,omitempty"` + + // The format of the value that the operator will use to compose values from multiple components. + // + // +kubebuilder:default="Flatten" + // +optional + ValueFormat MultipleClusterObjectValueFormat `json:"valueFormat,omitempty"` + + // The flatten format, default is: $(comp-name-1):value,$(comp-name-2):value. + // + // +optional + FlattenFormat *MultipleClusterObjectValueFormatFlatten `json:"flattenFormat,omitempty"` +} + +// MultipleClusterObjectValueFormat defines the format details for the value. +type MultipleClusterObjectValueFormat string + +const ( + FlattenFormat MultipleClusterObjectValueFormat = "Flatten" +) + +// MultipleClusterObjectValueFormatFlatten defines the flatten format for the value. +type MultipleClusterObjectValueFormatFlatten struct { + // Pair delimiter. + // + // +kubebuilder:default="," + // +kubebuilder:validation:Required + Delimiter string `json:"delimiter"` + + // Key-value delimiter. + // + // +kubebuilder:default=":" + // +kubebuilder:validation:Required + KeyValueDelimiter string `json:"keyValueDelimiter"` +} + +type ComponentVolume struct { + // Specifies the name of the volume. + // It must be a DNS_LABEL and unique within the pod. + // More info can be found at: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + // Note: This field cannot be updated. + // + // +kubebuilder:validation:Required + Name string `json:"name"` + + // Specifies whether the creation of a snapshot of this volume is necessary when performing a backup of the Component. + // + // Note: This field cannot be updated. + // + // +kubebuilder:default=false + // +optional + NeedSnapshot bool `json:"needSnapshot,omitempty"` + + // Sets the critical threshold for volume space utilization as a percentage (0-100). + // + // Exceeding this percentage triggers the system to switch the volume to read-only mode as specified in + // `componentDefinition.spec.lifecycleActions.readOnly`. + // This precaution helps prevent space depletion while maintaining read-only access. + // If the space utilization later falls below this threshold, the system reverts the volume to read-write mode + // as defined in `componentDefinition.spec.lifecycleActions.readWrite`, restoring full functionality. + // + // Note: This field cannot be updated. + // + // +kubebuilder:validation:Maximum=100 + // +kubebuilder:validation:Minimum=0 + // +kubebuilder:default=0 + // +optional + HighWatermark int `json:"highWatermark,omitempty"` +} + +type HostNetwork struct { + // The list of container ports that are required by the component. + // + // +optional + ContainerPorts []HostNetworkContainerPort `json:"containerPorts,omitempty"` +} + +type HostNetworkContainerPort struct { + // Container specifies the target container within the Pod. + // + // +required + Container string `json:"container"` + + // Ports are named container ports within the specified container. + // These container ports must be defined in the container for proper port allocation. + // + // +kubebuilder:validation:MinItems=1 + // +required + Ports []string `json:"ports"` +} + +type ComponentTemplateSpec struct { + // Specifies the name of the configuration template. + // + // +kubebuilder:validation:Required + // +kubebuilder:validation:MaxLength=63 + // +kubebuilder:validation:Pattern:=`^[a-z0-9]([a-z0-9\.\-]*[a-z0-9])?$` + Name string `json:"name"` + + // Specifies the name of the referenced configuration template ConfigMap object. + // + // +kubebuilder:validation:MaxLength=63 + // +kubebuilder:validation:Pattern:=`^[a-z0-9]([a-z0-9\.\-]*[a-z0-9])?$` + // +optional + TemplateRef string `json:"templateRef"` + + // Specifies the namespace of the referenced configuration template ConfigMap object. + // An empty namespace is equivalent to the "default" namespace. + // + // +kubebuilder:validation:MaxLength=63 + // +kubebuilder:validation:Pattern:=`^[a-z0-9]([a-z0-9\-]*[a-z0-9])?$` + // +kubebuilder:default="default" + // +optional + Namespace string `json:"namespace,omitempty"` + + // Refers to the volume name of PodTemplate. The configuration file produced through the configuration + // template will be mounted to the corresponding volume. Must be a DNS_LABEL name. + // The volume name must be defined in podSpec.containers[*].volumeMounts. + // + // +kubebuilder:validation:Required + // +kubebuilder:validation:MaxLength=63 + // +kubebuilder:validation:Pattern:=`^[a-z]([a-z0-9\-]*[a-z0-9])?$` + VolumeName string `json:"volumeName"` + + // The operator attempts to set default file permissions for scripts (0555) and configurations (0444). + // However, certain database engines may require different file permissions. + // You can specify the desired file permissions here. + // + // Must be specified as an octal value between 0000 and 0777 (inclusive), + // or as a decimal value between 0 and 511 (inclusive). + // YAML supports both octal and decimal values for file permissions. + // + // Please note that this setting only affects the permissions of the files themselves. + // Directories within the specified path are not impacted by this setting. + // It's important to be aware that this setting might conflict with other options + // that influence the file mode, such as fsGroup. + // In such cases, the resulting file mode may have additional bits set. + // Refers to documents of k8s.ConfigMapVolumeSource.defaultMode for more information. + // + // +optional + DefaultMode *int32 `json:"defaultMode,omitempty" protobuf:"varint,3,opt,name=defaultMode"` } + +type ComponentConfigSpec struct { + ComponentTemplateSpec `json:",inline"` + + // Specifies the configuration files within the ConfigMap that support dynamic updates. + // + // A configuration template (provided in the form of a ConfigMap) may contain templates for multiple + // configuration files. + // Each configuration file corresponds to a key in the ConfigMap. + // Some of these configuration files may support dynamic modification and reloading without requiring + // a pod restart. + // + // If empty or omitted, all configuration files in the ConfigMap are assumed to support dynamic updates, + // and ConfigConstraint applies to all keys. + // + // +listType=set + // +optional + Keys []string `json:"keys,omitempty"` + + // Specifies the secondary rendered config spec for pod-specific customization. + // + // The template is rendered inside the pod (by the "config-manager" sidecar container) and merged with the main + // template's render result to generate the final configuration file. + // + // This field is intended to handle scenarios where different pods within the same Component have + // varying configurations. It allows for pod-specific customization of the configuration. + // + // Note: This field will be deprecated in future versions, and the functionality will be moved to + // `cluster.spec.componentSpecs[*].instances[*]`. + // + // +kubebuilder:deprecatedversion:warning="This field has been deprecated since 0.9.0 and will be removed in 0.10.0" + // +optional + LegacyRenderedConfigSpec *LegacyRenderedTemplateSpec `json:"legacyRenderedConfigSpec,omitempty"` + + // Specifies the name of the referenced configuration constraints object. + // + // +kubebuilder:validation:MaxLength=63 + // +kubebuilder:validation:Pattern:=`^[a-z0-9]([a-z0-9\.\-]*[a-z0-9])?$` + // +optional + ConfigConstraintRef string `json:"constraintRef,omitempty"` + + // Specifies the containers to inject the ConfigMap parameters as environment variables. + // + // This is useful when application images accept parameters through environment variables and + // generate the final configuration file in the startup script based on these variables. + // + // This field allows users to specify a list of container names, and KubeBlocks will inject the environment + // variables converted from the ConfigMap into these designated containers. This provides a flexible way to + // pass the configuration items from the ConfigMap to the container without modifying the image. + // + // Deprecated: `asEnvFrom` has been deprecated since 0.9.0 and will be removed in 0.10.0. + // Use `injectEnvTo` instead. + // + // +kubebuilder:deprecatedversion:warning="This field has been deprecated since 0.9.0 and will be removed in 0.10.0" + // +listType=set + // +optional + AsEnvFrom []string `json:"asEnvFrom,omitempty"` + + // Specifies the containers to inject the ConfigMap parameters as environment variables. + // + // This is useful when application images accept parameters through environment variables and + // generate the final configuration file in the startup script based on these variables. + // + // This field allows users to specify a list of container names, and KubeBlocks will inject the environment + // variables converted from the ConfigMap into these designated containers. This provides a flexible way to + // pass the configuration items from the ConfigMap to the container without modifying the image. + // + // + // +listType=set + // +optional + InjectEnvTo []string `json:"injectEnvTo,omitempty"` + + // Specifies whether the configuration needs to be re-rendered after v-scale or h-scale operations to reflect changes. + // + // In some scenarios, the configuration may need to be updated to reflect the changes in resource allocation + // or cluster topology. Examples: + // + // - Redis: adjust maxmemory after v-scale operation. + // - MySQL: increase max connections after v-scale operation. + // - Zookeeper: update zoo.cfg with new node addresses after h-scale operation. + // + // +listType=set + // +optional + ReRenderResourceTypes []RerenderResourceType `json:"reRenderResourceTypes,omitempty"` +} + +// LegacyRenderedTemplateSpec describes the configuration extension for the lazy rendered template. +// Deprecated: LegacyRenderedTemplateSpec has been deprecated since 0.9.0 and will be removed in 0.10.0 +type LegacyRenderedTemplateSpec struct { + // Extends the configuration template. + ConfigTemplateExtension `json:",inline"` +} + +type ConfigTemplateExtension struct { + // Specifies the name of the referenced configuration template ConfigMap object. + // + // +kubebuilder:validation:Required + // +kubebuilder:validation:Pattern:=`^[a-z0-9]([a-z0-9\.\-]*[a-z0-9])?$` + TemplateRef string `json:"templateRef"` + + // Specifies the namespace of the referenced configuration template ConfigMap object. + // An empty namespace is equivalent to the "default" namespace. + // + // +kubebuilder:default="default" + // +kubebuilder:validation:Pattern:=`^[a-z0-9]([a-z0-9\-]*[a-z0-9])?$` + // +optional + Namespace string `json:"namespace,omitempty"` + + // Defines the strategy for merging externally imported templates into component templates. + // + // +kubebuilder:default="none" + // +optional + Policy MergedPolicy `json:"policy,omitempty"` +} + +// MergedPolicy defines how to merge external imported templates into component templates. +// +enum +// +kubebuilder:validation:Enum={patch,replace,none} +type MergedPolicy string + +const ( + PatchPolicy MergedPolicy = "patch" + ReplacePolicy MergedPolicy = "replace" + OnlyAddPolicy MergedPolicy = "add" + NoneMergePolicy MergedPolicy = "none" +) + +// RerenderResourceType defines the resource requirements for a component. +// +enum +// +kubebuilder:validation:Enum={vscale,hscale,tls} +type RerenderResourceType string + +const ( + ComponentVScaleType RerenderResourceType = "vscale" + ComponentHScaleType RerenderResourceType = "hscale" +) + +type LogConfig struct { + // Specifies a descriptive label for the log type, such as 'slow' for a MySQL slow log file. + // It provides a clear identification of the log's purpose and content. + // + // +kubebuilder:validation:Required + // +kubebuilder:validation:MaxLength=128 + Name string `json:"name"` + + // Specifies the paths or patterns identifying where the log files are stored. + // This field allows the system to locate and manage log files effectively. + // + // Examples: + // + // - /home/postgres/pgdata/pgroot/data/log/postgresql-* + // - /data/mysql/log/mysqld-error.log + // + // +kubebuilder:validation:Required + // +kubebuilder:validation:MaxLength=4096 + FilePathPattern string `json:"filePathPattern"` +} + +type SystemAccount struct { + // Specifies the unique identifier for the account. This name is used by other entities to reference the account. + // + // This field is immutable once set. + // + // +kubebuilder:validation:Required + Name string `json:"name"` + + // Indicates if this account is a system initialization account (e.g., MySQL root). + // + // This field is immutable once set. + // + // +kubebuilder:default=false + // +optional + InitAccount bool `json:"initAccount,omitempty"` + + // Defines the statement used to create the account with the necessary privileges. + // + // This field is immutable once set. + // + // +optional + Statement string `json:"statement,omitempty"` + + // Specifies the policy for generating the account's password. + // + // This field is immutable once set. + // + // +optional + PasswordGenerationPolicy PasswordConfig `json:"passwordGenerationPolicy"` + + // Refers to the secret from which data will be copied to create the new account. + // + // This field is immutable once set. + // + // +optional + SecretRef *ProvisionSecretRef `json:"secretRef,omitempty"` +} + +// ReplicasLimit defines the valid range of number of replicas supported. +// +// +kubebuilder:validation:XValidation:rule="self.minReplicas >= 0 && self.maxReplicas <= 16384",message="the minimum and maximum limit of replicas should be in the range of [0, 16384]" +// +kubebuilder:validation:XValidation:rule="self.minReplicas <= self.maxReplicas",message="the minimum replicas limit should be no greater than the maximum" +type ReplicasLimit struct { + // The minimum limit of replicas. + // + // +kubebuilder:validation:Required + MinReplicas int32 `json:"minReplicas"` + + // The maximum limit of replicas. + // + // +kubebuilder:validation:Required + MaxReplicas int32 `json:"maxReplicas"` +} + +// ReplicaRole represents a role that can be assumed by a component instance. +type ReplicaRole struct { + // Defines the role's identifier. It is used to set the "apps.kubeblocks.io/role" label value + // on the corresponding object. + // + // This field is immutable once set. + // + // +kubebuilder:validation:Required + // +kubebuilder:validation:MaxLength=32 + // +kubebuilder:validation:Pattern=`^.*[^\s]+.*$` + Name string `json:"name"` + + // Indicates whether a replica assigned this role is capable of providing services. + // + // This field is immutable once set. + // + // +kubebuilder:default=false + // +optional + Serviceable bool `json:"serviceable,omitempty"` + + // Determines if a replica in this role has the authority to perform write operations. + // A writable replica can modify data, handle update operations. + // + // This field is immutable once set. + // + // +kubebuilder:default=false + // +optional + Writable bool `json:"writable,omitempty"` + + // Specifies whether a replica with this role has voting rights. + // In distributed systems, this typically means the replica can participate in consensus decisions, + // configuration changes, or other processes that require a quorum. + // + // This field is immutable once set. + // + // +kubebuilder:default=false + // +optional + Votable bool `json:"votable,omitempty"` +} + +// UpdateStrategy defines the update strategy for cluster components. This strategy determines how updates are applied +// across the cluster. +// The available strategies are `Serial`, `BestEffortParallel`, and `Parallel`. +// +// +enum +// +kubebuilder:validation:Enum={Serial,BestEffortParallel,Parallel} +type UpdateStrategy string + +const ( + // SerialStrategy indicates that updates are applied one at a time in a sequential manner. + // The operator waits for each replica to be updated and ready before proceeding to the next one. + // This ensures that only one replica is unavailable at a time during the update process. + SerialStrategy UpdateStrategy = "Serial" + + // ParallelStrategy indicates that updates are applied simultaneously to all Pods of a Component. + // The replicas are updated in parallel, with the operator updating all replicas concurrently. + // This strategy provides the fastest update time but may lead to a period of reduced availability or + // capacity during the update process. + ParallelStrategy UpdateStrategy = "Parallel" + + // BestEffortParallelStrategy indicates that the replicas are updated in parallel, with the operator making + // a best-effort attempt to update as many replicas as possible concurrently + // while maintaining the component's availability. + // Unlike the `Parallel` strategy, the `BestEffortParallel` strategy aims to ensure that a minimum number + // of replicas remain available during the update process to maintain the component's quorum and functionality. + // + // For example, consider a component with 5 replicas. To maintain the component's availability and quorum, + // the operator may allow a maximum of 2 replicas to be simultaneously updated. This ensures that at least + // 3 replicas (a quorum) remain available and functional during the update process. + // + // The `BestEffortParallel` strategy strikes a balance between update speed and component availability. + BestEffortParallelStrategy UpdateStrategy = "BestEffortParallel" +) + +// ComponentLifecycleActions defines a collection of Actions for customizing the behavior of a Component. +type ComponentLifecycleActions struct { + // Specifies the hook to be executed after a component's creation. + // + // By setting `postProvision.customHandler.preCondition`, you can determine the specific lifecycle stage + // at which the action should trigger: `Immediately`, `RuntimeReady`, `ComponentReady`, and `ClusterReady`. + // with `ComponentReady` being the default. + // + // The PostProvision Action is intended to run only once. + // + // Note: This field is immutable once it has been set. + // + // +optional + PostProvision *Action `json:"postProvision,omitempty"` + + // Specifies the hook to be executed prior to terminating a component. + // + // The PreTerminate Action is intended to run only once. + // + // This action is executed immediately when a scale-down operation for the Component is initiated. + // The actual termination and cleanup of the Component and its associated resources will not proceed + // until the PreTerminate action has completed successfully. + // + // Note: This field is immutable once it has been set. + // + // +optional + PreTerminate *Action `json:"preTerminate,omitempty"` + + // Defines the procedure which is invoked regularly to assess the role of replicas. + // + // This action is periodically triggered at the specified interval to determine the role of each replica. + // Upon successful execution, the action's output designates the role of the replica, + // which should match one of the predefined role names within `componentDefinition.spec.roles`. + // The output is then compared with the previous successful execution result. + // If a role change is detected, an event is generated to inform the controller, + // which initiates an update of the replica's role. + // + // Defining a RoleProbe Action for a Component is required if roles are defined for the Component. + // It ensures replicas are correctly labeled with their respective roles. + // Without this, services that rely on roleSelectors might improperly direct traffic to wrong replicas. + // + // The container executing this action has access to following variables: + // + // - KB_POD_FQDN: The FQDN of the Pod whose role is being assessed. + // + // Expected output of this action: + // - On Success: The determined role of the replica, which must align with one of the roles specified + // in the component definition. + // - On Failure: An error message, if applicable, indicating why the action failed. + // + // Note: This field is immutable once it has been set. + // + // +optional + RoleProbe *Probe `json:"roleProbe,omitempty"` + + // Defines the procedure for a controlled transition of leadership from the current leader to a new replica. + // This approach aims to minimize downtime and maintain availability in systems with a leader-follower topology, + // during events such as planned maintenance or when performing stop, shutdown, restart, or upgrade operations + // involving the current leader node. + // + // The container executing this action has access to following variables: + // + // - KB_SWITCHOVER_CANDIDATE_NAME: The name of the pod for the new leader candidate, which may not be specified (empty). + // - KB_SWITCHOVER_CANDIDATE_FQDN: The FQDN of the new leader candidate's pod, which may not be specified (empty). + // + // Note: This field is immutable once it has been set. + // + // +optional + Switchover *Action `json:"switchover,omitempty"` + + // Defines the procedure to add a new replica to the replication group. + // + // This action is initiated after a replica pod becomes ready. + // + // The role of the replica (e.g., primary, secondary) will be determined and assigned as part of the action command + // implementation, or automatically by the database kernel or a sidecar utility like Patroni that implements + // a consensus algorithm. + // + // The container executing this action has access to following variables: + // + // - KB_JOIN_MEMBER_POD_FQDN: The pod FQDN of the replica being added to the group. + // - KB_JOIN_MEMBER_POD_NAME: The pod name of the replica being added to the group. + // + // Expected action output: + // - On Failure: An error message detailing the reason for any failure encountered + // during the addition of the new member. + // + // For example, to add a new OBServer to an OceanBase Cluster in 'zone1', the following command may be used: + // + // ```yaml + // command: + // - bash + // - -c + // - | + // CLIENT="mysql -u $SERVICE_USER -p$SERVICE_PASSWORD -P $SERVICE_PORT -h $SERVICE_HOST -e" + // $CLIENT "ALTER SYSTEM ADD SERVER '$KB_POD_FQDN:$SERVICE_PORT' ZONE 'zone1'" + // ``` + // + // Note: This field is immutable once it has been set. + // + // +optional + MemberJoin *Action `json:"memberJoin,omitempty"` + + // Defines the procedure to remove a replica from the replication group. + // + // This action is initiated before remove a replica from the group. + // The operator will wait for MemberLeave to complete successfully before releasing the replica and cleaning up + // related Kubernetes resources. + // + // The process typically includes updating configurations and informing other group members about the removal. + // Data migration is generally not part of this action and should be handled separately if needed. + // + // The container executing this action has access to following variables: + // + // - KB_LEAVE_MEMBER_POD_FQDN: The pod name of the replica being removed from the group. + // - KB_LEAVE_MEMBER_POD_NAME: The pod name of the replica being removed from the group. + // + // Expected action output: + // - On Failure: An error message, if applicable, indicating why the action failed. + // + // For example, to remove an OBServer from an OceanBase Cluster in 'zone1', the following command can be executed: + // + // ```yaml + // command: + // - bash + // - -c + // - | + // CLIENT="mysql -u $SERVICE_USER -p$SERVICE_PASSWORD -P $SERVICE_PORT -h $SERVICE_HOST -e" + // $CLIENT "ALTER SYSTEM DELETE SERVER '$KB_POD_FQDN:$SERVICE_PORT' ZONE 'zone1'" + // ``` + // + // Note: This field is immutable once it has been set. + // + // +optional + MemberLeave *Action `json:"memberLeave,omitempty"` + + // Defines the procedure to switch a replica into the read-only state. + // + // Use Case: + // This action is invoked when the database's volume capacity nears its upper limit and space is about to be exhausted. + // + // The container executing this action has access to following environment variables: + // + // - KB_POD_FQDN: The FQDN of the replica pod whose role is being checked. + // + // Expected action output: + // - On Failure: An error message, if applicable, indicating why the action failed. + // + // Note: This field is immutable once it has been set. + // + // +optional + Readonly *Action `json:"readonly,omitempty"` + + // Defines the procedure to transition a replica from the read-only state back to the read-write state. + // + // Use Case: + // This action is used to bring back a replica that was previously in a read-only state, + // which restricted write operations, to its normal operational state where it can handle + // both read and write operations. + // + // The container executing this action has access to following environment variables: + // + // - KB_POD_FQDN: The FQDN of the replica pod whose role is being checked. + // + // Expected action output: + // - On Failure: An error message, if applicable, indicating why the action failed. + // + // Note: This field is immutable once it has been set. + // + // +optional + Readwrite *Action `json:"readwrite,omitempty"` + + // Defines the procedure for exporting the data from a replica. + // + // Use Case: + // This action is intended for initializing a newly created replica with data. It involves exporting data + // from an existing replica and importing it into the new, empty replica. This is essential for synchronizing + // the state of replicas across the system. + // + // Applicability: + // Some database engines or associated sidecar applications (e.g., Patroni) may already provide this functionality. + // In such cases, this action may not be required. + // + // The output should be a valid data dump streamed to stdout. It must exclude any irrelevant information to ensure + // that only the necessary data is exported for import into the new replica. + // + // Note: This field is immutable once it has been set. + // + // +optional + DataDump *Action `json:"dataDump,omitempty"` + + // Defines the procedure for importing data into a replica. + // + // Use Case: + // This action is intended for initializing a newly created replica with data. It involves exporting data + // from an existing replica and importing it into the new, empty replica. This is essential for synchronizing + // the state of replicas across the system. + // + // Some database engines or associated sidecar applications (e.g., Patroni) may already provide this functionality. + // In such cases, this action may not be required. + // + // Data should be received through stdin. If any error occurs during the process, + // the action must be able to guarantee idempotence to allow for retries from the beginning. + // + // Note: This field is immutable once it has been set. + // + // +optional + DataLoad *Action `json:"dataLoad,omitempty"` + + // Defines the procedure that update a replica with new configuration. + // + // Note: This field is immutable once it has been set. + // + // This Action is reserved for future versions. + // + // +optional + Reconfigure *Action `json:"reconfigure,omitempty"` + + // Defines the procedure to generate a new database account. + // + // Use Case: + // This action is designed to create system accounts that are utilized for replication, monitoring, backup, + // and other administrative tasks. + // + // The container executing this action has access to following variables: + // + // - KB_ACCOUNT_NAME: The name of the system account to be created. + // - KB_ACCOUNT_PASSWORD: The password for the system account. // TODO: how to pass the password securely? + // - KB_ACCOUNT_STATEMENT: The statement used to create the system account. + // + // Note: This field is immutable once it has been set. + // + // +optional + AccountProvision *Action `json:"accountProvision,omitempty"` +} + +// Action defines a customizable hook or procedure tailored for different database engines, +// designed to be invoked at predetermined points within the lifecycle of a Component instance. +// It provides a modular and extensible way to customize a Component's behavior through the execution of defined actions. +// +// Available Action triggers include: +// +// - `postProvision`: Defines the hook to be executed after the creation of a Component, +// with `preCondition` specifying when the action should be fired relative to the Component's lifecycle stages: +// `Immediately`, `RuntimeReady`, `ComponentReady`, and `ClusterReady`. +// - `preTerminate`: Defines the hook to be executed before terminating a Component. +// - `roleProbe`: Defines the procedure which is invoked regularly to assess the role of replicas. +// - `switchover`: Defines the procedure for a controlled transition of leadership from the current leader to a new replica. +// This approach aims to minimize downtime and maintain availability in systems with a leader-follower topology, +// such as during planned maintenance or upgrades on the current leader node. +// - `memberJoin`: Defines the procedure to add a new replica to the replication group. +// - `memberLeave`: Defines the method to remove a replica from the replication group. +// - `readOnly`: Defines the procedure to switch a replica into the read-only state. +// - `readWrite`: Defines the procedure to transition a replica from the read-only state back to the read-write state. +// - `dataDump`: Defines the procedure to export the data from a replica. +// - `dataLoad`: Defines the procedure to import data into a replica. +// - `reconfigure`: Defines the procedure that update a replica with new configuration. +// - `accountProvision`: Defines the procedure to generate a new database account. +// +// Actions can be executed in different ways: +// +// - ExecAction: Executes a command inside a container. +// A set of predefined environment variables are available and can be leveraged within the `exec.command` +// to access context information such as details about pods, components, the overall cluster state, +// or database connection credentials. +// These variables provide a dynamic and context-aware mechanism for script execution. +// - HTTPAction: Performs an HTTP request. +// HTTPAction is to be implemented in future version. +// - GRPCAction: In future version, Actions will support initiating gRPC calls. +// This allows developers to implement Actions using plugins written in programming language like Go, +// providing greater flexibility and extensibility. +// +// An action is considered successful on returning 0, or HTTP 200 for status HTTP(s) Actions. +// Any other return value or HTTP status codes indicate failure, +// and the action may be retried based on the configured retry policy. +// +// - If an action exceeds the specified timeout duration, it will be terminated, and the action is considered failed. +// - If an action produces any data as output, it should be written to stdout, +// or included in the HTTP response payload for HTTP(s) actions. +// - If an action encounters any errors, error messages should be written to stderr, +// or detailed in the HTTP response with the appropriate non-200 status code. +type Action struct { + // Defines the command to run. + // + // This field cannot be updated. + // + // +optional + Exec *ExecAction `json:"exec,omitempty"` + + // Specifies the maximum duration in seconds that the Action is allowed to run. + // + // If the Action does not complete within this time frame, it will be terminated. + // + // This field cannot be updated. + // + // +kubebuilder:default=0 + // +optional + TimeoutSeconds int32 `json:"timeoutSeconds,omitempty"` + + // Defines the strategy to be taken when retrying the Action after a failure. + // + // It specifies the conditions under which the Action should be retried and the limits to apply, + // such as the maximum number of retries and backoff strategy. + // + // This field cannot be updated. + // + // +optional + RetryPolicy *RetryPolicy `json:"retryPolicy,omitempty"` + + // Specifies the state that the cluster must reach before the Action is executed. + // Currently, this is only applicable to the `postProvision` action. + // + // The conditions are as follows: + // + // - `Immediately`: Executed right after the Component object is created. + // The readiness of the Component and its resources is not guaranteed at this stage. + // - `RuntimeReady`: The Action is triggered after the Component object has been created and all associated + // runtime resources (e.g. Pods) are in a ready state. + // - `ComponentReady`: The Action is triggered after the Component itself is in a ready state. + // This process does not affect the readiness state of the Component or the Cluster. + // - `ClusterReady`: The Action is executed after the Cluster is in a ready state. + // This execution does not alter the Component or the Cluster's state of readiness. + // + // This field cannot be updated. + // + // +optional + PreCondition *PreConditionType `json:"preCondition,omitempty"` +} + +// ExecAction describes an Action that executes a command inside a container. +type ExecAction struct { + // Specifies the container image to be used for running the Action. + // + // When specified, a dedicated container will be created using this image to execute the Action. + // All actions with same image will share the same container. + // + // This field cannot be updated. + // + // +optional + Image string `json:"image,omitempty"` + + // Represents a list of environment variables that will be injected into the container. + // These variables enable the container to adapt its behavior based on the environment it's running in. + // + // This field cannot be updated. + // + // +optional + // +patchMergeKey=name + // +patchStrategy=merge + Env []corev1.EnvVar `json:"env,omitempty" patchStrategy:"merge" patchMergeKey:"name"` + + // Specifies the command to be executed inside the container. + // The working directory for this command is the container's root directory('/'). + // Commands are executed directly without a shell environment, meaning shell-specific syntax ('|', etc.) is not supported. + // If the shell is required, it must be explicitly invoked in the command. + // + // A successful execution is indicated by an exit status of 0; any non-zero status signifies a failure. + // + // +optional + Command []string `json:"command,omitempty"` + + // Args represents the arguments that are passed to the `command` for execution. + // + // +optional + Args []string `json:"args,omitempty"` + + // Defines the criteria used to select the target Pod(s) for executing the Action. + // This is useful when there is no default target replica identified. + // It allows for precise control over which Pod(s) the Action should run in. + // + // If not specified, the Action will be executed in the pod where the Action is triggered, such as the pod + // to be removed or added; or a random pod if the Action is triggered at the component level, such as + // post-provision or pre-terminate of the component. + // + // This field cannot be updated. + // + // +optional + TargetPodSelector TargetPodSelector `json:"targetPodSelector,omitempty"` + + // Used in conjunction with the `targetPodSelector` field to refine the selection of target pod(s) for Action execution. + // The impact of this field depends on the `targetPodSelector` value: + // + // - When `targetPodSelector` is set to `Any` or `All`, this field will be ignored. + // - When `targetPodSelector` is set to `Role`, only those replicas whose role matches the `matchingKey` + // will be selected for the Action. + // + // This field cannot be updated. + // + // +optional + MatchingKey string `json:"matchingKey,omitempty"` + + // Specifies the name of the container within the same pod whose resources will be shared with the action. + // This allows the action to utilize the specified container's resources without executing within it. + // + // The name must match one of the containers defined in `componentDefinition.spec.runtime`. + // + // The resources that can be shared are included: + // + // - volume mounts + // + // This field cannot be updated. + // + // +optional + Container string `json:"container,omitempty"` +} + +// TargetPodSelector defines how to select pod(s) to execute an Action. +// +enum +// +kubebuilder:validation:Enum={Any,All,Role,Ordinal} +type TargetPodSelector string + +const ( + AnyReplica TargetPodSelector = "Any" + AllReplicas TargetPodSelector = "All" + RoleSelector TargetPodSelector = "Role" + OrdinalSelector TargetPodSelector = "Ordinal" +) + +type RetryPolicy struct { + // Defines the maximum number of retry attempts that should be made for a given Action. + // This value is set to 0 by default, indicating that no retries will be made. + // + // +kubebuilder:default=0 + // +optional + MaxRetries int `json:"maxRetries,omitempty"` + + // Indicates the duration of time to wait between each retry attempt. + // This value is set to 0 by default, indicating that there will be no delay between retry attempts. + // + // +kubebuilder:default=0 + // +optional + RetryInterval time.Duration `json:"retryInterval,omitempty"` +} + +// PreConditionType defines the preCondition type of the action execution. +type PreConditionType string + +const ( + ImmediatelyPreConditionType PreConditionType = "Immediately" + RuntimeReadyPreConditionType PreConditionType = "RuntimeReady" + ComponentReadyPreConditionType PreConditionType = "ComponentReady" + ClusterReadyPreConditionType PreConditionType = "ClusterReady" +) + +type Probe struct { + Action `json:",inline"` + + // Specifies the number of seconds to wait after the container has started before the RoleProbe + // begins to detect the container's role. + // + // +optional + InitialDelaySeconds int32 `json:"initialDelaySeconds,omitempty"` + + // Specifies the frequency at which the probe is conducted. This value is expressed in seconds. + // Default to 10 seconds. Minimum value is 1. + // + // +optional + PeriodSeconds int32 `json:"periodSeconds,omitempty"` + + // Minimum consecutive successes for the probe to be considered successful after having failed. + // Defaults to 1. Minimum value is 1. + // + // +optional + SuccessThreshold int32 `json:"successThreshold,omitempty"` + + // Minimum consecutive failures for the probe to be considered failed after having succeeded. + // Defaults to 3. Minimum value is 1. + // + // +optional + FailureThreshold int32 `json:"failureThreshold,omitempty"` +} + +// ServiceRefDeclaration represents a reference to a service that can be either provided by a KubeBlocks Cluster +// or an external service. +// It acts as a placeholder for the actual service reference, which is determined later when a Cluster is created. +// +// The purpose of ServiceRefDeclaration is to declare a service dependency without specifying the concrete details +// of the service. +// It allows for flexibility and abstraction in defining service references within a Component. +// By using ServiceRefDeclaration, you can define service dependencies in a declarative manner, enabling loose coupling +// and easier management of service references across different components and clusters. +// +// Upon Cluster creation, the ServiceRefDeclaration is bound to an actual service through the ServiceRef field, +// effectively resolving and connecting to the specified service. +type ServiceRefDeclaration struct { + // Specifies the name of the ServiceRefDeclaration. + // + // +kubebuilder:validation:Required + Name string `json:"name"` + + // Defines a list of constraints and requirements for services that can be bound to this ServiceRefDeclaration + // upon Cluster creation. + // Each ServiceRefDeclarationSpec defines a ServiceKind and ServiceVersion, + // outlining the acceptable service types and versions that are compatible. + // + // This flexibility allows a ServiceRefDeclaration to be fulfilled by any one of the provided specs. + // For example, if it requires an OLTP database, specs for both MySQL and PostgreSQL are listed, + // either MySQL or PostgreSQL services can be used when binding. + // + // +kubebuilder:validation:Required + ServiceRefDeclarationSpecs []ServiceRefDeclarationSpec `json:"serviceRefDeclarationSpecs"` + + // Specifies whether the service reference can be optional. + // + // For an optional service-ref, the component can still be created even if the service-ref is not provided. + // + // +optional + Optional *bool `json:"optional,omitempty"` +} + +type ServiceRefDeclarationSpec struct { + // Specifies the type or nature of the service. This should be a well-known application cluster type, such as + // {mysql, redis, mongodb}. + // The field is case-insensitive and supports abbreviations for some well-known databases. + // For instance, both `zk` and `zookeeper` are considered as a ZooKeeper cluster, while `pg`, `postgres`, `postgresql` + // are all recognized as a PostgreSQL cluster. + // + // +kubebuilder:validation:Required + ServiceKind string `json:"serviceKind"` + + // Defines the service version of the service reference. This is a regular expression that matches a version number pattern. + // For instance, `^8.0.8$`, `8.0.\d{1,2}$`, `^[v\-]*?(\d{1,2}\.){0,3}\d{1,2}$` are all valid patterns. + // + // +kubebuilder:validation:Required + ServiceVersion string `json:"serviceVersion"` +} + +type Exporter struct { + // Specifies the name of the built-in metrics exporter container. + // + // +optional + ContainerName string `json:"containerName,omitempty"` + + // Specifies the http/https url path to scrape for metrics. + // If empty, Prometheus uses the default value (e.g. `/metrics`). + // + // +kubebuilder:validation:default="/metrics" + // +optional + ScrapePath string `json:"scrapePath,omitempty"` + + // Specifies the port name to scrape for metrics. + // + // +optional + ScrapePort string `json:"scrapePort,omitempty"` + + // Specifies the schema to use for scraping. + // `http` and `https` are the expected values unless you rewrite the `__scheme__` label via relabeling. + // If empty, Prometheus uses the default value `http`. + // + // +kubebuilder:validation:default="http" + // +optional + ScrapeScheme PrometheusScheme `json:"scrapeScheme,omitempty"` +} + +// PrometheusScheme defines the protocol of prometheus scrape metrics. +// +// +enum +// +kubebuilder:validation:Enum={http,https} +type PrometheusScheme string + +const ( + HTTPProtocol PrometheusScheme = "http" + HTTPSProtocol PrometheusScheme = "https" +) diff --git a/apis/apps/v1/types.go b/apis/apps/v1/types.go index 8263b109a4d..2dba4c50b99 100644 --- a/apis/apps/v1/types.go +++ b/apis/apps/v1/types.go @@ -16,6 +16,10 @@ limitations under the License. package v1 +import ( + corev1 "k8s.io/api/core/v1" +) + // Phase represents the status of a CR. // // +enum @@ -29,3 +33,646 @@ const ( // UnavailablePhase indicates that a CR is in an unavailable state. UnavailablePhase Phase = "Unavailable" ) + +// ClusterComponentPhase defines the phase of a cluster component as represented in cluster.status.components.phase field. +// +// +enum +// +kubebuilder:validation:Enum={Creating,Running,Updating,Stopping,Stopped,Deleting,Failed,Abnormal} +type ClusterComponentPhase string + +const ( + // CreatingClusterCompPhase indicates the component is being created. + CreatingClusterCompPhase ClusterComponentPhase = "Creating" + + // RunningClusterCompPhase indicates the component has more than zero replicas, and all pods are up-to-date and + // in a 'Running' state. + RunningClusterCompPhase ClusterComponentPhase = "Running" + + // UpdatingClusterCompPhase indicates the component has more than zero replicas, and there are no failed pods, + // it is currently being updated. + UpdatingClusterCompPhase ClusterComponentPhase = "Updating" + + // StoppingClusterCompPhase indicates the component has zero replicas, and there are pods that are terminating. + StoppingClusterCompPhase ClusterComponentPhase = "Stopping" + + // StoppedClusterCompPhase indicates the component has zero replicas, and all pods have been deleted. + StoppedClusterCompPhase ClusterComponentPhase = "Stopped" + + // DeletingClusterCompPhase indicates the component is currently being deleted. + DeletingClusterCompPhase ClusterComponentPhase = "Deleting" + + // FailedClusterCompPhase indicates the component has more than zero replicas, but there are some failed pods. + // The component is not functioning. + FailedClusterCompPhase ClusterComponentPhase = "Failed" + + // AbnormalClusterCompPhase indicates the component has more than zero replicas, but there are some failed pods. + // The component is functioning, but it is in a fragile state. + AbnormalClusterCompPhase ClusterComponentPhase = "Abnormal" +) + +const ( + ConditionTypeHaltRecovery = "HaltRecovery" // ConditionTypeHaltRecovery describe Halt recovery processing stage + ConditionTypeProvisioningStarted = "ProvisioningStarted" // ConditionTypeProvisioningStarted the operator starts resource provisioning to create or change the cluster + ConditionTypeApplyResources = "ApplyResources" // ConditionTypeApplyResources the operator start to apply resources to create or change the cluster + ConditionTypeReplicasReady = "ReplicasReady" // ConditionTypeReplicasReady all pods of components are ready + ConditionTypeReady = "Ready" // ConditionTypeReady all components are running +) + +type ServiceRef struct { + // Specifies the identifier of the service reference declaration. + // It corresponds to the serviceRefDeclaration name defined in either: + // + // - `componentDefinition.spec.serviceRefDeclarations[*].name` + // - `clusterDefinition.spec.componentDefs[*].serviceRefDeclarations[*].name` (deprecated) + // + // +kubebuilder:validation:Required + Name string `json:"name"` + + // Specifies the namespace of the referenced Cluster or the namespace of the referenced ServiceDescriptor object. + // If not provided, the referenced Cluster and ServiceDescriptor will be searched in the namespace of the current + // Cluster by default. + // + // +optional + Namespace string `json:"namespace,omitempty"` + + // Specifies the name of the KubeBlocks Cluster being referenced. + // This is used when services from another KubeBlocks Cluster are consumed. + // + // By default, the referenced KubeBlocks Cluster's `clusterDefinition.spec.connectionCredential` + // will be utilized to bind to the current Component. This credential should include: + // `endpoint`, `port`, `username`, and `password`. + // + // Note: + // + // - The `ServiceKind` and `ServiceVersion` specified in the service reference within the + // ClusterDefinition are not validated when using this approach. + // - If both `cluster` and `serviceDescriptor` are present, `cluster` will take precedence. + // + // Deprecated since v0.9 since `clusterDefinition.spec.connectionCredential` is deprecated, + // use `clusterServiceSelector` instead. + // This field is maintained for backward compatibility and its use is discouraged. + // Existing usage should be updated to the current preferred approach to avoid compatibility issues in future releases. + // + // +kubebuilder:deprecatedversion:warning="This field has been deprecated since 0.9.0" + // +optional + Cluster string `json:"cluster,omitempty"` + + // References a service provided by another KubeBlocks Cluster. + // It specifies the ClusterService and the account credentials needed for access. + // + // +optional + ClusterServiceSelector *ServiceRefClusterSelector `json:"clusterServiceSelector,omitempty"` + + // Specifies the name of the ServiceDescriptor object that describes a service provided by external sources. + // + // When referencing a service provided by external sources, a ServiceDescriptor object is required to establish + // the service binding. + // The `serviceDescriptor.spec.serviceKind` and `serviceDescriptor.spec.serviceVersion` should match the serviceKind + // and serviceVersion declared in the definition. + // + // If both `cluster` and `serviceDescriptor` are specified, the `cluster` takes precedence. + // + // +optional + ServiceDescriptor string `json:"serviceDescriptor,omitempty"` +} + +type ServiceRefClusterSelector struct { + // The name of the Cluster being referenced. + // + // +kubebuilder:validation:Required + Cluster string `json:"cluster"` + + // Identifies a ClusterService from the list of Services defined in `cluster.spec.services` of the referenced Cluster. + // + // +optional + Service *ServiceRefServiceSelector `json:"service,omitempty"` + + // Specifies the SystemAccount to authenticate and establish a connection with the referenced Cluster. + // The SystemAccount should be defined in `componentDefinition.spec.systemAccounts` + // of the Component providing the service in the referenced Cluster. + // + // +optional + Credential *ServiceRefCredentialSelector `json:"credential,omitempty"` +} + +type ServiceRefServiceSelector struct { + // The name of the Component where the Service resides in. + // + // It is required when referencing a Component's Service. + // + // +optional + Component string `json:"component,omitempty"` + + // The name of the Service to be referenced. + // + // Leave it empty to reference the default Service. Set it to "headless" to reference the default headless Service. + // + // If the referenced Service is of pod-service type (a Service per Pod), there will be multiple Service objects matched, + // and the resolved value will be presented in the following format: service1.name,service2.name... + // + // +kubebuilder:validation:Required + Service string `json:"service"` + + // The port name of the Service to be referenced. + // + // If there is a non-zero node-port exist for the matched Service port, the node-port will be selected first. + // + // If the referenced Service is of pod-service type (a Service per Pod), there will be multiple Service objects matched, + // and the resolved value will be presented in the following format: service1.name:port1,service2.name:port2... + // + // +optional + Port string `json:"port,omitempty"` +} + +type ServiceRefCredentialSelector struct { + // The name of the Component where the credential resides in. + // + // +kubebuilder:validation:Required + Component string `json:"component"` + + // The name of the credential (SystemAccount) to reference. + // + // +kubebuilder:validation:Required + Name string `json:"name"` +} + +type ClusterComponentVolumeClaimTemplate struct { + // Refers to the name of a volumeMount defined in either: + // + // - `componentDefinition.spec.runtime.containers[*].volumeMounts` + // - `clusterDefinition.spec.componentDefs[*].podSpec.containers[*].volumeMounts` (deprecated) + // + // The value of `name` must match the `name` field of a volumeMount specified in the corresponding `volumeMounts` array. + // + // +kubebuilder:validation:Required + Name string `json:"name"` + + // Defines the desired characteristics of a PersistentVolumeClaim that will be created for the volume + // with the mount name specified in the `name` field. + // + // When a Pod is created for this ClusterComponent, a new PVC will be created based on the specification + // defined in the `spec` field. The PVC will be associated with the volume mount specified by the `name` field. + // + // +optional + Spec PersistentVolumeClaimSpec `json:"spec,omitempty"` +} + +type PersistentVolumeClaimSpec struct { + // Contains the desired access modes the volume should have. + // More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1. + // + // +kubebuilder:pruning:PreserveUnknownFields + // +optional + AccessModes []corev1.PersistentVolumeAccessMode `json:"accessModes,omitempty" protobuf:"bytes,1,rep,name=accessModes,casttype=PersistentVolumeAccessMode"` + + // Represents the minimum resources the volume should have. + // If the RecoverVolumeExpansionFailure feature is enabled, users are allowed to specify resource requirements that + // are lower than the previous value but must still be higher than the capacity recorded in the status field of the claim. + // More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources. + // + // +kubebuilder:pruning:PreserveUnknownFields + // +optional + Resources corev1.VolumeResourceRequirements `json:"resources,omitempty" protobuf:"bytes,2,opt,name=resources"` + + // The name of the StorageClass required by the claim. + // More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1. + // + // +optional + StorageClassName *string `json:"storageClassName,omitempty" protobuf:"bytes,5,opt,name=storageClassName"` + + // Defines what type of volume is required by the claim, either Block or Filesystem. + // + // +optional + VolumeMode *corev1.PersistentVolumeMode `json:"volumeMode,omitempty" protobuf:"bytes,6,opt,name=volumeMode,casttype=PersistentVolumeMode"` +} + +type Service struct { + // Name defines the name of the service. + // otherwise, it indicates the name of the service. + // Others can refer to this service by its name. (e.g., connection credential) + // Cannot be updated. + // + // +kubebuilder:validation:Required + // +kubebuilder:validation:MaxLength=25 + Name string `json:"name"` + + // ServiceName defines the name of the underlying service object. + // If not specified, the default service name with different patterns will be used: + // + // - CLUSTER_NAME: for cluster-level services + // - CLUSTER_NAME-COMPONENT_NAME: for component-level services + // + // Only one default service name is allowed. + // Cannot be updated. + // + // +kubebuilder:validation:MaxLength=25 + // +kubebuilder:validation:Pattern:=`^[a-z]([a-z0-9\-]*[a-z0-9])?$` + // + // +optional + ServiceName string `json:"serviceName,omitempty"` + + // If ServiceType is LoadBalancer, cloud provider related parameters can be put here + // More info: https://kubernetes.io/docs/concepts/services-networking/service/#loadbalancer. + // + // +optional + Annotations map[string]string `json:"annotations,omitempty"` + + // Spec defines the behavior of a service. + // https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status + // + // +optional + Spec corev1.ServiceSpec `json:"spec,omitempty"` + + // Extends the above `serviceSpec.selector` by allowing you to specify defined role as selector for the service. + // When `roleSelector` is set, it adds a label selector "kubeblocks.io/role: {roleSelector}" + // to the `serviceSpec.selector`. + // Example usage: + // + // roleSelector: "leader" + // + // In this example, setting `roleSelector` to "leader" will add a label selector + // "kubeblocks.io/role: leader" to the `serviceSpec.selector`. + // This means that the service will select and route traffic to Pods with the label + // "kubeblocks.io/role" set to "leader". + // + // Note that if `podService` sets to true, RoleSelector will be ignored. + // The `podService` flag takes precedence over `roleSelector` and generates a service for each Pod. + // + // +optional + RoleSelector string `json:"roleSelector,omitempty"` +} + +// ComponentService defines a service that would be exposed as an inter-component service within a Cluster. +// A Service defined in the ComponentService is expected to be accessed by other Components within the same Cluster. +// +// When a Component needs to use a ComponentService provided by another Component within the same Cluster, +// it can declare a variable in the `componentDefinition.spec.vars` section and bind it to the specific exposed address +// of the ComponentService using the `serviceVarRef` field. +type ComponentService struct { + Service `json:",inline"` + + // Indicates whether to create a corresponding Service for each Pod of the selected Component. + // When set to true, a set of Services will be automatically generated for each Pod, + // and the `roleSelector` field will be ignored. + // + // The names of the generated Services will follow the same suffix naming pattern: `$(serviceName)-$(podOrdinal)`. + // The total number of generated Services will be equal to the number of replicas specified for the Component. + // + // Example usage: + // + // ```yaml + // name: my-service + // serviceName: my-service + // podService: true + // disableAutoProvision: true + // spec: + // type: NodePort + // ports: + // - name: http + // port: 80 + // targetPort: 8080 + // ``` + // + // In this example, if the Component has 3 replicas, three Services will be generated: + // - my-service-0: Points to the first Pod (podOrdinal: 0) + // - my-service-1: Points to the second Pod (podOrdinal: 1) + // - my-service-2: Points to the third Pod (podOrdinal: 2) + // + // Each generated Service will have the specified spec configuration and will target its respective Pod. + // + // This feature is useful when you need to expose each Pod of a Component individually, allowing external access + // to specific instances of the Component. + // + // +kubebuilder:default=false + // +optional + PodService *bool `json:"podService,omitempty"` + + // Indicates whether the automatic provisioning of the service should be disabled. + // + // If set to true, the service will not be automatically created at the component provisioning. + // Instead, you can enable the creation of this service by specifying it explicitly in the cluster API. + // + // +optional + DisableAutoProvision *bool `json:"disableAutoProvision,omitempty"` +} + +type ComponentSystemAccount struct { + // The name of the system account. + // + // +kubebuilder:validation:Required + Name string `json:"name"` + + // Specifies the policy for generating the account's password. + // + // This field is immutable once set. + // + // +optional + PasswordConfig *PasswordConfig `json:"passwordConfig,omitempty"` + + // Refers to the secret from which data will be copied to create the new account. + // + // This field is immutable once set. + // + // +optional + SecretRef *ProvisionSecretRef `json:"secretRef,omitempty"` +} + +// PasswordConfig helps provide to customize complexity of password generation pattern. +type PasswordConfig struct { + // The length of the password. + // + // +kubebuilder:validation:Maximum=32 + // +kubebuilder:validation:Minimum=8 + // +kubebuilder:default=16 + // +optional + Length int32 `json:"length,omitempty"` + + // The number of digits in the password. + // + // +kubebuilder:validation:Maximum=8 + // +kubebuilder:validation:Minimum=0 + // +kubebuilder:default=4 + // +optional + NumDigits int32 `json:"numDigits,omitempty"` + + // The number of symbols in the password. + // + // +kubebuilder:validation:Maximum=8 + // +kubebuilder:validation:Minimum=0 + // +kubebuilder:default=0 + // +optional + NumSymbols int32 `json:"numSymbols,omitempty"` + + // The case of the letters in the password. + // + // +kubebuilder:default=MixedCases + // +optional + LetterCase LetterCase `json:"letterCase,omitempty"` + + // Seed to generate the account's password. + // Cannot be updated. + // + // +optional + Seed string `json:"seed,omitempty"` +} + +// LetterCase defines the available cases to be used in password generation. +// +// +enum +// +kubebuilder:validation:Enum={LowerCases,UpperCases,MixedCases} +type LetterCase string + +const ( + // LowerCases represents the use of lower case letters only. + LowerCases LetterCase = "LowerCases" + + // UpperCases represents the use of upper case letters only. + UpperCases LetterCase = "UpperCases" + + // MixedCases represents the use of a mix of both lower and upper case letters. + MixedCases LetterCase = "MixedCases" +) + +// ProvisionSecretRef represents the reference to a secret. +type ProvisionSecretRef struct { + // The unique identifier of the secret. + // + // +kubebuilder:validation:Required + Name string `json:"name"` + + // The namespace where the secret is located. + // + // +kubebuilder:validation:Required + Namespace string `json:"namespace"` +} + +// ClusterComponentConfig represents a config with its source bound. +type ClusterComponentConfig struct { + // The name of the config. + // + // +optional + Name *string `json:"name,omitempty"` + + // The source of the config. + ClusterComponentConfigSource `json:",inline"` +} + +// ClusterComponentConfigSource represents the source of a config. +type ClusterComponentConfigSource struct { + // ConfigMap source for the config. + // + // +optional + ConfigMap *corev1.ConfigMapVolumeSource `json:"configMap,omitempty"` + + // TODO: support more diverse sources: + // - Config template of other components within the same cluster + // - Config template of components from other clusters + // - Secret + // - Local file +} + +type PodUpdatePolicyType string + +const ( + // StrictInPlacePodUpdatePolicyType indicates that only allows in-place upgrades. + // Any attempt to modify other fields will be rejected. + StrictInPlacePodUpdatePolicyType PodUpdatePolicyType = "StrictInPlace" + + // PreferInPlacePodUpdatePolicyType indicates that we will first attempt an in-place upgrade of the Pod. + // If that fails, it will fall back to the ReCreate, where pod will be recreated. + PreferInPlacePodUpdatePolicyType PodUpdatePolicyType = "PreferInPlace" +) + +type SchedulingPolicy struct { + // If specified, the Pod will be dispatched by specified scheduler. + // If not specified, the Pod will be dispatched by default scheduler. + // + // +optional + SchedulerName string `json:"schedulerName,omitempty"` + + // NodeSelector is a selector which must be true for the Pod to fit on a node. + // Selector which must match a node's labels for the Pod to be scheduled on that node. + // More info: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ + // + // +optional + // +mapType=atomic + NodeSelector map[string]string `json:"nodeSelector,omitempty"` + + // NodeName is a request to schedule this Pod onto a specific node. If it is non-empty, + // the scheduler simply schedules this Pod onto that node, assuming that it fits resource + // requirements. + // + // +optional + NodeName string `json:"nodeName,omitempty"` + + // Specifies a group of affinity scheduling rules of the Cluster, including NodeAffinity, PodAffinity, and PodAntiAffinity. + // + // +optional + Affinity *corev1.Affinity `json:"affinity,omitempty"` + + // Allows Pods to be scheduled onto nodes with matching taints. + // Each toleration in the array allows the Pod to tolerate node taints based on + // specified `key`, `value`, `effect`, and `operator`. + // + // - The `key`, `value`, and `effect` identify the taint that the toleration matches. + // - The `operator` determines how the toleration matches the taint. + // + // Pods with matching tolerations are allowed to be scheduled on tainted nodes, typically reserved for specific purposes. + // + // +optional + Tolerations []corev1.Toleration `json:"tolerations,omitempty"` + + // TopologySpreadConstraints describes how a group of Pods ought to spread across topology + // domains. Scheduler will schedule Pods in a way which abides by the constraints. + // All topologySpreadConstraints are ANDed. + // + // +optional + TopologySpreadConstraints []corev1.TopologySpreadConstraint `json:"topologySpreadConstraints,omitempty"` +} + +type TLSConfig struct { + // A boolean flag that indicates whether the Component should use Transport Layer Security (TLS) + // for secure communication. + // When set to true, the Component will be configured to use TLS encryption for its network connections. + // This ensures that the data transmitted between the Component and its clients or other Components is encrypted + // and protected from unauthorized access. + // If TLS is enabled, the Component may require additional configuration, + // such as specifying TLS certificates and keys, to properly set up the secure communication channel. + // + // +kubebuilder:default=false + // +optional + Enable bool `json:"enable,omitempty"` + + // Specifies the configuration for the TLS certificates issuer. + // It allows defining the issuer name and the reference to the secret containing the TLS certificates and key. + // The secret should contain the CA certificate, TLS certificate, and private key in the specified keys. + // Required when TLS is enabled. + // + // +optional + Issuer *Issuer `json:"issuer,omitempty"` +} + +// Issuer defines the TLS certificates issuer for the Cluster. +type Issuer struct { + // The issuer for TLS certificates. + // It only allows two enum values: `KubeBlocks` and `UserProvided`. + // + // - `KubeBlocks` indicates that the self-signed TLS certificates generated by the KubeBlocks Operator will be used. + // - `UserProvided` means that the user is responsible for providing their own CA, Cert, and Key. + // In this case, the user-provided CA certificate, server certificate, and private key will be used + // for TLS communication. + // + // +kubebuilder:validation:Enum={KubeBlocks, UserProvided} + // +kubebuilder:default=KubeBlocks + // +kubebuilder:validation:Required + Name IssuerName `json:"name"` + + // SecretRef is the reference to the secret that contains user-provided certificates. + // It is required when the issuer is set to `UserProvided`. + // + // +optional + SecretRef *TLSSecretRef `json:"secretRef,omitempty"` +} + +// IssuerName defines the name of the TLS certificates issuer. +// +enum +// +kubebuilder:validation:Enum={KubeBlocks,UserProvided} +type IssuerName string + +const ( + // IssuerKubeBlocks represents certificates that are signed by the KubeBlocks Operator. + IssuerKubeBlocks IssuerName = "KubeBlocks" + + // IssuerUserProvided indicates that the user has provided their own CA-signed certificates. + IssuerUserProvided IssuerName = "UserProvided" +) + +// TLSSecretRef defines Secret contains Tls certs +type TLSSecretRef struct { + // Name of the Secret that contains user-provided certificates. + // +kubebuilder:validation:Required + Name string `json:"name"` + + // Key of CA cert in Secret + // +kubebuilder:validation:Required + CA string `json:"ca"` + + // Key of Cert in Secret + // +kubebuilder:validation:Required + Cert string `json:"cert"` + + // Key of TLS private key in Secret + // +kubebuilder:validation:Required + Key string `json:"key"` +} + +// InstanceTemplate allows customization of individual replica configurations in a Component. +type InstanceTemplate struct { + // Name specifies the unique name of the instance Pod created using this InstanceTemplate. + // This name is constructed by concatenating the Component's name, the template's name, and the instance's ordinal + // using the pattern: $(cluster.name)-$(component.name)-$(template.name)-$(ordinal). Ordinals start from 0. + // The specified name overrides any default naming conventions or patterns. + // + // +kubebuilder:validation:MaxLength=54 + // +kubebuilder:validation:Pattern:=`^[a-z0-9]([a-z0-9\.\-]*[a-z0-9])?$` + // +kubebuilder:validation:Required + Name string `json:"name"` + + // Specifies the number of instances (Pods) to create from this InstanceTemplate. + // This field allows setting how many replicated instances of the Component, + // with the specific overrides in the InstanceTemplate, are created. + // The default value is 1. A value of 0 disables instance creation. + // + // +kubebuilder:default=1 + // +kubebuilder:validation:Minimum=0 + // +optional + Replicas *int32 `json:"replicas,omitempty"` + + // Specifies a map of key-value pairs to be merged into the Pod's existing annotations. + // Existing keys will have their values overwritten, while new keys will be added to the annotations. + // + // +optional + Annotations map[string]string `json:"annotations,omitempty"` + + // Specifies a map of key-value pairs that will be merged into the Pod's existing labels. + // Values for existing keys will be overwritten, and new keys will be added. + // + // +optional + Labels map[string]string `json:"labels,omitempty"` + + // Specifies an override for the first container's image in the Pod. + // + // +optional + Image *string `json:"image,omitempty"` + + // Specifies the scheduling policy for the Component. + // + // +optional + SchedulingPolicy *SchedulingPolicy `json:"schedulingPolicy,omitempty"` + + // Specifies an override for the resource requirements of the first container in the Pod. + // This field allows for customizing resource allocation (CPU, memory, etc.) for the container. + // + // +optional + Resources *corev1.ResourceRequirements `json:"resources,omitempty"` + + // Defines Env to override. + // Add new or override existing envs. + // +optional + Env []corev1.EnvVar `json:"env,omitempty"` + + // Defines Volumes to override. + // Add new or override existing volumes. + // +optional + Volumes []corev1.Volume `json:"volumes,omitempty"` + + // Defines VolumeMounts to override. + // Add new or override existing volume mounts of the first container in the Pod. + // +optional + VolumeMounts []corev1.VolumeMount `json:"volumeMounts,omitempty"` + + // Defines VolumeClaimTemplates to override. + // Add new or override existing volume claim templates. + // +optional + VolumeClaimTemplates []ClusterComponentVolumeClaimTemplate `json:"volumeClaimTemplates,omitempty"` +} diff --git a/apis/apps/v1/zz_generated.deepcopy.go b/apis/apps/v1/zz_generated.deepcopy.go index ede99714e5b..f0eb9d031e1 100644 --- a/apis/apps/v1/zz_generated.deepcopy.go +++ b/apis/apps/v1/zz_generated.deepcopy.go @@ -24,10 +24,44 @@ along with this program. If not, see . package v1 import ( + appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" + rbacv1 "k8s.io/api/rbac/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/util/intstr" ) +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Action) DeepCopyInto(out *Action) { + *out = *in + if in.Exec != nil { + in, out := &in.Exec, &out.Exec + *out = new(ExecAction) + (*in).DeepCopyInto(*out) + } + if in.RetryPolicy != nil { + in, out := &in.RetryPolicy, &out.RetryPolicy + *out = new(RetryPolicy) + **out = **in + } + if in.PreCondition != nil { + in, out := &in.PreCondition, &out.PreCondition + *out = new(PreConditionType) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Action. +func (in *Action) DeepCopy() *Action { + if in == nil { + return nil + } + out := new(Action) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Cluster) DeepCopyInto(out *Cluster) { *out = *in @@ -55,6 +89,63 @@ func (in *Cluster) DeepCopyObject() runtime.Object { return nil } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterComponentConfig) DeepCopyInto(out *ClusterComponentConfig) { + *out = *in + if in.Name != nil { + in, out := &in.Name, &out.Name + *out = new(string) + **out = **in + } + in.ClusterComponentConfigSource.DeepCopyInto(&out.ClusterComponentConfigSource) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterComponentConfig. +func (in *ClusterComponentConfig) DeepCopy() *ClusterComponentConfig { + if in == nil { + return nil + } + out := new(ClusterComponentConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterComponentConfigSource) DeepCopyInto(out *ClusterComponentConfigSource) { + *out = *in + if in.ConfigMap != nil { + in, out := &in.ConfigMap, &out.ConfigMap + *out = new(corev1.ConfigMapVolumeSource) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterComponentConfigSource. +func (in *ClusterComponentConfigSource) DeepCopy() *ClusterComponentConfigSource { + if in == nil { + return nil + } + out := new(ClusterComponentConfigSource) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterComponentVolumeClaimTemplate) DeepCopyInto(out *ClusterComponentVolumeClaimTemplate) { + *out = *in + in.Spec.DeepCopyInto(&out.Spec) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterComponentVolumeClaimTemplate. +func (in *ClusterComponentVolumeClaimTemplate) DeepCopy() *ClusterComponentVolumeClaimTemplate { + if in == nil { + return nil + } + out := new(ClusterComponentVolumeClaimTemplate) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ClusterDefinition) DeepCopyInto(out *ClusterDefinition) { *out = *in @@ -183,6 +274,31 @@ func (in *ClusterList) DeepCopyObject() runtime.Object { return nil } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterObjectReference) DeepCopyInto(out *ClusterObjectReference) { + *out = *in + if in.Optional != nil { + in, out := &in.Optional, &out.Optional + *out = new(bool) + **out = **in + } + if in.MultipleClusterObjectOption != nil { + in, out := &in.MultipleClusterObjectOption, &out.MultipleClusterObjectOption + *out = new(MultipleClusterObjectOption) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterObjectReference. +func (in *ClusterObjectReference) DeepCopy() *ClusterObjectReference { + if in == nil { + return nil + } + out := new(ClusterObjectReference) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ClusterSpec) DeepCopyInto(out *ClusterSpec) { *out = *in @@ -283,13 +399,59 @@ func (in *ClusterTopologyOrders) DeepCopy() *ClusterTopologyOrders { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterVarSelector) DeepCopyInto(out *ClusterVarSelector) { + *out = *in + in.ClusterVars.DeepCopyInto(&out.ClusterVars) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterVarSelector. +func (in *ClusterVarSelector) DeepCopy() *ClusterVarSelector { + if in == nil { + return nil + } + out := new(ClusterVarSelector) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterVars) DeepCopyInto(out *ClusterVars) { + *out = *in + if in.Namespace != nil { + in, out := &in.Namespace, &out.Namespace + *out = new(VarOption) + **out = **in + } + if in.ClusterName != nil { + in, out := &in.ClusterName, &out.ClusterName + *out = new(VarOption) + **out = **in + } + if in.ClusterUID != nil { + in, out := &in.ClusterUID, &out.ClusterUID + *out = new(VarOption) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterVars. +func (in *ClusterVars) DeepCopy() *ClusterVars { + if in == nil { + return nil + } + out := new(ClusterVars) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Component) DeepCopyInto(out *Component) { *out = *in out.TypeMeta = in.TypeMeta in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - out.Spec = in.Spec - out.Status = in.Status + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Component. @@ -310,12 +472,53 @@ func (in *Component) DeepCopyObject() runtime.Object { return nil } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ComponentConfigSpec) DeepCopyInto(out *ComponentConfigSpec) { + *out = *in + in.ComponentTemplateSpec.DeepCopyInto(&out.ComponentTemplateSpec) + if in.Keys != nil { + in, out := &in.Keys, &out.Keys + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.LegacyRenderedConfigSpec != nil { + in, out := &in.LegacyRenderedConfigSpec, &out.LegacyRenderedConfigSpec + *out = new(LegacyRenderedTemplateSpec) + **out = **in + } + if in.AsEnvFrom != nil { + in, out := &in.AsEnvFrom, &out.AsEnvFrom + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.InjectEnvTo != nil { + in, out := &in.InjectEnvTo, &out.InjectEnvTo + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.ReRenderResourceTypes != nil { + in, out := &in.ReRenderResourceTypes, &out.ReRenderResourceTypes + *out = make([]RerenderResourceType, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ComponentConfigSpec. +func (in *ComponentConfigSpec) DeepCopy() *ComponentConfigSpec { + if in == nil { + return nil + } + out := new(ComponentConfigSpec) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ComponentDefinition) DeepCopyInto(out *ComponentDefinition) { *out = *in out.TypeMeta = in.TypeMeta in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - out.Spec = in.Spec + in.Spec.DeepCopyInto(&out.Spec) out.Status = in.Status } @@ -372,6 +575,115 @@ func (in *ComponentDefinitionList) DeepCopyObject() runtime.Object { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ComponentDefinitionSpec) DeepCopyInto(out *ComponentDefinitionSpec) { *out = *in + if in.Labels != nil { + in, out := &in.Labels, &out.Labels + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.Annotations != nil { + in, out := &in.Annotations, &out.Annotations + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + in.Runtime.DeepCopyInto(&out.Runtime) + if in.Vars != nil { + in, out := &in.Vars, &out.Vars + *out = make([]EnvVar, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.Volumes != nil { + in, out := &in.Volumes, &out.Volumes + *out = make([]ComponentVolume, len(*in)) + copy(*out, *in) + } + if in.HostNetwork != nil { + in, out := &in.HostNetwork, &out.HostNetwork + *out = new(HostNetwork) + (*in).DeepCopyInto(*out) + } + if in.Services != nil { + in, out := &in.Services, &out.Services + *out = make([]ComponentService, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.Configs != nil { + in, out := &in.Configs, &out.Configs + *out = make([]ComponentConfigSpec, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.LogConfigs != nil { + in, out := &in.LogConfigs, &out.LogConfigs + *out = make([]LogConfig, len(*in)) + copy(*out, *in) + } + if in.Scripts != nil { + in, out := &in.Scripts, &out.Scripts + *out = make([]ComponentTemplateSpec, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.SystemAccounts != nil { + in, out := &in.SystemAccounts, &out.SystemAccounts + *out = make([]SystemAccount, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.ReplicasLimit != nil { + in, out := &in.ReplicasLimit, &out.ReplicasLimit + *out = new(ReplicasLimit) + **out = **in + } + if in.Roles != nil { + in, out := &in.Roles, &out.Roles + *out = make([]ReplicaRole, len(*in)) + copy(*out, *in) + } + if in.UpdateStrategy != nil { + in, out := &in.UpdateStrategy, &out.UpdateStrategy + *out = new(UpdateStrategy) + **out = **in + } + if in.PodManagementPolicy != nil { + in, out := &in.PodManagementPolicy, &out.PodManagementPolicy + *out = new(appsv1.PodManagementPolicyType) + **out = **in + } + if in.PolicyRules != nil { + in, out := &in.PolicyRules, &out.PolicyRules + *out = make([]rbacv1.PolicyRule, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.LifecycleActions != nil { + in, out := &in.LifecycleActions, &out.LifecycleActions + *out = new(ComponentLifecycleActions) + (*in).DeepCopyInto(*out) + } + if in.ServiceRefDeclarations != nil { + in, out := &in.ServiceRefDeclarations, &out.ServiceRefDeclarations + *out = make([]ServiceRefDeclaration, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.Exporter != nil { + in, out := &in.Exporter, &out.Exporter + *out = new(Exporter) + **out = **in + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ComponentDefinitionSpec. @@ -399,6 +711,81 @@ func (in *ComponentDefinitionStatus) DeepCopy() *ComponentDefinitionStatus { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ComponentLifecycleActions) DeepCopyInto(out *ComponentLifecycleActions) { + *out = *in + if in.PostProvision != nil { + in, out := &in.PostProvision, &out.PostProvision + *out = new(Action) + (*in).DeepCopyInto(*out) + } + if in.PreTerminate != nil { + in, out := &in.PreTerminate, &out.PreTerminate + *out = new(Action) + (*in).DeepCopyInto(*out) + } + if in.RoleProbe != nil { + in, out := &in.RoleProbe, &out.RoleProbe + *out = new(Probe) + (*in).DeepCopyInto(*out) + } + if in.Switchover != nil { + in, out := &in.Switchover, &out.Switchover + *out = new(Action) + (*in).DeepCopyInto(*out) + } + if in.MemberJoin != nil { + in, out := &in.MemberJoin, &out.MemberJoin + *out = new(Action) + (*in).DeepCopyInto(*out) + } + if in.MemberLeave != nil { + in, out := &in.MemberLeave, &out.MemberLeave + *out = new(Action) + (*in).DeepCopyInto(*out) + } + if in.Readonly != nil { + in, out := &in.Readonly, &out.Readonly + *out = new(Action) + (*in).DeepCopyInto(*out) + } + if in.Readwrite != nil { + in, out := &in.Readwrite, &out.Readwrite + *out = new(Action) + (*in).DeepCopyInto(*out) + } + if in.DataDump != nil { + in, out := &in.DataDump, &out.DataDump + *out = new(Action) + (*in).DeepCopyInto(*out) + } + if in.DataLoad != nil { + in, out := &in.DataLoad, &out.DataLoad + *out = new(Action) + (*in).DeepCopyInto(*out) + } + if in.Reconfigure != nil { + in, out := &in.Reconfigure, &out.Reconfigure + *out = new(Action) + (*in).DeepCopyInto(*out) + } + if in.AccountProvision != nil { + in, out := &in.AccountProvision, &out.AccountProvision + *out = new(Action) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ComponentLifecycleActions. +func (in *ComponentLifecycleActions) DeepCopy() *ComponentLifecycleActions { + if in == nil { + return nil + } + out := new(ComponentLifecycleActions) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ComponentList) DeepCopyInto(out *ComponentList) { *out = *in @@ -432,63 +819,331 @@ func (in *ComponentList) DeepCopyObject() runtime.Object { } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ComponentSpec) DeepCopyInto(out *ComponentSpec) { +func (in *ComponentService) DeepCopyInto(out *ComponentService) { *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ComponentSpec. -func (in *ComponentSpec) DeepCopy() *ComponentSpec { - if in == nil { - return nil + in.Service.DeepCopyInto(&out.Service) + if in.PodService != nil { + in, out := &in.PodService, &out.PodService + *out = new(bool) + **out = **in + } + if in.DisableAutoProvision != nil { + in, out := &in.DisableAutoProvision, &out.DisableAutoProvision + *out = new(bool) + **out = **in } - out := new(ComponentSpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ComponentStatus) DeepCopyInto(out *ComponentStatus) { - *out = *in } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ComponentStatus. -func (in *ComponentStatus) DeepCopy() *ComponentStatus { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ComponentService. +func (in *ComponentService) DeepCopy() *ComponentService { if in == nil { return nil } - out := new(ComponentStatus) + out := new(ComponentService) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ComponentVersion) DeepCopyInto(out *ComponentVersion) { +func (in *ComponentSpec) DeepCopyInto(out *ComponentSpec) { *out = *in - out.TypeMeta = in.TypeMeta - in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - in.Spec.DeepCopyInto(&out.Spec) - out.Status = in.Status -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ComponentVersion. -func (in *ComponentVersion) DeepCopy() *ComponentVersion { - if in == nil { - return nil + if in.ServiceRefs != nil { + in, out := &in.ServiceRefs, &out.ServiceRefs + *out = make([]ServiceRef, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } } - out := new(ComponentVersion) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *ComponentVersion) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c + if in.Labels != nil { + in, out := &in.Labels, &out.Labels + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. + if in.Annotations != nil { + in, out := &in.Annotations, &out.Annotations + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.Env != nil { + in, out := &in.Env, &out.Env + *out = make([]corev1.EnvVar, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + in.Resources.DeepCopyInto(&out.Resources) + if in.VolumeClaimTemplates != nil { + in, out := &in.VolumeClaimTemplates, &out.VolumeClaimTemplates + *out = make([]ClusterComponentVolumeClaimTemplate, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.Volumes != nil { + in, out := &in.Volumes, &out.Volumes + *out = make([]corev1.Volume, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.Services != nil { + in, out := &in.Services, &out.Services + *out = make([]ComponentService, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.SystemAccounts != nil { + in, out := &in.SystemAccounts, &out.SystemAccounts + *out = make([]ComponentSystemAccount, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.Configs != nil { + in, out := &in.Configs, &out.Configs + *out = make([]ClusterComponentConfig, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.EnabledLogs != nil { + in, out := &in.EnabledLogs, &out.EnabledLogs + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.ParallelPodManagementConcurrency != nil { + in, out := &in.ParallelPodManagementConcurrency, &out.ParallelPodManagementConcurrency + *out = new(intstr.IntOrString) + **out = **in + } + if in.PodUpdatePolicy != nil { + in, out := &in.PodUpdatePolicy, &out.PodUpdatePolicy + *out = new(PodUpdatePolicyType) + **out = **in + } + if in.SchedulingPolicy != nil { + in, out := &in.SchedulingPolicy, &out.SchedulingPolicy + *out = new(SchedulingPolicy) + (*in).DeepCopyInto(*out) + } + if in.TLSConfig != nil { + in, out := &in.TLSConfig, &out.TLSConfig + *out = new(TLSConfig) + (*in).DeepCopyInto(*out) + } + if in.Instances != nil { + in, out := &in.Instances, &out.Instances + *out = make([]InstanceTemplate, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.OfflineInstances != nil { + in, out := &in.OfflineInstances, &out.OfflineInstances + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.RuntimeClassName != nil { + in, out := &in.RuntimeClassName, &out.RuntimeClassName + *out = new(string) + **out = **in + } + if in.DisableExporter != nil { + in, out := &in.DisableExporter, &out.DisableExporter + *out = new(bool) + **out = **in + } + if in.Stop != nil { + in, out := &in.Stop, &out.Stop + *out = new(bool) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ComponentSpec. +func (in *ComponentSpec) DeepCopy() *ComponentSpec { + if in == nil { + return nil + } + out := new(ComponentSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ComponentStatus) DeepCopyInto(out *ComponentStatus) { + *out = *in + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]metav1.Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.Message != nil { + in, out := &in.Message, &out.Message + *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 ComponentStatus. +func (in *ComponentStatus) DeepCopy() *ComponentStatus { + if in == nil { + return nil + } + out := new(ComponentStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ComponentSystemAccount) DeepCopyInto(out *ComponentSystemAccount) { + *out = *in + if in.PasswordConfig != nil { + in, out := &in.PasswordConfig, &out.PasswordConfig + *out = new(PasswordConfig) + **out = **in + } + if in.SecretRef != nil { + in, out := &in.SecretRef, &out.SecretRef + *out = new(ProvisionSecretRef) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ComponentSystemAccount. +func (in *ComponentSystemAccount) DeepCopy() *ComponentSystemAccount { + if in == nil { + return nil + } + out := new(ComponentSystemAccount) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ComponentTemplateSpec) DeepCopyInto(out *ComponentTemplateSpec) { + *out = *in + if in.DefaultMode != nil { + in, out := &in.DefaultMode, &out.DefaultMode + *out = new(int32) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ComponentTemplateSpec. +func (in *ComponentTemplateSpec) DeepCopy() *ComponentTemplateSpec { + if in == nil { + return nil + } + out := new(ComponentTemplateSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ComponentVarSelector) DeepCopyInto(out *ComponentVarSelector) { + *out = *in + in.ClusterObjectReference.DeepCopyInto(&out.ClusterObjectReference) + in.ComponentVars.DeepCopyInto(&out.ComponentVars) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ComponentVarSelector. +func (in *ComponentVarSelector) DeepCopy() *ComponentVarSelector { + if in == nil { + return nil + } + out := new(ComponentVarSelector) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ComponentVars) DeepCopyInto(out *ComponentVars) { + *out = *in + if in.ComponentName != nil { + in, out := &in.ComponentName, &out.ComponentName + *out = new(VarOption) + **out = **in + } + if in.ShortName != nil { + in, out := &in.ShortName, &out.ShortName + *out = new(VarOption) + **out = **in + } + if in.Replicas != nil { + in, out := &in.Replicas, &out.Replicas + *out = new(VarOption) + **out = **in + } + if in.PodNames != nil { + in, out := &in.PodNames, &out.PodNames + *out = new(VarOption) + **out = **in + } + if in.PodFQDNs != nil { + in, out := &in.PodFQDNs, &out.PodFQDNs + *out = new(VarOption) + **out = **in + } + if in.PodNamesForRole != nil { + in, out := &in.PodNamesForRole, &out.PodNamesForRole + *out = new(RoledVar) + (*in).DeepCopyInto(*out) + } + if in.PodFQDNsForRole != nil { + in, out := &in.PodFQDNsForRole, &out.PodFQDNsForRole + *out = new(RoledVar) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ComponentVars. +func (in *ComponentVars) DeepCopy() *ComponentVars { + if in == nil { + return nil + } + out := new(ComponentVars) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ComponentVersion) DeepCopyInto(out *ComponentVersion) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + out.Status = in.Status +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ComponentVersion. +func (in *ComponentVersion) DeepCopy() *ComponentVersion { + if in == nil { + return nil + } + out := new(ComponentVersion) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ComponentVersion) 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 *ComponentVersionCompatibilityRule) DeepCopyInto(out *ComponentVersionCompatibilityRule) { *out = *in if in.CompDefs != nil { @@ -611,6 +1266,36 @@ func (in *ComponentVersionStatus) DeepCopy() *ComponentVersionStatus { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ComponentVolume) DeepCopyInto(out *ComponentVolume) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ComponentVolume. +func (in *ComponentVolume) DeepCopy() *ComponentVolume { + if in == nil { + return nil + } + out := new(ComponentVolume) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ConfigTemplateExtension) DeepCopyInto(out *ConfigTemplateExtension) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ConfigTemplateExtension. +func (in *ConfigTemplateExtension) DeepCopy() *ConfigTemplateExtension { + if in == nil { + return nil + } + out := new(ConfigTemplateExtension) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ConnectionCredentialAuth) DeepCopyInto(out *ConnectionCredentialAuth) { *out = *in @@ -636,6 +1321,26 @@ func (in *ConnectionCredentialAuth) DeepCopy() *ConnectionCredentialAuth { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ContainerVars) DeepCopyInto(out *ContainerVars) { + *out = *in + if in.Port != nil { + in, out := &in.Port, &out.Port + *out = new(NamedVar) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ContainerVars. +func (in *ContainerVars) DeepCopy() *ContainerVars { + if in == nil { + return nil + } + out := new(ContainerVars) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *CredentialVar) DeepCopyInto(out *CredentialVar) { *out = *in @@ -657,81 +1362,688 @@ func (in *CredentialVar) DeepCopy() *CredentialVar { } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ServiceDescriptor) DeepCopyInto(out *ServiceDescriptor) { +func (in *CredentialVarSelector) DeepCopyInto(out *CredentialVarSelector) { *out = *in - out.TypeMeta = in.TypeMeta - in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - in.Spec.DeepCopyInto(&out.Spec) - out.Status = in.Status + in.ClusterObjectReference.DeepCopyInto(&out.ClusterObjectReference) + in.CredentialVars.DeepCopyInto(&out.CredentialVars) } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceDescriptor. -func (in *ServiceDescriptor) DeepCopy() *ServiceDescriptor { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CredentialVarSelector. +func (in *CredentialVarSelector) DeepCopy() *CredentialVarSelector { if in == nil { return nil } - out := new(ServiceDescriptor) + out := new(CredentialVarSelector) in.DeepCopyInto(out) return out } -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *ServiceDescriptor) 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 *ServiceDescriptorList) DeepCopyInto(out *ServiceDescriptorList) { +func (in *CredentialVars) DeepCopyInto(out *CredentialVars) { *out = *in - out.TypeMeta = in.TypeMeta - in.ListMeta.DeepCopyInto(&out.ListMeta) - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]ServiceDescriptor, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } + if in.Username != nil { + in, out := &in.Username, &out.Username + *out = new(VarOption) + **out = **in + } + if in.Password != nil { + in, out := &in.Password, &out.Password + *out = new(VarOption) + **out = **in } } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceDescriptorList. -func (in *ServiceDescriptorList) DeepCopy() *ServiceDescriptorList { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CredentialVars. +func (in *CredentialVars) DeepCopy() *CredentialVars { if in == nil { return nil } - out := new(ServiceDescriptorList) + out := new(CredentialVars) in.DeepCopyInto(out) return out } -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *ServiceDescriptorList) 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 *ServiceDescriptorSpec) DeepCopyInto(out *ServiceDescriptorSpec) { +func (in *EnvVar) DeepCopyInto(out *EnvVar) { *out = *in - if in.Endpoint != nil { - in, out := &in.Endpoint, &out.Endpoint - *out = new(CredentialVar) - (*in).DeepCopyInto(*out) - } - if in.Host != nil { - in, out := &in.Host, &out.Host - *out = new(CredentialVar) + if in.ValueFrom != nil { + in, out := &in.ValueFrom, &out.ValueFrom + *out = new(VarSource) (*in).DeepCopyInto(*out) } - if in.Port != nil { - in, out := &in.Port, &out.Port - *out = new(CredentialVar) - (*in).DeepCopyInto(*out) + if in.Expression != nil { + in, out := &in.Expression, &out.Expression + *out = new(string) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EnvVar. +func (in *EnvVar) DeepCopy() *EnvVar { + if in == nil { + return nil + } + out := new(EnvVar) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ExecAction) DeepCopyInto(out *ExecAction) { + *out = *in + if in.Env != nil { + in, out := &in.Env, &out.Env + *out = make([]corev1.EnvVar, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.Command != nil { + in, out := &in.Command, &out.Command + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.Args != nil { + in, out := &in.Args, &out.Args + *out = make([]string, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExecAction. +func (in *ExecAction) DeepCopy() *ExecAction { + if in == nil { + return nil + } + out := new(ExecAction) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Exporter) DeepCopyInto(out *Exporter) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Exporter. +func (in *Exporter) DeepCopy() *Exporter { + if in == nil { + return nil + } + out := new(Exporter) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *HostNetwork) DeepCopyInto(out *HostNetwork) { + *out = *in + if in.ContainerPorts != nil { + in, out := &in.ContainerPorts, &out.ContainerPorts + *out = make([]HostNetworkContainerPort, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HostNetwork. +func (in *HostNetwork) DeepCopy() *HostNetwork { + if in == nil { + return nil + } + out := new(HostNetwork) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *HostNetworkContainerPort) DeepCopyInto(out *HostNetworkContainerPort) { + *out = *in + if in.Ports != nil { + in, out := &in.Ports, &out.Ports + *out = make([]string, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HostNetworkContainerPort. +func (in *HostNetworkContainerPort) DeepCopy() *HostNetworkContainerPort { + if in == nil { + return nil + } + out := new(HostNetworkContainerPort) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *HostNetworkVarSelector) DeepCopyInto(out *HostNetworkVarSelector) { + *out = *in + in.ClusterObjectReference.DeepCopyInto(&out.ClusterObjectReference) + in.HostNetworkVars.DeepCopyInto(&out.HostNetworkVars) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HostNetworkVarSelector. +func (in *HostNetworkVarSelector) DeepCopy() *HostNetworkVarSelector { + if in == nil { + return nil + } + out := new(HostNetworkVarSelector) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *HostNetworkVars) DeepCopyInto(out *HostNetworkVars) { + *out = *in + if in.Container != nil { + in, out := &in.Container, &out.Container + *out = new(ContainerVars) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HostNetworkVars. +func (in *HostNetworkVars) DeepCopy() *HostNetworkVars { + if in == nil { + return nil + } + out := new(HostNetworkVars) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *InstanceTemplate) DeepCopyInto(out *InstanceTemplate) { + *out = *in + if in.Replicas != nil { + in, out := &in.Replicas, &out.Replicas + *out = new(int32) + **out = **in + } + if in.Annotations != nil { + in, out := &in.Annotations, &out.Annotations + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.Labels != nil { + in, out := &in.Labels, &out.Labels + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.Image != nil { + in, out := &in.Image, &out.Image + *out = new(string) + **out = **in + } + if in.SchedulingPolicy != nil { + in, out := &in.SchedulingPolicy, &out.SchedulingPolicy + *out = new(SchedulingPolicy) + (*in).DeepCopyInto(*out) + } + if in.Resources != nil { + in, out := &in.Resources, &out.Resources + *out = new(corev1.ResourceRequirements) + (*in).DeepCopyInto(*out) + } + if in.Env != nil { + in, out := &in.Env, &out.Env + *out = make([]corev1.EnvVar, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.Volumes != nil { + in, out := &in.Volumes, &out.Volumes + *out = make([]corev1.Volume, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.VolumeMounts != nil { + in, out := &in.VolumeMounts, &out.VolumeMounts + *out = make([]corev1.VolumeMount, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.VolumeClaimTemplates != nil { + in, out := &in.VolumeClaimTemplates, &out.VolumeClaimTemplates + *out = make([]ClusterComponentVolumeClaimTemplate, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InstanceTemplate. +func (in *InstanceTemplate) DeepCopy() *InstanceTemplate { + if in == nil { + return nil + } + out := new(InstanceTemplate) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Issuer) DeepCopyInto(out *Issuer) { + *out = *in + if in.SecretRef != nil { + in, out := &in.SecretRef, &out.SecretRef + *out = new(TLSSecretRef) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Issuer. +func (in *Issuer) DeepCopy() *Issuer { + if in == nil { + return nil + } + out := new(Issuer) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *LegacyRenderedTemplateSpec) DeepCopyInto(out *LegacyRenderedTemplateSpec) { + *out = *in + out.ConfigTemplateExtension = in.ConfigTemplateExtension +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LegacyRenderedTemplateSpec. +func (in *LegacyRenderedTemplateSpec) DeepCopy() *LegacyRenderedTemplateSpec { + if in == nil { + return nil + } + out := new(LegacyRenderedTemplateSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *LogConfig) DeepCopyInto(out *LogConfig) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LogConfig. +func (in *LogConfig) DeepCopy() *LogConfig { + if in == nil { + return nil + } + out := new(LogConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MultipleClusterObjectCombinedOption) DeepCopyInto(out *MultipleClusterObjectCombinedOption) { + *out = *in + if in.NewVarSuffix != nil { + in, out := &in.NewVarSuffix, &out.NewVarSuffix + *out = new(string) + **out = **in + } + if in.FlattenFormat != nil { + in, out := &in.FlattenFormat, &out.FlattenFormat + *out = new(MultipleClusterObjectValueFormatFlatten) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MultipleClusterObjectCombinedOption. +func (in *MultipleClusterObjectCombinedOption) DeepCopy() *MultipleClusterObjectCombinedOption { + if in == nil { + return nil + } + out := new(MultipleClusterObjectCombinedOption) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MultipleClusterObjectOption) DeepCopyInto(out *MultipleClusterObjectOption) { + *out = *in + if in.CombinedOption != nil { + in, out := &in.CombinedOption, &out.CombinedOption + *out = new(MultipleClusterObjectCombinedOption) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MultipleClusterObjectOption. +func (in *MultipleClusterObjectOption) DeepCopy() *MultipleClusterObjectOption { + if in == nil { + return nil + } + out := new(MultipleClusterObjectOption) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MultipleClusterObjectValueFormatFlatten) DeepCopyInto(out *MultipleClusterObjectValueFormatFlatten) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MultipleClusterObjectValueFormatFlatten. +func (in *MultipleClusterObjectValueFormatFlatten) DeepCopy() *MultipleClusterObjectValueFormatFlatten { + if in == nil { + return nil + } + out := new(MultipleClusterObjectValueFormatFlatten) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NamedVar) DeepCopyInto(out *NamedVar) { + *out = *in + if in.Option != nil { + in, out := &in.Option, &out.Option + *out = new(VarOption) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NamedVar. +func (in *NamedVar) DeepCopy() *NamedVar { + if in == nil { + return nil + } + out := new(NamedVar) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PasswordConfig) DeepCopyInto(out *PasswordConfig) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PasswordConfig. +func (in *PasswordConfig) DeepCopy() *PasswordConfig { + if in == nil { + return nil + } + out := new(PasswordConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PersistentVolumeClaimSpec) DeepCopyInto(out *PersistentVolumeClaimSpec) { + *out = *in + if in.AccessModes != nil { + in, out := &in.AccessModes, &out.AccessModes + *out = make([]corev1.PersistentVolumeAccessMode, len(*in)) + copy(*out, *in) + } + in.Resources.DeepCopyInto(&out.Resources) + if in.StorageClassName != nil { + in, out := &in.StorageClassName, &out.StorageClassName + *out = new(string) + **out = **in + } + if in.VolumeMode != nil { + in, out := &in.VolumeMode, &out.VolumeMode + *out = new(corev1.PersistentVolumeMode) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PersistentVolumeClaimSpec. +func (in *PersistentVolumeClaimSpec) DeepCopy() *PersistentVolumeClaimSpec { + if in == nil { + return nil + } + out := new(PersistentVolumeClaimSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Probe) DeepCopyInto(out *Probe) { + *out = *in + in.Action.DeepCopyInto(&out.Action) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Probe. +func (in *Probe) DeepCopy() *Probe { + if in == nil { + return nil + } + out := new(Probe) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ProvisionSecretRef) DeepCopyInto(out *ProvisionSecretRef) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProvisionSecretRef. +func (in *ProvisionSecretRef) DeepCopy() *ProvisionSecretRef { + if in == nil { + return nil + } + out := new(ProvisionSecretRef) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ReplicaRole) DeepCopyInto(out *ReplicaRole) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ReplicaRole. +func (in *ReplicaRole) DeepCopy() *ReplicaRole { + if in == nil { + return nil + } + out := new(ReplicaRole) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ReplicasLimit) DeepCopyInto(out *ReplicasLimit) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ReplicasLimit. +func (in *ReplicasLimit) DeepCopy() *ReplicasLimit { + if in == nil { + return nil + } + out := new(ReplicasLimit) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RetryPolicy) DeepCopyInto(out *RetryPolicy) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RetryPolicy. +func (in *RetryPolicy) DeepCopy() *RetryPolicy { + if in == nil { + return nil + } + out := new(RetryPolicy) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RoledVar) DeepCopyInto(out *RoledVar) { + *out = *in + if in.Option != nil { + in, out := &in.Option, &out.Option + *out = new(VarOption) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RoledVar. +func (in *RoledVar) DeepCopy() *RoledVar { + if in == nil { + return nil + } + out := new(RoledVar) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SchedulingPolicy) DeepCopyInto(out *SchedulingPolicy) { + *out = *in + if in.NodeSelector != nil { + in, out := &in.NodeSelector, &out.NodeSelector + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.Affinity != nil { + in, out := &in.Affinity, &out.Affinity + *out = new(corev1.Affinity) + (*in).DeepCopyInto(*out) + } + if in.Tolerations != nil { + in, out := &in.Tolerations, &out.Tolerations + *out = make([]corev1.Toleration, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.TopologySpreadConstraints != nil { + in, out := &in.TopologySpreadConstraints, &out.TopologySpreadConstraints + *out = make([]corev1.TopologySpreadConstraint, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SchedulingPolicy. +func (in *SchedulingPolicy) DeepCopy() *SchedulingPolicy { + if in == nil { + return nil + } + out := new(SchedulingPolicy) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Service) DeepCopyInto(out *Service) { + *out = *in + if in.Annotations != nil { + in, out := &in.Annotations, &out.Annotations + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + in.Spec.DeepCopyInto(&out.Spec) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Service. +func (in *Service) DeepCopy() *Service { + if in == nil { + return nil + } + out := new(Service) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ServiceDescriptor) DeepCopyInto(out *ServiceDescriptor) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + out.Status = in.Status +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceDescriptor. +func (in *ServiceDescriptor) DeepCopy() *ServiceDescriptor { + if in == nil { + return nil + } + out := new(ServiceDescriptor) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ServiceDescriptor) 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 *ServiceDescriptorList) DeepCopyInto(out *ServiceDescriptorList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]ServiceDescriptor, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceDescriptorList. +func (in *ServiceDescriptorList) DeepCopy() *ServiceDescriptorList { + if in == nil { + return nil + } + out := new(ServiceDescriptorList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ServiceDescriptorList) 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 *ServiceDescriptorSpec) DeepCopyInto(out *ServiceDescriptorSpec) { + *out = *in + if in.Endpoint != nil { + in, out := &in.Endpoint, &out.Endpoint + *out = new(CredentialVar) + (*in).DeepCopyInto(*out) + } + if in.Host != nil { + in, out := &in.Host, &out.Host + *out = new(CredentialVar) + (*in).DeepCopyInto(*out) + } + if in.Port != nil { + in, out := &in.Port, &out.Port + *out = new(CredentialVar) + (*in).DeepCopyInto(*out) } if in.Auth != nil { in, out := &in.Auth, &out.Auth @@ -764,3 +2076,329 @@ func (in *ServiceDescriptorStatus) DeepCopy() *ServiceDescriptorStatus { in.DeepCopyInto(out) return out } + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ServiceRef) DeepCopyInto(out *ServiceRef) { + *out = *in + if in.ClusterServiceSelector != nil { + in, out := &in.ClusterServiceSelector, &out.ClusterServiceSelector + *out = new(ServiceRefClusterSelector) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceRef. +func (in *ServiceRef) DeepCopy() *ServiceRef { + if in == nil { + return nil + } + out := new(ServiceRef) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ServiceRefClusterSelector) DeepCopyInto(out *ServiceRefClusterSelector) { + *out = *in + if in.Service != nil { + in, out := &in.Service, &out.Service + *out = new(ServiceRefServiceSelector) + **out = **in + } + if in.Credential != nil { + in, out := &in.Credential, &out.Credential + *out = new(ServiceRefCredentialSelector) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceRefClusterSelector. +func (in *ServiceRefClusterSelector) DeepCopy() *ServiceRefClusterSelector { + if in == nil { + return nil + } + out := new(ServiceRefClusterSelector) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ServiceRefCredentialSelector) DeepCopyInto(out *ServiceRefCredentialSelector) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceRefCredentialSelector. +func (in *ServiceRefCredentialSelector) DeepCopy() *ServiceRefCredentialSelector { + if in == nil { + return nil + } + out := new(ServiceRefCredentialSelector) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ServiceRefDeclaration) DeepCopyInto(out *ServiceRefDeclaration) { + *out = *in + if in.ServiceRefDeclarationSpecs != nil { + in, out := &in.ServiceRefDeclarationSpecs, &out.ServiceRefDeclarationSpecs + *out = make([]ServiceRefDeclarationSpec, len(*in)) + copy(*out, *in) + } + if in.Optional != nil { + in, out := &in.Optional, &out.Optional + *out = new(bool) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceRefDeclaration. +func (in *ServiceRefDeclaration) DeepCopy() *ServiceRefDeclaration { + if in == nil { + return nil + } + out := new(ServiceRefDeclaration) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ServiceRefDeclarationSpec) DeepCopyInto(out *ServiceRefDeclarationSpec) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceRefDeclarationSpec. +func (in *ServiceRefDeclarationSpec) DeepCopy() *ServiceRefDeclarationSpec { + if in == nil { + return nil + } + out := new(ServiceRefDeclarationSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ServiceRefServiceSelector) DeepCopyInto(out *ServiceRefServiceSelector) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceRefServiceSelector. +func (in *ServiceRefServiceSelector) DeepCopy() *ServiceRefServiceSelector { + if in == nil { + return nil + } + out := new(ServiceRefServiceSelector) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ServiceRefVarSelector) DeepCopyInto(out *ServiceRefVarSelector) { + *out = *in + in.ClusterObjectReference.DeepCopyInto(&out.ClusterObjectReference) + in.ServiceRefVars.DeepCopyInto(&out.ServiceRefVars) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceRefVarSelector. +func (in *ServiceRefVarSelector) DeepCopy() *ServiceRefVarSelector { + if in == nil { + return nil + } + out := new(ServiceRefVarSelector) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ServiceRefVars) DeepCopyInto(out *ServiceRefVars) { + *out = *in + if in.Endpoint != nil { + in, out := &in.Endpoint, &out.Endpoint + *out = new(VarOption) + **out = **in + } + if in.Host != nil { + in, out := &in.Host, &out.Host + *out = new(VarOption) + **out = **in + } + if in.Port != nil { + in, out := &in.Port, &out.Port + *out = new(VarOption) + **out = **in + } + in.CredentialVars.DeepCopyInto(&out.CredentialVars) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceRefVars. +func (in *ServiceRefVars) DeepCopy() *ServiceRefVars { + if in == nil { + return nil + } + out := new(ServiceRefVars) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ServiceVarSelector) DeepCopyInto(out *ServiceVarSelector) { + *out = *in + in.ClusterObjectReference.DeepCopyInto(&out.ClusterObjectReference) + in.ServiceVars.DeepCopyInto(&out.ServiceVars) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceVarSelector. +func (in *ServiceVarSelector) DeepCopy() *ServiceVarSelector { + if in == nil { + return nil + } + out := new(ServiceVarSelector) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ServiceVars) DeepCopyInto(out *ServiceVars) { + *out = *in + if in.ServiceType != nil { + in, out := &in.ServiceType, &out.ServiceType + *out = new(VarOption) + **out = **in + } + if in.Host != nil { + in, out := &in.Host, &out.Host + *out = new(VarOption) + **out = **in + } + if in.LoadBalancer != nil { + in, out := &in.LoadBalancer, &out.LoadBalancer + *out = new(VarOption) + **out = **in + } + if in.Port != nil { + in, out := &in.Port, &out.Port + *out = new(NamedVar) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceVars. +func (in *ServiceVars) DeepCopy() *ServiceVars { + if in == nil { + return nil + } + out := new(ServiceVars) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SystemAccount) DeepCopyInto(out *SystemAccount) { + *out = *in + out.PasswordGenerationPolicy = in.PasswordGenerationPolicy + if in.SecretRef != nil { + in, out := &in.SecretRef, &out.SecretRef + *out = new(ProvisionSecretRef) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SystemAccount. +func (in *SystemAccount) DeepCopy() *SystemAccount { + if in == nil { + return nil + } + out := new(SystemAccount) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *TLSConfig) DeepCopyInto(out *TLSConfig) { + *out = *in + if in.Issuer != nil { + in, out := &in.Issuer, &out.Issuer + *out = new(Issuer) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TLSConfig. +func (in *TLSConfig) DeepCopy() *TLSConfig { + if in == nil { + return nil + } + out := new(TLSConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *TLSSecretRef) DeepCopyInto(out *TLSSecretRef) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TLSSecretRef. +func (in *TLSSecretRef) DeepCopy() *TLSSecretRef { + if in == nil { + return nil + } + out := new(TLSSecretRef) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VarSource) DeepCopyInto(out *VarSource) { + *out = *in + if in.ConfigMapKeyRef != nil { + in, out := &in.ConfigMapKeyRef, &out.ConfigMapKeyRef + *out = new(corev1.ConfigMapKeySelector) + (*in).DeepCopyInto(*out) + } + if in.SecretKeyRef != nil { + in, out := &in.SecretKeyRef, &out.SecretKeyRef + *out = new(corev1.SecretKeySelector) + (*in).DeepCopyInto(*out) + } + if in.HostNetworkVarRef != nil { + in, out := &in.HostNetworkVarRef, &out.HostNetworkVarRef + *out = new(HostNetworkVarSelector) + (*in).DeepCopyInto(*out) + } + if in.ServiceVarRef != nil { + in, out := &in.ServiceVarRef, &out.ServiceVarRef + *out = new(ServiceVarSelector) + (*in).DeepCopyInto(*out) + } + if in.CredentialVarRef != nil { + in, out := &in.CredentialVarRef, &out.CredentialVarRef + *out = new(CredentialVarSelector) + (*in).DeepCopyInto(*out) + } + if in.ServiceRefVarRef != nil { + in, out := &in.ServiceRefVarRef, &out.ServiceRefVarRef + *out = new(ServiceRefVarSelector) + (*in).DeepCopyInto(*out) + } + if in.ComponentVarRef != nil { + in, out := &in.ComponentVarRef, &out.ComponentVarRef + *out = new(ComponentVarSelector) + (*in).DeepCopyInto(*out) + } + if in.ClusterVarRef != nil { + in, out := &in.ClusterVarRef, &out.ClusterVarRef + *out = new(ClusterVarSelector) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VarSource. +func (in *VarSource) DeepCopy() *VarSource { + if in == nil { + return nil + } + out := new(VarSource) + in.DeepCopyInto(out) + return out +} diff --git a/apis/apps/v1alpha1/component_conversion.go b/apis/apps/v1alpha1/component_conversion.go index 71549e8098b..cdd140b423a 100644 --- a/apis/apps/v1alpha1/component_conversion.go +++ b/apis/apps/v1alpha1/component_conversion.go @@ -20,15 +20,46 @@ along with this program. If not, see . package v1alpha1 import ( + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" "sigs.k8s.io/controller-runtime/pkg/conversion" ) // ConvertTo converts this Component to the Hub version (v1). func (r *Component) ConvertTo(dstRaw conversion.Hub) error { + dst := dstRaw.(*appsv1.Component) + + // objectMeta + dst.ObjectMeta = r.ObjectMeta + + // spec + dst.Spec.CompatibilityRules = r.compatibilityRulesTo(r.Spec.CompatibilityRules) + dst.Spec.Releases = r.releasesTo(r.Spec.Releases) + + // status + dst.Status.ObservedGeneration = r.Status.ObservedGeneration + dst.Status.Phase = appsv1.Phase(r.Status.Phase) + dst.Status.Message = r.Status.Message + dst.Status.ServiceVersions = r.Status.ServiceVersions + return nil } // ConvertFrom converts from the Hub version (v1) to this version. func (r *Component) ConvertFrom(srcRaw conversion.Hub) error { + src := srcRaw.(*appsv1.Component) + + // objectMeta + r.ObjectMeta = src.ObjectMeta + + // spec + r.Spec.CompatibilityRules = r.compatibilityRulesFrom(src.Spec.CompatibilityRules) + r.Spec.Releases = r.releasesFrom(src.Spec.Releases) + + // status + r.Status.ObservedGeneration = src.Status.ObservedGeneration + r.Status.Phase = Phase(src.Status.Phase) + r.Status.Message = src.Status.Message + r.Status.ServiceVersions = src.Status.ServiceVersions + return nil } diff --git a/config/crd/bases/apps.kubeblocks.io_componentdefinitions.yaml b/config/crd/bases/apps.kubeblocks.io_componentdefinitions.yaml index 6ee9d7c1abb..4360700ec17 100644 --- a/config/crd/bases/apps.kubeblocks.io_componentdefinitions.yaml +++ b/config/crd/bases/apps.kubeblocks.io_componentdefinitions.yaml @@ -86,15 +86,13040 @@ spec: metadata: type: object spec: - description: ComponentDefinitionSpec defines the desired state of ComponentDefinition properties: - foo: - description: Foo is an example field of ComponentDefinition. Edit - componentdefinition_types.go to remove/update + annotations: + additionalProperties: + type: string + description: |- + Specifies static annotations that will be patched to all Kubernetes resources created for the Component. + + + Note: If an annotation key in the `annotations` field conflicts with any system annotations + or user-specified annotations, it will be silently ignored to avoid overriding higher-priority annotations. + + + This field is immutable. + type: object + configs: + description: |- + Specifies the configuration file templates and volume mount parameters used by the Component. + It also includes descriptions of the parameters in the ConfigMaps, such as value range limitations. + + + This field specifies a list of templates that will be rendered into Component containers' configuration files. + Each template is represented as a ConfigMap and may contain multiple configuration files, + with each file being a key in the ConfigMap. + + + The rendered configuration files will be mounted into the Component's containers + according to the specified volume mount parameters. + + + This field is immutable. + items: + properties: + asEnvFrom: + description: |- + Specifies the containers to inject the ConfigMap parameters as environment variables. + + + This is useful when application images accept parameters through environment variables and + generate the final configuration file in the startup script based on these variables. + + + This field allows users to specify a list of container names, and KubeBlocks will inject the environment + variables converted from the ConfigMap into these designated containers. This provides a flexible way to + pass the configuration items from the ConfigMap to the container without modifying the image. + + + Deprecated: `asEnvFrom` has been deprecated since 0.9.0 and will be removed in 0.10.0. + Use `injectEnvTo` instead. + items: + type: string + type: array + x-kubernetes-list-type: set + constraintRef: + description: Specifies the name of the referenced configuration + constraints object. + maxLength: 63 + pattern: ^[a-z0-9]([a-z0-9\.\-]*[a-z0-9])?$ + type: string + defaultMode: + description: |- + The operator attempts to set default file permissions for scripts (0555) and configurations (0444). + However, certain database engines may require different file permissions. + You can specify the desired file permissions here. + + + Must be specified as an octal value between 0000 and 0777 (inclusive), + or as a decimal value between 0 and 511 (inclusive). + YAML supports both octal and decimal values for file permissions. + + + Please note that this setting only affects the permissions of the files themselves. + Directories within the specified path are not impacted by this setting. + It's important to be aware that this setting might conflict with other options + that influence the file mode, such as fsGroup. + In such cases, the resulting file mode may have additional bits set. + Refers to documents of k8s.ConfigMapVolumeSource.defaultMode for more information. + format: int32 + type: integer + injectEnvTo: + description: |- + Specifies the containers to inject the ConfigMap parameters as environment variables. + + + This is useful when application images accept parameters through environment variables and + generate the final configuration file in the startup script based on these variables. + + + This field allows users to specify a list of container names, and KubeBlocks will inject the environment + variables converted from the ConfigMap into these designated containers. This provides a flexible way to + pass the configuration items from the ConfigMap to the container without modifying the image. + items: + type: string + type: array + x-kubernetes-list-type: set + keys: + description: |- + Specifies the configuration files within the ConfigMap that support dynamic updates. + + + A configuration template (provided in the form of a ConfigMap) may contain templates for multiple + configuration files. + Each configuration file corresponds to a key in the ConfigMap. + Some of these configuration files may support dynamic modification and reloading without requiring + a pod restart. + + + If empty or omitted, all configuration files in the ConfigMap are assumed to support dynamic updates, + and ConfigConstraint applies to all keys. + items: + type: string + type: array + x-kubernetes-list-type: set + legacyRenderedConfigSpec: + description: |- + Specifies the secondary rendered config spec for pod-specific customization. + + + The template is rendered inside the pod (by the "config-manager" sidecar container) and merged with the main + template's render result to generate the final configuration file. + + + This field is intended to handle scenarios where different pods within the same Component have + varying configurations. It allows for pod-specific customization of the configuration. + + + Note: This field will be deprecated in future versions, and the functionality will be moved to + `cluster.spec.componentSpecs[*].instances[*]`. + properties: + namespace: + default: default + description: |- + Specifies the namespace of the referenced configuration template ConfigMap object. + An empty namespace is equivalent to the "default" namespace. + pattern: ^[a-z0-9]([a-z0-9\-]*[a-z0-9])?$ + type: string + policy: + default: none + description: Defines the strategy for merging externally + imported templates into component templates. + enum: + - patch + - replace + - none + type: string + templateRef: + description: Specifies the name of the referenced configuration + template ConfigMap object. + pattern: ^[a-z0-9]([a-z0-9\.\-]*[a-z0-9])?$ + type: string + required: + - templateRef + type: object + name: + description: Specifies the name of the configuration template. + maxLength: 63 + pattern: ^[a-z0-9]([a-z0-9\.\-]*[a-z0-9])?$ + type: string + namespace: + default: default + description: |- + Specifies the namespace of the referenced configuration template ConfigMap object. + An empty namespace is equivalent to the "default" namespace. + maxLength: 63 + pattern: ^[a-z0-9]([a-z0-9\-]*[a-z0-9])?$ + type: string + reRenderResourceTypes: + description: |- + Specifies whether the configuration needs to be re-rendered after v-scale or h-scale operations to reflect changes. + + + In some scenarios, the configuration may need to be updated to reflect the changes in resource allocation + or cluster topology. Examples: + + + - Redis: adjust maxmemory after v-scale operation. + - MySQL: increase max connections after v-scale operation. + - Zookeeper: update zoo.cfg with new node addresses after h-scale operation. + items: + description: RerenderResourceType defines the resource requirements + for a component. + enum: + - vscale + - hscale + - tls + type: string + type: array + x-kubernetes-list-type: set + templateRef: + description: Specifies the name of the referenced configuration + template ConfigMap object. + maxLength: 63 + pattern: ^[a-z0-9]([a-z0-9\.\-]*[a-z0-9])?$ + type: string + volumeName: + description: |- + Refers to the volume name of PodTemplate. The configuration file produced through the configuration + template will be mounted to the corresponding volume. Must be a DNS_LABEL name. + The volume name must be defined in podSpec.containers[*].volumeMounts. + maxLength: 63 + pattern: ^[a-z]([a-z0-9\-]*[a-z0-9])?$ + type: string + required: + - name + - volumeName + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + description: + description: |- + Provides a brief and concise explanation of the Component's purpose, functionality, and any relevant details. + It serves as a quick reference for users to understand the Component's role and characteristics. + maxLength: 256 type: string + exporter: + description: Defines the built-in metrics exporter container. + properties: + containerName: + description: Specifies the name of the built-in metrics exporter + container. + type: string + scrapePath: + description: |- + Specifies the http/https url path to scrape for metrics. + If empty, Prometheus uses the default value (e.g. `/metrics`). + type: string + scrapePort: + description: Specifies the port name to scrape for metrics. + type: string + scrapeScheme: + description: |- + Specifies the schema to use for scraping. + `http` and `https` are the expected values unless you rewrite the `__scheme__` label via relabeling. + If empty, Prometheus uses the default value `http`. + enum: + - http + - https + type: string + type: object + hostNetwork: + description: |- + Specifies the host network configuration for the Component. + + + When `hostNetwork` option is enabled, the Pods share the host's network namespace and can directly access + the host's network interfaces. + This means that if multiple Pods need to use the same port, they cannot run on the same host simultaneously + due to port conflicts. + + + The DNSPolicy field in the Pod spec determines how containers within the Pod perform DNS resolution. + When using hostNetwork, the operator will set the DNSPolicy to 'ClusterFirstWithHostNet'. + With this policy, DNS queries will first go through the K8s cluster's DNS service. + If the query fails, it will fall back to the host's DNS settings. + + + If set, the DNS policy will be automatically set to "ClusterFirstWithHostNet". + + + This field is immutable. + properties: + containerPorts: + description: The list of container ports that are required by + the component. + items: + properties: + container: + description: Container specifies the target container within + the Pod. + type: string + ports: + description: |- + Ports are named container ports within the specified container. + These container ports must be defined in the container for proper port allocation. + items: + type: string + minItems: 1 + type: array + required: + - container + - ports + type: object + type: array + type: object + labels: + additionalProperties: + type: string + description: |- + Specifies static labels that will be patched to all Kubernetes resources created for the Component. + + + Note: If a label key in the `labels` field conflicts with any system labels or user-specified labels, + it will be silently ignored to avoid overriding higher-priority labels. + + + This field is immutable. + type: object + lifecycleActions: + description: |- + Defines a set of hooks and procedures that customize the behavior of a Component throughout its lifecycle. + Actions are triggered at specific lifecycle stages: + + + - `postProvision`: Defines the hook to be executed after the creation of a Component, + with `preCondition` specifying when the action should be fired relative to the Component's lifecycle stages: + `Immediately`, `RuntimeReady`, `ComponentReady`, and `ClusterReady`. + - `preTerminate`: Defines the hook to be executed before terminating a Component. + - `roleProbe`: Defines the procedure which is invoked regularly to assess the role of replicas. + - `switchover`: Defines the procedure for a controlled transition of leadership from the current leader to a new replica. + This approach aims to minimize downtime and maintain availability in systems with a leader-follower topology, + such as before planned maintenance or upgrades on the current leader node. + - `memberJoin`: Defines the procedure to add a new replica to the replication group. + - `memberLeave`: Defines the method to remove a replica from the replication group. + - `readOnly`: Defines the procedure to switch a replica into the read-only state. + - `readWrite`: transition a replica from the read-only state back to the read-write state. + - `dataDump`: Defines the procedure to export the data from a replica. + - `dataLoad`: Defines the procedure to import data into a replica. + - `reconfigure`: Defines the procedure that update a replica with new configuration file. + - `accountProvision`: Defines the procedure to generate a new database account. + + + This field is immutable. + properties: + accountProvision: + description: |- + Defines the procedure to generate a new database account. + + + Use Case: + This action is designed to create system accounts that are utilized for replication, monitoring, backup, + and other administrative tasks. + + + The container executing this action has access to following variables: + + + - KB_ACCOUNT_NAME: The name of the system account to be created. + - KB_ACCOUNT_PASSWORD: The password for the system account. // TODO: how to pass the password securely? + - KB_ACCOUNT_STATEMENT: The statement used to create the system account. + + + Note: This field is immutable once it has been set. + properties: + exec: + description: |- + Defines the command to run. + + + This field cannot be updated. + properties: + args: + description: Args represents the arguments that are passed + to the `command` for execution. + items: + type: string + type: array + command: + description: |- + Specifies the command to be executed inside the container. + The working directory for this command is the container's root directory('/'). + Commands are executed directly without a shell environment, meaning shell-specific syntax ('|', etc.) is not supported. + If the shell is required, it must be explicitly invoked in the command. + + + A successful execution is indicated by an exit status of 0; any non-zero status signifies a failure. + items: + type: string + type: array + container: + description: |- + Specifies the name of the container within the same pod whose resources will be shared with the action. + This allows the action to utilize the specified container's resources without executing within it. + + + The name must match one of the containers defined in `componentDefinition.spec.runtime`. + + + The resources that can be shared are included: + + + - volume mounts + + + This field cannot be updated. + type: string + env: + description: |- + Represents a list of environment variables that will be injected into the container. + These variables enable the container to adapt its behavior based on the environment it's running in. + + + This field cannot be updated. + items: + description: EnvVar represents an environment variable + present in a Container. + properties: + name: + description: Name of the environment variable. Must + be a C_IDENTIFIER. + type: string + value: + description: |- + Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in the container and + any service environment variables. If a variable cannot be resolved, + the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless of whether the variable + exists or not. + Defaults to "". + type: string + valueFrom: + description: Source for the environment variable's + value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select + in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required for + volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format + of the exposed resources, defaults to + "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in the + pod's namespace + properties: + key: + description: The key of the secret to select + from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + image: + description: |- + Specifies the container image to be used for running the Action. + + + When specified, a dedicated container will be created using this image to execute the Action. + All actions with same image will share the same container. + + + This field cannot be updated. + type: string + matchingKey: + description: |- + Used in conjunction with the `targetPodSelector` field to refine the selection of target pod(s) for Action execution. + The impact of this field depends on the `targetPodSelector` value: + + + - When `targetPodSelector` is set to `Any` or `All`, this field will be ignored. + - When `targetPodSelector` is set to `Role`, only those replicas whose role matches the `matchingKey` + will be selected for the Action. + + + This field cannot be updated. + type: string + targetPodSelector: + description: |- + Defines the criteria used to select the target Pod(s) for executing the Action. + This is useful when there is no default target replica identified. + It allows for precise control over which Pod(s) the Action should run in. + + + If not specified, the Action will be executed in the pod where the Action is triggered, such as the pod + to be removed or added; or a random pod if the Action is triggered at the component level, such as + post-provision or pre-terminate of the component. + + + This field cannot be updated. + enum: + - Any + - All + - Role + - Ordinal + type: string + type: object + preCondition: + description: |- + Specifies the state that the cluster must reach before the Action is executed. + Currently, this is only applicable to the `postProvision` action. + + + The conditions are as follows: + + + - `Immediately`: Executed right after the Component object is created. + The readiness of the Component and its resources is not guaranteed at this stage. + - `RuntimeReady`: The Action is triggered after the Component object has been created and all associated + runtime resources (e.g. Pods) are in a ready state. + - `ComponentReady`: The Action is triggered after the Component itself is in a ready state. + This process does not affect the readiness state of the Component or the Cluster. + - `ClusterReady`: The Action is executed after the Cluster is in a ready state. + This execution does not alter the Component or the Cluster's state of readiness. + + + This field cannot be updated. + type: string + retryPolicy: + description: |- + Defines the strategy to be taken when retrying the Action after a failure. + + + It specifies the conditions under which the Action should be retried and the limits to apply, + such as the maximum number of retries and backoff strategy. + + + This field cannot be updated. + properties: + maxRetries: + default: 0 + description: |- + Defines the maximum number of retry attempts that should be made for a given Action. + This value is set to 0 by default, indicating that no retries will be made. + type: integer + retryInterval: + default: 0 + description: |- + Indicates the duration of time to wait between each retry attempt. + This value is set to 0 by default, indicating that there will be no delay between retry attempts. + format: int64 + type: integer + type: object + timeoutSeconds: + default: 0 + description: |- + Specifies the maximum duration in seconds that the Action is allowed to run. + + + If the Action does not complete within this time frame, it will be terminated. + + + This field cannot be updated. + format: int32 + type: integer + type: object + dataDump: + description: |- + Defines the procedure for exporting the data from a replica. + + + Use Case: + This action is intended for initializing a newly created replica with data. It involves exporting data + from an existing replica and importing it into the new, empty replica. This is essential for synchronizing + the state of replicas across the system. + + + Applicability: + Some database engines or associated sidecar applications (e.g., Patroni) may already provide this functionality. + In such cases, this action may not be required. + + + The output should be a valid data dump streamed to stdout. It must exclude any irrelevant information to ensure + that only the necessary data is exported for import into the new replica. + + + Note: This field is immutable once it has been set. + properties: + exec: + description: |- + Defines the command to run. + + + This field cannot be updated. + properties: + args: + description: Args represents the arguments that are passed + to the `command` for execution. + items: + type: string + type: array + command: + description: |- + Specifies the command to be executed inside the container. + The working directory for this command is the container's root directory('/'). + Commands are executed directly without a shell environment, meaning shell-specific syntax ('|', etc.) is not supported. + If the shell is required, it must be explicitly invoked in the command. + + + A successful execution is indicated by an exit status of 0; any non-zero status signifies a failure. + items: + type: string + type: array + container: + description: |- + Specifies the name of the container within the same pod whose resources will be shared with the action. + This allows the action to utilize the specified container's resources without executing within it. + + + The name must match one of the containers defined in `componentDefinition.spec.runtime`. + + + The resources that can be shared are included: + + + - volume mounts + + + This field cannot be updated. + type: string + env: + description: |- + Represents a list of environment variables that will be injected into the container. + These variables enable the container to adapt its behavior based on the environment it's running in. + + + This field cannot be updated. + items: + description: EnvVar represents an environment variable + present in a Container. + properties: + name: + description: Name of the environment variable. Must + be a C_IDENTIFIER. + type: string + value: + description: |- + Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in the container and + any service environment variables. If a variable cannot be resolved, + the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless of whether the variable + exists or not. + Defaults to "". + type: string + valueFrom: + description: Source for the environment variable's + value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select + in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required for + volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format + of the exposed resources, defaults to + "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in the + pod's namespace + properties: + key: + description: The key of the secret to select + from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + image: + description: |- + Specifies the container image to be used for running the Action. + + + When specified, a dedicated container will be created using this image to execute the Action. + All actions with same image will share the same container. + + + This field cannot be updated. + type: string + matchingKey: + description: |- + Used in conjunction with the `targetPodSelector` field to refine the selection of target pod(s) for Action execution. + The impact of this field depends on the `targetPodSelector` value: + + + - When `targetPodSelector` is set to `Any` or `All`, this field will be ignored. + - When `targetPodSelector` is set to `Role`, only those replicas whose role matches the `matchingKey` + will be selected for the Action. + + + This field cannot be updated. + type: string + targetPodSelector: + description: |- + Defines the criteria used to select the target Pod(s) for executing the Action. + This is useful when there is no default target replica identified. + It allows for precise control over which Pod(s) the Action should run in. + + + If not specified, the Action will be executed in the pod where the Action is triggered, such as the pod + to be removed or added; or a random pod if the Action is triggered at the component level, such as + post-provision or pre-terminate of the component. + + + This field cannot be updated. + enum: + - Any + - All + - Role + - Ordinal + type: string + type: object + preCondition: + description: |- + Specifies the state that the cluster must reach before the Action is executed. + Currently, this is only applicable to the `postProvision` action. + + + The conditions are as follows: + + + - `Immediately`: Executed right after the Component object is created. + The readiness of the Component and its resources is not guaranteed at this stage. + - `RuntimeReady`: The Action is triggered after the Component object has been created and all associated + runtime resources (e.g. Pods) are in a ready state. + - `ComponentReady`: The Action is triggered after the Component itself is in a ready state. + This process does not affect the readiness state of the Component or the Cluster. + - `ClusterReady`: The Action is executed after the Cluster is in a ready state. + This execution does not alter the Component or the Cluster's state of readiness. + + + This field cannot be updated. + type: string + retryPolicy: + description: |- + Defines the strategy to be taken when retrying the Action after a failure. + + + It specifies the conditions under which the Action should be retried and the limits to apply, + such as the maximum number of retries and backoff strategy. + + + This field cannot be updated. + properties: + maxRetries: + default: 0 + description: |- + Defines the maximum number of retry attempts that should be made for a given Action. + This value is set to 0 by default, indicating that no retries will be made. + type: integer + retryInterval: + default: 0 + description: |- + Indicates the duration of time to wait between each retry attempt. + This value is set to 0 by default, indicating that there will be no delay between retry attempts. + format: int64 + type: integer + type: object + timeoutSeconds: + default: 0 + description: |- + Specifies the maximum duration in seconds that the Action is allowed to run. + + + If the Action does not complete within this time frame, it will be terminated. + + + This field cannot be updated. + format: int32 + type: integer + type: object + dataLoad: + description: |- + Defines the procedure for importing data into a replica. + + + Use Case: + This action is intended for initializing a newly created replica with data. It involves exporting data + from an existing replica and importing it into the new, empty replica. This is essential for synchronizing + the state of replicas across the system. + + + Some database engines or associated sidecar applications (e.g., Patroni) may already provide this functionality. + In such cases, this action may not be required. + + + Data should be received through stdin. If any error occurs during the process, + the action must be able to guarantee idempotence to allow for retries from the beginning. + + + Note: This field is immutable once it has been set. + properties: + exec: + description: |- + Defines the command to run. + + + This field cannot be updated. + properties: + args: + description: Args represents the arguments that are passed + to the `command` for execution. + items: + type: string + type: array + command: + description: |- + Specifies the command to be executed inside the container. + The working directory for this command is the container's root directory('/'). + Commands are executed directly without a shell environment, meaning shell-specific syntax ('|', etc.) is not supported. + If the shell is required, it must be explicitly invoked in the command. + + + A successful execution is indicated by an exit status of 0; any non-zero status signifies a failure. + items: + type: string + type: array + container: + description: |- + Specifies the name of the container within the same pod whose resources will be shared with the action. + This allows the action to utilize the specified container's resources without executing within it. + + + The name must match one of the containers defined in `componentDefinition.spec.runtime`. + + + The resources that can be shared are included: + + + - volume mounts + + + This field cannot be updated. + type: string + env: + description: |- + Represents a list of environment variables that will be injected into the container. + These variables enable the container to adapt its behavior based on the environment it's running in. + + + This field cannot be updated. + items: + description: EnvVar represents an environment variable + present in a Container. + properties: + name: + description: Name of the environment variable. Must + be a C_IDENTIFIER. + type: string + value: + description: |- + Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in the container and + any service environment variables. If a variable cannot be resolved, + the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless of whether the variable + exists or not. + Defaults to "". + type: string + valueFrom: + description: Source for the environment variable's + value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select + in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required for + volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format + of the exposed resources, defaults to + "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in the + pod's namespace + properties: + key: + description: The key of the secret to select + from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + image: + description: |- + Specifies the container image to be used for running the Action. + + + When specified, a dedicated container will be created using this image to execute the Action. + All actions with same image will share the same container. + + + This field cannot be updated. + type: string + matchingKey: + description: |- + Used in conjunction with the `targetPodSelector` field to refine the selection of target pod(s) for Action execution. + The impact of this field depends on the `targetPodSelector` value: + + + - When `targetPodSelector` is set to `Any` or `All`, this field will be ignored. + - When `targetPodSelector` is set to `Role`, only those replicas whose role matches the `matchingKey` + will be selected for the Action. + + + This field cannot be updated. + type: string + targetPodSelector: + description: |- + Defines the criteria used to select the target Pod(s) for executing the Action. + This is useful when there is no default target replica identified. + It allows for precise control over which Pod(s) the Action should run in. + + + If not specified, the Action will be executed in the pod where the Action is triggered, such as the pod + to be removed or added; or a random pod if the Action is triggered at the component level, such as + post-provision or pre-terminate of the component. + + + This field cannot be updated. + enum: + - Any + - All + - Role + - Ordinal + type: string + type: object + preCondition: + description: |- + Specifies the state that the cluster must reach before the Action is executed. + Currently, this is only applicable to the `postProvision` action. + + + The conditions are as follows: + + + - `Immediately`: Executed right after the Component object is created. + The readiness of the Component and its resources is not guaranteed at this stage. + - `RuntimeReady`: The Action is triggered after the Component object has been created and all associated + runtime resources (e.g. Pods) are in a ready state. + - `ComponentReady`: The Action is triggered after the Component itself is in a ready state. + This process does not affect the readiness state of the Component or the Cluster. + - `ClusterReady`: The Action is executed after the Cluster is in a ready state. + This execution does not alter the Component or the Cluster's state of readiness. + + + This field cannot be updated. + type: string + retryPolicy: + description: |- + Defines the strategy to be taken when retrying the Action after a failure. + + + It specifies the conditions under which the Action should be retried and the limits to apply, + such as the maximum number of retries and backoff strategy. + + + This field cannot be updated. + properties: + maxRetries: + default: 0 + description: |- + Defines the maximum number of retry attempts that should be made for a given Action. + This value is set to 0 by default, indicating that no retries will be made. + type: integer + retryInterval: + default: 0 + description: |- + Indicates the duration of time to wait between each retry attempt. + This value is set to 0 by default, indicating that there will be no delay between retry attempts. + format: int64 + type: integer + type: object + timeoutSeconds: + default: 0 + description: |- + Specifies the maximum duration in seconds that the Action is allowed to run. + + + If the Action does not complete within this time frame, it will be terminated. + + + This field cannot be updated. + format: int32 + type: integer + type: object + memberJoin: + description: "Defines the procedure to add a new replica to the + replication group.\n\n\nThis action is initiated after a replica + pod becomes ready.\n\n\nThe role of the replica (e.g., primary, + secondary) will be determined and assigned as part of the action + command\nimplementation, or automatically by the database kernel + or a sidecar utility like Patroni that implements\na consensus + algorithm.\n\n\nThe container executing this action has access + to following variables:\n\n\n- KB_JOIN_MEMBER_POD_FQDN: The + pod FQDN of the replica being added to the group.\n- KB_JOIN_MEMBER_POD_NAME: + The pod name of the replica being added to the group.\n\n\nExpected + action output:\n- On Failure: An error message detailing the + reason for any failure encountered\n during the addition of + the new member.\n\n\nFor example, to add a new OBServer to an + OceanBase Cluster in 'zone1', the following command may be used:\n\n\n```yaml\ncommand:\n- + bash\n- -c\n- |\n CLIENT=\"mysql -u $SERVICE_USER -p$SERVICE_PASSWORD + -P $SERVICE_PORT -h $SERVICE_HOST -e\"\n\t $CLIENT \"ALTER + SYSTEM ADD SERVER '$KB_POD_FQDN:$SERVICE_PORT' ZONE 'zone1'\"\n```\n\n\nNote: + This field is immutable once it has been set." + properties: + exec: + description: |- + Defines the command to run. + + + This field cannot be updated. + properties: + args: + description: Args represents the arguments that are passed + to the `command` for execution. + items: + type: string + type: array + command: + description: |- + Specifies the command to be executed inside the container. + The working directory for this command is the container's root directory('/'). + Commands are executed directly without a shell environment, meaning shell-specific syntax ('|', etc.) is not supported. + If the shell is required, it must be explicitly invoked in the command. + + + A successful execution is indicated by an exit status of 0; any non-zero status signifies a failure. + items: + type: string + type: array + container: + description: |- + Specifies the name of the container within the same pod whose resources will be shared with the action. + This allows the action to utilize the specified container's resources without executing within it. + + + The name must match one of the containers defined in `componentDefinition.spec.runtime`. + + + The resources that can be shared are included: + + + - volume mounts + + + This field cannot be updated. + type: string + env: + description: |- + Represents a list of environment variables that will be injected into the container. + These variables enable the container to adapt its behavior based on the environment it's running in. + + + This field cannot be updated. + items: + description: EnvVar represents an environment variable + present in a Container. + properties: + name: + description: Name of the environment variable. Must + be a C_IDENTIFIER. + type: string + value: + description: |- + Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in the container and + any service environment variables. If a variable cannot be resolved, + the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless of whether the variable + exists or not. + Defaults to "". + type: string + valueFrom: + description: Source for the environment variable's + value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select + in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required for + volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format + of the exposed resources, defaults to + "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in the + pod's namespace + properties: + key: + description: The key of the secret to select + from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + image: + description: |- + Specifies the container image to be used for running the Action. + + + When specified, a dedicated container will be created using this image to execute the Action. + All actions with same image will share the same container. + + + This field cannot be updated. + type: string + matchingKey: + description: |- + Used in conjunction with the `targetPodSelector` field to refine the selection of target pod(s) for Action execution. + The impact of this field depends on the `targetPodSelector` value: + + + - When `targetPodSelector` is set to `Any` or `All`, this field will be ignored. + - When `targetPodSelector` is set to `Role`, only those replicas whose role matches the `matchingKey` + will be selected for the Action. + + + This field cannot be updated. + type: string + targetPodSelector: + description: |- + Defines the criteria used to select the target Pod(s) for executing the Action. + This is useful when there is no default target replica identified. + It allows for precise control over which Pod(s) the Action should run in. + + + If not specified, the Action will be executed in the pod where the Action is triggered, such as the pod + to be removed or added; or a random pod if the Action is triggered at the component level, such as + post-provision or pre-terminate of the component. + + + This field cannot be updated. + enum: + - Any + - All + - Role + - Ordinal + type: string + type: object + preCondition: + description: |- + Specifies the state that the cluster must reach before the Action is executed. + Currently, this is only applicable to the `postProvision` action. + + + The conditions are as follows: + + + - `Immediately`: Executed right after the Component object is created. + The readiness of the Component and its resources is not guaranteed at this stage. + - `RuntimeReady`: The Action is triggered after the Component object has been created and all associated + runtime resources (e.g. Pods) are in a ready state. + - `ComponentReady`: The Action is triggered after the Component itself is in a ready state. + This process does not affect the readiness state of the Component or the Cluster. + - `ClusterReady`: The Action is executed after the Cluster is in a ready state. + This execution does not alter the Component or the Cluster's state of readiness. + + + This field cannot be updated. + type: string + retryPolicy: + description: |- + Defines the strategy to be taken when retrying the Action after a failure. + + + It specifies the conditions under which the Action should be retried and the limits to apply, + such as the maximum number of retries and backoff strategy. + + + This field cannot be updated. + properties: + maxRetries: + default: 0 + description: |- + Defines the maximum number of retry attempts that should be made for a given Action. + This value is set to 0 by default, indicating that no retries will be made. + type: integer + retryInterval: + default: 0 + description: |- + Indicates the duration of time to wait between each retry attempt. + This value is set to 0 by default, indicating that there will be no delay between retry attempts. + format: int64 + type: integer + type: object + timeoutSeconds: + default: 0 + description: |- + Specifies the maximum duration in seconds that the Action is allowed to run. + + + If the Action does not complete within this time frame, it will be terminated. + + + This field cannot be updated. + format: int32 + type: integer + type: object + memberLeave: + description: "Defines the procedure to remove a replica from the + replication group.\n\n\nThis action is initiated before remove + a replica from the group.\nThe operator will wait for MemberLeave + to complete successfully before releasing the replica and cleaning + up\nrelated Kubernetes resources.\n\n\nThe process typically + includes updating configurations and informing other group members + about the removal.\nData migration is generally not part of + this action and should be handled separately if needed.\n\n\nThe + container executing this action has access to following variables:\n\n\n- + KB_LEAVE_MEMBER_POD_FQDN: The pod name of the replica being + removed from the group.\n- KB_LEAVE_MEMBER_POD_NAME: The pod + name of the replica being removed from the group.\n\n\nExpected + action output:\n- On Failure: An error message, if applicable, + indicating why the action failed.\n\n\nFor example, to remove + an OBServer from an OceanBase Cluster in 'zone1', the following + command can be executed:\n\n\n```yaml\ncommand:\n- bash\n- -c\n- + |\n CLIENT=\"mysql -u $SERVICE_USER -p$SERVICE_PASSWORD -P + $SERVICE_PORT -h $SERVICE_HOST -e\"\n\t $CLIENT \"ALTER SYSTEM + DELETE SERVER '$KB_POD_FQDN:$SERVICE_PORT' ZONE 'zone1'\"\n```\n\n\nNote: + This field is immutable once it has been set." + properties: + exec: + description: |- + Defines the command to run. + + + This field cannot be updated. + properties: + args: + description: Args represents the arguments that are passed + to the `command` for execution. + items: + type: string + type: array + command: + description: |- + Specifies the command to be executed inside the container. + The working directory for this command is the container's root directory('/'). + Commands are executed directly without a shell environment, meaning shell-specific syntax ('|', etc.) is not supported. + If the shell is required, it must be explicitly invoked in the command. + + + A successful execution is indicated by an exit status of 0; any non-zero status signifies a failure. + items: + type: string + type: array + container: + description: |- + Specifies the name of the container within the same pod whose resources will be shared with the action. + This allows the action to utilize the specified container's resources without executing within it. + + + The name must match one of the containers defined in `componentDefinition.spec.runtime`. + + + The resources that can be shared are included: + + + - volume mounts + + + This field cannot be updated. + type: string + env: + description: |- + Represents a list of environment variables that will be injected into the container. + These variables enable the container to adapt its behavior based on the environment it's running in. + + + This field cannot be updated. + items: + description: EnvVar represents an environment variable + present in a Container. + properties: + name: + description: Name of the environment variable. Must + be a C_IDENTIFIER. + type: string + value: + description: |- + Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in the container and + any service environment variables. If a variable cannot be resolved, + the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless of whether the variable + exists or not. + Defaults to "". + type: string + valueFrom: + description: Source for the environment variable's + value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select + in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required for + volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format + of the exposed resources, defaults to + "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in the + pod's namespace + properties: + key: + description: The key of the secret to select + from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + image: + description: |- + Specifies the container image to be used for running the Action. + + + When specified, a dedicated container will be created using this image to execute the Action. + All actions with same image will share the same container. + + + This field cannot be updated. + type: string + matchingKey: + description: |- + Used in conjunction with the `targetPodSelector` field to refine the selection of target pod(s) for Action execution. + The impact of this field depends on the `targetPodSelector` value: + + + - When `targetPodSelector` is set to `Any` or `All`, this field will be ignored. + - When `targetPodSelector` is set to `Role`, only those replicas whose role matches the `matchingKey` + will be selected for the Action. + + + This field cannot be updated. + type: string + targetPodSelector: + description: |- + Defines the criteria used to select the target Pod(s) for executing the Action. + This is useful when there is no default target replica identified. + It allows for precise control over which Pod(s) the Action should run in. + + + If not specified, the Action will be executed in the pod where the Action is triggered, such as the pod + to be removed or added; or a random pod if the Action is triggered at the component level, such as + post-provision or pre-terminate of the component. + + + This field cannot be updated. + enum: + - Any + - All + - Role + - Ordinal + type: string + type: object + preCondition: + description: |- + Specifies the state that the cluster must reach before the Action is executed. + Currently, this is only applicable to the `postProvision` action. + + + The conditions are as follows: + + + - `Immediately`: Executed right after the Component object is created. + The readiness of the Component and its resources is not guaranteed at this stage. + - `RuntimeReady`: The Action is triggered after the Component object has been created and all associated + runtime resources (e.g. Pods) are in a ready state. + - `ComponentReady`: The Action is triggered after the Component itself is in a ready state. + This process does not affect the readiness state of the Component or the Cluster. + - `ClusterReady`: The Action is executed after the Cluster is in a ready state. + This execution does not alter the Component or the Cluster's state of readiness. + + + This field cannot be updated. + type: string + retryPolicy: + description: |- + Defines the strategy to be taken when retrying the Action after a failure. + + + It specifies the conditions under which the Action should be retried and the limits to apply, + such as the maximum number of retries and backoff strategy. + + + This field cannot be updated. + properties: + maxRetries: + default: 0 + description: |- + Defines the maximum number of retry attempts that should be made for a given Action. + This value is set to 0 by default, indicating that no retries will be made. + type: integer + retryInterval: + default: 0 + description: |- + Indicates the duration of time to wait between each retry attempt. + This value is set to 0 by default, indicating that there will be no delay between retry attempts. + format: int64 + type: integer + type: object + timeoutSeconds: + default: 0 + description: |- + Specifies the maximum duration in seconds that the Action is allowed to run. + + + If the Action does not complete within this time frame, it will be terminated. + + + This field cannot be updated. + format: int32 + type: integer + type: object + postProvision: + description: |- + Specifies the hook to be executed after a component's creation. + + + By setting `postProvision.customHandler.preCondition`, you can determine the specific lifecycle stage + at which the action should trigger: `Immediately`, `RuntimeReady`, `ComponentReady`, and `ClusterReady`. + with `ComponentReady` being the default. + + + The PostProvision Action is intended to run only once. + + + Note: This field is immutable once it has been set. + properties: + exec: + description: |- + Defines the command to run. + + + This field cannot be updated. + properties: + args: + description: Args represents the arguments that are passed + to the `command` for execution. + items: + type: string + type: array + command: + description: |- + Specifies the command to be executed inside the container. + The working directory for this command is the container's root directory('/'). + Commands are executed directly without a shell environment, meaning shell-specific syntax ('|', etc.) is not supported. + If the shell is required, it must be explicitly invoked in the command. + + + A successful execution is indicated by an exit status of 0; any non-zero status signifies a failure. + items: + type: string + type: array + container: + description: |- + Specifies the name of the container within the same pod whose resources will be shared with the action. + This allows the action to utilize the specified container's resources without executing within it. + + + The name must match one of the containers defined in `componentDefinition.spec.runtime`. + + + The resources that can be shared are included: + + + - volume mounts + + + This field cannot be updated. + type: string + env: + description: |- + Represents a list of environment variables that will be injected into the container. + These variables enable the container to adapt its behavior based on the environment it's running in. + + + This field cannot be updated. + items: + description: EnvVar represents an environment variable + present in a Container. + properties: + name: + description: Name of the environment variable. Must + be a C_IDENTIFIER. + type: string + value: + description: |- + Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in the container and + any service environment variables. If a variable cannot be resolved, + the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless of whether the variable + exists or not. + Defaults to "". + type: string + valueFrom: + description: Source for the environment variable's + value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select + in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required for + volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format + of the exposed resources, defaults to + "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in the + pod's namespace + properties: + key: + description: The key of the secret to select + from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + image: + description: |- + Specifies the container image to be used for running the Action. + + + When specified, a dedicated container will be created using this image to execute the Action. + All actions with same image will share the same container. + + + This field cannot be updated. + type: string + matchingKey: + description: |- + Used in conjunction with the `targetPodSelector` field to refine the selection of target pod(s) for Action execution. + The impact of this field depends on the `targetPodSelector` value: + + + - When `targetPodSelector` is set to `Any` or `All`, this field will be ignored. + - When `targetPodSelector` is set to `Role`, only those replicas whose role matches the `matchingKey` + will be selected for the Action. + + + This field cannot be updated. + type: string + targetPodSelector: + description: |- + Defines the criteria used to select the target Pod(s) for executing the Action. + This is useful when there is no default target replica identified. + It allows for precise control over which Pod(s) the Action should run in. + + + If not specified, the Action will be executed in the pod where the Action is triggered, such as the pod + to be removed or added; or a random pod if the Action is triggered at the component level, such as + post-provision or pre-terminate of the component. + + + This field cannot be updated. + enum: + - Any + - All + - Role + - Ordinal + type: string + type: object + preCondition: + description: |- + Specifies the state that the cluster must reach before the Action is executed. + Currently, this is only applicable to the `postProvision` action. + + + The conditions are as follows: + + + - `Immediately`: Executed right after the Component object is created. + The readiness of the Component and its resources is not guaranteed at this stage. + - `RuntimeReady`: The Action is triggered after the Component object has been created and all associated + runtime resources (e.g. Pods) are in a ready state. + - `ComponentReady`: The Action is triggered after the Component itself is in a ready state. + This process does not affect the readiness state of the Component or the Cluster. + - `ClusterReady`: The Action is executed after the Cluster is in a ready state. + This execution does not alter the Component or the Cluster's state of readiness. + + + This field cannot be updated. + type: string + retryPolicy: + description: |- + Defines the strategy to be taken when retrying the Action after a failure. + + + It specifies the conditions under which the Action should be retried and the limits to apply, + such as the maximum number of retries and backoff strategy. + + + This field cannot be updated. + properties: + maxRetries: + default: 0 + description: |- + Defines the maximum number of retry attempts that should be made for a given Action. + This value is set to 0 by default, indicating that no retries will be made. + type: integer + retryInterval: + default: 0 + description: |- + Indicates the duration of time to wait between each retry attempt. + This value is set to 0 by default, indicating that there will be no delay between retry attempts. + format: int64 + type: integer + type: object + timeoutSeconds: + default: 0 + description: |- + Specifies the maximum duration in seconds that the Action is allowed to run. + + + If the Action does not complete within this time frame, it will be terminated. + + + This field cannot be updated. + format: int32 + type: integer + type: object + preTerminate: + description: |- + Specifies the hook to be executed prior to terminating a component. + + + The PreTerminate Action is intended to run only once. + + + This action is executed immediately when a scale-down operation for the Component is initiated. + The actual termination and cleanup of the Component and its associated resources will not proceed + until the PreTerminate action has completed successfully. + + + Note: This field is immutable once it has been set. + properties: + exec: + description: |- + Defines the command to run. + + + This field cannot be updated. + properties: + args: + description: Args represents the arguments that are passed + to the `command` for execution. + items: + type: string + type: array + command: + description: |- + Specifies the command to be executed inside the container. + The working directory for this command is the container's root directory('/'). + Commands are executed directly without a shell environment, meaning shell-specific syntax ('|', etc.) is not supported. + If the shell is required, it must be explicitly invoked in the command. + + + A successful execution is indicated by an exit status of 0; any non-zero status signifies a failure. + items: + type: string + type: array + container: + description: |- + Specifies the name of the container within the same pod whose resources will be shared with the action. + This allows the action to utilize the specified container's resources without executing within it. + + + The name must match one of the containers defined in `componentDefinition.spec.runtime`. + + + The resources that can be shared are included: + + + - volume mounts + + + This field cannot be updated. + type: string + env: + description: |- + Represents a list of environment variables that will be injected into the container. + These variables enable the container to adapt its behavior based on the environment it's running in. + + + This field cannot be updated. + items: + description: EnvVar represents an environment variable + present in a Container. + properties: + name: + description: Name of the environment variable. Must + be a C_IDENTIFIER. + type: string + value: + description: |- + Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in the container and + any service environment variables. If a variable cannot be resolved, + the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless of whether the variable + exists or not. + Defaults to "". + type: string + valueFrom: + description: Source for the environment variable's + value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select + in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required for + volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format + of the exposed resources, defaults to + "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in the + pod's namespace + properties: + key: + description: The key of the secret to select + from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + image: + description: |- + Specifies the container image to be used for running the Action. + + + When specified, a dedicated container will be created using this image to execute the Action. + All actions with same image will share the same container. + + + This field cannot be updated. + type: string + matchingKey: + description: |- + Used in conjunction with the `targetPodSelector` field to refine the selection of target pod(s) for Action execution. + The impact of this field depends on the `targetPodSelector` value: + + + - When `targetPodSelector` is set to `Any` or `All`, this field will be ignored. + - When `targetPodSelector` is set to `Role`, only those replicas whose role matches the `matchingKey` + will be selected for the Action. + + + This field cannot be updated. + type: string + targetPodSelector: + description: |- + Defines the criteria used to select the target Pod(s) for executing the Action. + This is useful when there is no default target replica identified. + It allows for precise control over which Pod(s) the Action should run in. + + + If not specified, the Action will be executed in the pod where the Action is triggered, such as the pod + to be removed or added; or a random pod if the Action is triggered at the component level, such as + post-provision or pre-terminate of the component. + + + This field cannot be updated. + enum: + - Any + - All + - Role + - Ordinal + type: string + type: object + preCondition: + description: |- + Specifies the state that the cluster must reach before the Action is executed. + Currently, this is only applicable to the `postProvision` action. + + + The conditions are as follows: + + + - `Immediately`: Executed right after the Component object is created. + The readiness of the Component and its resources is not guaranteed at this stage. + - `RuntimeReady`: The Action is triggered after the Component object has been created and all associated + runtime resources (e.g. Pods) are in a ready state. + - `ComponentReady`: The Action is triggered after the Component itself is in a ready state. + This process does not affect the readiness state of the Component or the Cluster. + - `ClusterReady`: The Action is executed after the Cluster is in a ready state. + This execution does not alter the Component or the Cluster's state of readiness. + + + This field cannot be updated. + type: string + retryPolicy: + description: |- + Defines the strategy to be taken when retrying the Action after a failure. + + + It specifies the conditions under which the Action should be retried and the limits to apply, + such as the maximum number of retries and backoff strategy. + + + This field cannot be updated. + properties: + maxRetries: + default: 0 + description: |- + Defines the maximum number of retry attempts that should be made for a given Action. + This value is set to 0 by default, indicating that no retries will be made. + type: integer + retryInterval: + default: 0 + description: |- + Indicates the duration of time to wait between each retry attempt. + This value is set to 0 by default, indicating that there will be no delay between retry attempts. + format: int64 + type: integer + type: object + timeoutSeconds: + default: 0 + description: |- + Specifies the maximum duration in seconds that the Action is allowed to run. + + + If the Action does not complete within this time frame, it will be terminated. + + + This field cannot be updated. + format: int32 + type: integer + type: object + readonly: + description: |- + Defines the procedure to switch a replica into the read-only state. + + + Use Case: + This action is invoked when the database's volume capacity nears its upper limit and space is about to be exhausted. + + + The container executing this action has access to following environment variables: + + + - KB_POD_FQDN: The FQDN of the replica pod whose role is being checked. + + + Expected action output: + - On Failure: An error message, if applicable, indicating why the action failed. + + + Note: This field is immutable once it has been set. + properties: + exec: + description: |- + Defines the command to run. + + + This field cannot be updated. + properties: + args: + description: Args represents the arguments that are passed + to the `command` for execution. + items: + type: string + type: array + command: + description: |- + Specifies the command to be executed inside the container. + The working directory for this command is the container's root directory('/'). + Commands are executed directly without a shell environment, meaning shell-specific syntax ('|', etc.) is not supported. + If the shell is required, it must be explicitly invoked in the command. + + + A successful execution is indicated by an exit status of 0; any non-zero status signifies a failure. + items: + type: string + type: array + container: + description: |- + Specifies the name of the container within the same pod whose resources will be shared with the action. + This allows the action to utilize the specified container's resources without executing within it. + + + The name must match one of the containers defined in `componentDefinition.spec.runtime`. + + + The resources that can be shared are included: + + + - volume mounts + + + This field cannot be updated. + type: string + env: + description: |- + Represents a list of environment variables that will be injected into the container. + These variables enable the container to adapt its behavior based on the environment it's running in. + + + This field cannot be updated. + items: + description: EnvVar represents an environment variable + present in a Container. + properties: + name: + description: Name of the environment variable. Must + be a C_IDENTIFIER. + type: string + value: + description: |- + Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in the container and + any service environment variables. If a variable cannot be resolved, + the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless of whether the variable + exists or not. + Defaults to "". + type: string + valueFrom: + description: Source for the environment variable's + value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select + in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required for + volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format + of the exposed resources, defaults to + "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in the + pod's namespace + properties: + key: + description: The key of the secret to select + from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + image: + description: |- + Specifies the container image to be used for running the Action. + + + When specified, a dedicated container will be created using this image to execute the Action. + All actions with same image will share the same container. + + + This field cannot be updated. + type: string + matchingKey: + description: |- + Used in conjunction with the `targetPodSelector` field to refine the selection of target pod(s) for Action execution. + The impact of this field depends on the `targetPodSelector` value: + + + - When `targetPodSelector` is set to `Any` or `All`, this field will be ignored. + - When `targetPodSelector` is set to `Role`, only those replicas whose role matches the `matchingKey` + will be selected for the Action. + + + This field cannot be updated. + type: string + targetPodSelector: + description: |- + Defines the criteria used to select the target Pod(s) for executing the Action. + This is useful when there is no default target replica identified. + It allows for precise control over which Pod(s) the Action should run in. + + + If not specified, the Action will be executed in the pod where the Action is triggered, such as the pod + to be removed or added; or a random pod if the Action is triggered at the component level, such as + post-provision or pre-terminate of the component. + + + This field cannot be updated. + enum: + - Any + - All + - Role + - Ordinal + type: string + type: object + preCondition: + description: |- + Specifies the state that the cluster must reach before the Action is executed. + Currently, this is only applicable to the `postProvision` action. + + + The conditions are as follows: + + + - `Immediately`: Executed right after the Component object is created. + The readiness of the Component and its resources is not guaranteed at this stage. + - `RuntimeReady`: The Action is triggered after the Component object has been created and all associated + runtime resources (e.g. Pods) are in a ready state. + - `ComponentReady`: The Action is triggered after the Component itself is in a ready state. + This process does not affect the readiness state of the Component or the Cluster. + - `ClusterReady`: The Action is executed after the Cluster is in a ready state. + This execution does not alter the Component or the Cluster's state of readiness. + + + This field cannot be updated. + type: string + retryPolicy: + description: |- + Defines the strategy to be taken when retrying the Action after a failure. + + + It specifies the conditions under which the Action should be retried and the limits to apply, + such as the maximum number of retries and backoff strategy. + + + This field cannot be updated. + properties: + maxRetries: + default: 0 + description: |- + Defines the maximum number of retry attempts that should be made for a given Action. + This value is set to 0 by default, indicating that no retries will be made. + type: integer + retryInterval: + default: 0 + description: |- + Indicates the duration of time to wait between each retry attempt. + This value is set to 0 by default, indicating that there will be no delay between retry attempts. + format: int64 + type: integer + type: object + timeoutSeconds: + default: 0 + description: |- + Specifies the maximum duration in seconds that the Action is allowed to run. + + + If the Action does not complete within this time frame, it will be terminated. + + + This field cannot be updated. + format: int32 + type: integer + type: object + readwrite: + description: |- + Defines the procedure to transition a replica from the read-only state back to the read-write state. + + + Use Case: + This action is used to bring back a replica that was previously in a read-only state, + which restricted write operations, to its normal operational state where it can handle + both read and write operations. + + + The container executing this action has access to following environment variables: + + + - KB_POD_FQDN: The FQDN of the replica pod whose role is being checked. + + + Expected action output: + - On Failure: An error message, if applicable, indicating why the action failed. + + + Note: This field is immutable once it has been set. + properties: + exec: + description: |- + Defines the command to run. + + + This field cannot be updated. + properties: + args: + description: Args represents the arguments that are passed + to the `command` for execution. + items: + type: string + type: array + command: + description: |- + Specifies the command to be executed inside the container. + The working directory for this command is the container's root directory('/'). + Commands are executed directly without a shell environment, meaning shell-specific syntax ('|', etc.) is not supported. + If the shell is required, it must be explicitly invoked in the command. + + + A successful execution is indicated by an exit status of 0; any non-zero status signifies a failure. + items: + type: string + type: array + container: + description: |- + Specifies the name of the container within the same pod whose resources will be shared with the action. + This allows the action to utilize the specified container's resources without executing within it. + + + The name must match one of the containers defined in `componentDefinition.spec.runtime`. + + + The resources that can be shared are included: + + + - volume mounts + + + This field cannot be updated. + type: string + env: + description: |- + Represents a list of environment variables that will be injected into the container. + These variables enable the container to adapt its behavior based on the environment it's running in. + + + This field cannot be updated. + items: + description: EnvVar represents an environment variable + present in a Container. + properties: + name: + description: Name of the environment variable. Must + be a C_IDENTIFIER. + type: string + value: + description: |- + Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in the container and + any service environment variables. If a variable cannot be resolved, + the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless of whether the variable + exists or not. + Defaults to "". + type: string + valueFrom: + description: Source for the environment variable's + value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select + in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required for + volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format + of the exposed resources, defaults to + "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in the + pod's namespace + properties: + key: + description: The key of the secret to select + from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + image: + description: |- + Specifies the container image to be used for running the Action. + + + When specified, a dedicated container will be created using this image to execute the Action. + All actions with same image will share the same container. + + + This field cannot be updated. + type: string + matchingKey: + description: |- + Used in conjunction with the `targetPodSelector` field to refine the selection of target pod(s) for Action execution. + The impact of this field depends on the `targetPodSelector` value: + + + - When `targetPodSelector` is set to `Any` or `All`, this field will be ignored. + - When `targetPodSelector` is set to `Role`, only those replicas whose role matches the `matchingKey` + will be selected for the Action. + + + This field cannot be updated. + type: string + targetPodSelector: + description: |- + Defines the criteria used to select the target Pod(s) for executing the Action. + This is useful when there is no default target replica identified. + It allows for precise control over which Pod(s) the Action should run in. + + + If not specified, the Action will be executed in the pod where the Action is triggered, such as the pod + to be removed or added; or a random pod if the Action is triggered at the component level, such as + post-provision or pre-terminate of the component. + + + This field cannot be updated. + enum: + - Any + - All + - Role + - Ordinal + type: string + type: object + preCondition: + description: |- + Specifies the state that the cluster must reach before the Action is executed. + Currently, this is only applicable to the `postProvision` action. + + + The conditions are as follows: + + + - `Immediately`: Executed right after the Component object is created. + The readiness of the Component and its resources is not guaranteed at this stage. + - `RuntimeReady`: The Action is triggered after the Component object has been created and all associated + runtime resources (e.g. Pods) are in a ready state. + - `ComponentReady`: The Action is triggered after the Component itself is in a ready state. + This process does not affect the readiness state of the Component or the Cluster. + - `ClusterReady`: The Action is executed after the Cluster is in a ready state. + This execution does not alter the Component or the Cluster's state of readiness. + + + This field cannot be updated. + type: string + retryPolicy: + description: |- + Defines the strategy to be taken when retrying the Action after a failure. + + + It specifies the conditions under which the Action should be retried and the limits to apply, + such as the maximum number of retries and backoff strategy. + + + This field cannot be updated. + properties: + maxRetries: + default: 0 + description: |- + Defines the maximum number of retry attempts that should be made for a given Action. + This value is set to 0 by default, indicating that no retries will be made. + type: integer + retryInterval: + default: 0 + description: |- + Indicates the duration of time to wait between each retry attempt. + This value is set to 0 by default, indicating that there will be no delay between retry attempts. + format: int64 + type: integer + type: object + timeoutSeconds: + default: 0 + description: |- + Specifies the maximum duration in seconds that the Action is allowed to run. + + + If the Action does not complete within this time frame, it will be terminated. + + + This field cannot be updated. + format: int32 + type: integer + type: object + reconfigure: + description: |- + Defines the procedure that update a replica with new configuration. + + + Note: This field is immutable once it has been set. + + + This Action is reserved for future versions. + properties: + exec: + description: |- + Defines the command to run. + + + This field cannot be updated. + properties: + args: + description: Args represents the arguments that are passed + to the `command` for execution. + items: + type: string + type: array + command: + description: |- + Specifies the command to be executed inside the container. + The working directory for this command is the container's root directory('/'). + Commands are executed directly without a shell environment, meaning shell-specific syntax ('|', etc.) is not supported. + If the shell is required, it must be explicitly invoked in the command. + + + A successful execution is indicated by an exit status of 0; any non-zero status signifies a failure. + items: + type: string + type: array + container: + description: |- + Specifies the name of the container within the same pod whose resources will be shared with the action. + This allows the action to utilize the specified container's resources without executing within it. + + + The name must match one of the containers defined in `componentDefinition.spec.runtime`. + + + The resources that can be shared are included: + + + - volume mounts + + + This field cannot be updated. + type: string + env: + description: |- + Represents a list of environment variables that will be injected into the container. + These variables enable the container to adapt its behavior based on the environment it's running in. + + + This field cannot be updated. + items: + description: EnvVar represents an environment variable + present in a Container. + properties: + name: + description: Name of the environment variable. Must + be a C_IDENTIFIER. + type: string + value: + description: |- + Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in the container and + any service environment variables. If a variable cannot be resolved, + the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless of whether the variable + exists or not. + Defaults to "". + type: string + valueFrom: + description: Source for the environment variable's + value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select + in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required for + volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format + of the exposed resources, defaults to + "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in the + pod's namespace + properties: + key: + description: The key of the secret to select + from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + image: + description: |- + Specifies the container image to be used for running the Action. + + + When specified, a dedicated container will be created using this image to execute the Action. + All actions with same image will share the same container. + + + This field cannot be updated. + type: string + matchingKey: + description: |- + Used in conjunction with the `targetPodSelector` field to refine the selection of target pod(s) for Action execution. + The impact of this field depends on the `targetPodSelector` value: + + + - When `targetPodSelector` is set to `Any` or `All`, this field will be ignored. + - When `targetPodSelector` is set to `Role`, only those replicas whose role matches the `matchingKey` + will be selected for the Action. + + + This field cannot be updated. + type: string + targetPodSelector: + description: |- + Defines the criteria used to select the target Pod(s) for executing the Action. + This is useful when there is no default target replica identified. + It allows for precise control over which Pod(s) the Action should run in. + + + If not specified, the Action will be executed in the pod where the Action is triggered, such as the pod + to be removed or added; or a random pod if the Action is triggered at the component level, such as + post-provision or pre-terminate of the component. + + + This field cannot be updated. + enum: + - Any + - All + - Role + - Ordinal + type: string + type: object + preCondition: + description: |- + Specifies the state that the cluster must reach before the Action is executed. + Currently, this is only applicable to the `postProvision` action. + + + The conditions are as follows: + + + - `Immediately`: Executed right after the Component object is created. + The readiness of the Component and its resources is not guaranteed at this stage. + - `RuntimeReady`: The Action is triggered after the Component object has been created and all associated + runtime resources (e.g. Pods) are in a ready state. + - `ComponentReady`: The Action is triggered after the Component itself is in a ready state. + This process does not affect the readiness state of the Component or the Cluster. + - `ClusterReady`: The Action is executed after the Cluster is in a ready state. + This execution does not alter the Component or the Cluster's state of readiness. + + + This field cannot be updated. + type: string + retryPolicy: + description: |- + Defines the strategy to be taken when retrying the Action after a failure. + + + It specifies the conditions under which the Action should be retried and the limits to apply, + such as the maximum number of retries and backoff strategy. + + + This field cannot be updated. + properties: + maxRetries: + default: 0 + description: |- + Defines the maximum number of retry attempts that should be made for a given Action. + This value is set to 0 by default, indicating that no retries will be made. + type: integer + retryInterval: + default: 0 + description: |- + Indicates the duration of time to wait between each retry attempt. + This value is set to 0 by default, indicating that there will be no delay between retry attempts. + format: int64 + type: integer + type: object + timeoutSeconds: + default: 0 + description: |- + Specifies the maximum duration in seconds that the Action is allowed to run. + + + If the Action does not complete within this time frame, it will be terminated. + + + This field cannot be updated. + format: int32 + type: integer + type: object + roleProbe: + description: |- + Defines the procedure which is invoked regularly to assess the role of replicas. + + + This action is periodically triggered at the specified interval to determine the role of each replica. + Upon successful execution, the action's output designates the role of the replica, + which should match one of the predefined role names within `componentDefinition.spec.roles`. + The output is then compared with the previous successful execution result. + If a role change is detected, an event is generated to inform the controller, + which initiates an update of the replica's role. + + + Defining a RoleProbe Action for a Component is required if roles are defined for the Component. + It ensures replicas are correctly labeled with their respective roles. + Without this, services that rely on roleSelectors might improperly direct traffic to wrong replicas. + + + The container executing this action has access to following variables: + + + - KB_POD_FQDN: The FQDN of the Pod whose role is being assessed. + + + Expected output of this action: + - On Success: The determined role of the replica, which must align with one of the roles specified + in the component definition. + - On Failure: An error message, if applicable, indicating why the action failed. + + + Note: This field is immutable once it has been set. + properties: + exec: + description: |- + Defines the command to run. + + + This field cannot be updated. + properties: + args: + description: Args represents the arguments that are passed + to the `command` for execution. + items: + type: string + type: array + command: + description: |- + Specifies the command to be executed inside the container. + The working directory for this command is the container's root directory('/'). + Commands are executed directly without a shell environment, meaning shell-specific syntax ('|', etc.) is not supported. + If the shell is required, it must be explicitly invoked in the command. + + + A successful execution is indicated by an exit status of 0; any non-zero status signifies a failure. + items: + type: string + type: array + container: + description: |- + Specifies the name of the container within the same pod whose resources will be shared with the action. + This allows the action to utilize the specified container's resources without executing within it. + + + The name must match one of the containers defined in `componentDefinition.spec.runtime`. + + + The resources that can be shared are included: + + + - volume mounts + + + This field cannot be updated. + type: string + env: + description: |- + Represents a list of environment variables that will be injected into the container. + These variables enable the container to adapt its behavior based on the environment it's running in. + + + This field cannot be updated. + items: + description: EnvVar represents an environment variable + present in a Container. + properties: + name: + description: Name of the environment variable. Must + be a C_IDENTIFIER. + type: string + value: + description: |- + Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in the container and + any service environment variables. If a variable cannot be resolved, + the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless of whether the variable + exists or not. + Defaults to "". + type: string + valueFrom: + description: Source for the environment variable's + value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select + in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required for + volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format + of the exposed resources, defaults to + "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in the + pod's namespace + properties: + key: + description: The key of the secret to select + from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + image: + description: |- + Specifies the container image to be used for running the Action. + + + When specified, a dedicated container will be created using this image to execute the Action. + All actions with same image will share the same container. + + + This field cannot be updated. + type: string + matchingKey: + description: |- + Used in conjunction with the `targetPodSelector` field to refine the selection of target pod(s) for Action execution. + The impact of this field depends on the `targetPodSelector` value: + + + - When `targetPodSelector` is set to `Any` or `All`, this field will be ignored. + - When `targetPodSelector` is set to `Role`, only those replicas whose role matches the `matchingKey` + will be selected for the Action. + + + This field cannot be updated. + type: string + targetPodSelector: + description: |- + Defines the criteria used to select the target Pod(s) for executing the Action. + This is useful when there is no default target replica identified. + It allows for precise control over which Pod(s) the Action should run in. + + + If not specified, the Action will be executed in the pod where the Action is triggered, such as the pod + to be removed or added; or a random pod if the Action is triggered at the component level, such as + post-provision or pre-terminate of the component. + + + This field cannot be updated. + enum: + - Any + - All + - Role + - Ordinal + type: string + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + initialDelaySeconds: + description: |- + Specifies the number of seconds to wait after the container has started before the RoleProbe + begins to detect the container's role. + format: int32 + type: integer + periodSeconds: + description: |- + Specifies the frequency at which the probe is conducted. This value is expressed in seconds. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + preCondition: + description: |- + Specifies the state that the cluster must reach before the Action is executed. + Currently, this is only applicable to the `postProvision` action. + + + The conditions are as follows: + + + - `Immediately`: Executed right after the Component object is created. + The readiness of the Component and its resources is not guaranteed at this stage. + - `RuntimeReady`: The Action is triggered after the Component object has been created and all associated + runtime resources (e.g. Pods) are in a ready state. + - `ComponentReady`: The Action is triggered after the Component itself is in a ready state. + This process does not affect the readiness state of the Component or the Cluster. + - `ClusterReady`: The Action is executed after the Cluster is in a ready state. + This execution does not alter the Component or the Cluster's state of readiness. + + + This field cannot be updated. + type: string + retryPolicy: + description: |- + Defines the strategy to be taken when retrying the Action after a failure. + + + It specifies the conditions under which the Action should be retried and the limits to apply, + such as the maximum number of retries and backoff strategy. + + + This field cannot be updated. + properties: + maxRetries: + default: 0 + description: |- + Defines the maximum number of retry attempts that should be made for a given Action. + This value is set to 0 by default, indicating that no retries will be made. + type: integer + retryInterval: + default: 0 + description: |- + Indicates the duration of time to wait between each retry attempt. + This value is set to 0 by default, indicating that there will be no delay between retry attempts. + format: int64 + type: integer + type: object + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Minimum value is 1. + format: int32 + type: integer + timeoutSeconds: + default: 0 + description: |- + Specifies the maximum duration in seconds that the Action is allowed to run. + + + If the Action does not complete within this time frame, it will be terminated. + + + This field cannot be updated. + format: int32 + type: integer + type: object + switchover: + description: |- + Defines the procedure for a controlled transition of leadership from the current leader to a new replica. + This approach aims to minimize downtime and maintain availability in systems with a leader-follower topology, + during events such as planned maintenance or when performing stop, shutdown, restart, or upgrade operations + involving the current leader node. + + + The container executing this action has access to following variables: + + + - KB_SWITCHOVER_CANDIDATE_NAME: The name of the pod for the new leader candidate, which may not be specified (empty). + - KB_SWITCHOVER_CANDIDATE_FQDN: The FQDN of the new leader candidate's pod, which may not be specified (empty). + + + Note: This field is immutable once it has been set. + properties: + exec: + description: |- + Defines the command to run. + + + This field cannot be updated. + properties: + args: + description: Args represents the arguments that are passed + to the `command` for execution. + items: + type: string + type: array + command: + description: |- + Specifies the command to be executed inside the container. + The working directory for this command is the container's root directory('/'). + Commands are executed directly without a shell environment, meaning shell-specific syntax ('|', etc.) is not supported. + If the shell is required, it must be explicitly invoked in the command. + + + A successful execution is indicated by an exit status of 0; any non-zero status signifies a failure. + items: + type: string + type: array + container: + description: |- + Specifies the name of the container within the same pod whose resources will be shared with the action. + This allows the action to utilize the specified container's resources without executing within it. + + + The name must match one of the containers defined in `componentDefinition.spec.runtime`. + + + The resources that can be shared are included: + + + - volume mounts + + + This field cannot be updated. + type: string + env: + description: |- + Represents a list of environment variables that will be injected into the container. + These variables enable the container to adapt its behavior based on the environment it's running in. + + + This field cannot be updated. + items: + description: EnvVar represents an environment variable + present in a Container. + properties: + name: + description: Name of the environment variable. Must + be a C_IDENTIFIER. + type: string + value: + description: |- + Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in the container and + any service environment variables. If a variable cannot be resolved, + the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless of whether the variable + exists or not. + Defaults to "". + type: string + valueFrom: + description: Source for the environment variable's + value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select + in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required for + volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format + of the exposed resources, defaults to + "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in the + pod's namespace + properties: + key: + description: The key of the secret to select + from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + image: + description: |- + Specifies the container image to be used for running the Action. + + + When specified, a dedicated container will be created using this image to execute the Action. + All actions with same image will share the same container. + + + This field cannot be updated. + type: string + matchingKey: + description: |- + Used in conjunction with the `targetPodSelector` field to refine the selection of target pod(s) for Action execution. + The impact of this field depends on the `targetPodSelector` value: + + + - When `targetPodSelector` is set to `Any` or `All`, this field will be ignored. + - When `targetPodSelector` is set to `Role`, only those replicas whose role matches the `matchingKey` + will be selected for the Action. + + + This field cannot be updated. + type: string + targetPodSelector: + description: |- + Defines the criteria used to select the target Pod(s) for executing the Action. + This is useful when there is no default target replica identified. + It allows for precise control over which Pod(s) the Action should run in. + + + If not specified, the Action will be executed in the pod where the Action is triggered, such as the pod + to be removed or added; or a random pod if the Action is triggered at the component level, such as + post-provision or pre-terminate of the component. + + + This field cannot be updated. + enum: + - Any + - All + - Role + - Ordinal + type: string + type: object + preCondition: + description: |- + Specifies the state that the cluster must reach before the Action is executed. + Currently, this is only applicable to the `postProvision` action. + + + The conditions are as follows: + + + - `Immediately`: Executed right after the Component object is created. + The readiness of the Component and its resources is not guaranteed at this stage. + - `RuntimeReady`: The Action is triggered after the Component object has been created and all associated + runtime resources (e.g. Pods) are in a ready state. + - `ComponentReady`: The Action is triggered after the Component itself is in a ready state. + This process does not affect the readiness state of the Component or the Cluster. + - `ClusterReady`: The Action is executed after the Cluster is in a ready state. + This execution does not alter the Component or the Cluster's state of readiness. + + + This field cannot be updated. + type: string + retryPolicy: + description: |- + Defines the strategy to be taken when retrying the Action after a failure. + + + It specifies the conditions under which the Action should be retried and the limits to apply, + such as the maximum number of retries and backoff strategy. + + + This field cannot be updated. + properties: + maxRetries: + default: 0 + description: |- + Defines the maximum number of retry attempts that should be made for a given Action. + This value is set to 0 by default, indicating that no retries will be made. + type: integer + retryInterval: + default: 0 + description: |- + Indicates the duration of time to wait between each retry attempt. + This value is set to 0 by default, indicating that there will be no delay between retry attempts. + format: int64 + type: integer + type: object + timeoutSeconds: + default: 0 + description: |- + Specifies the maximum duration in seconds that the Action is allowed to run. + + + If the Action does not complete within this time frame, it will be terminated. + + + This field cannot be updated. + format: int32 + type: integer + type: object + type: object + logConfigs: + description: |- + Defines the types of logs generated by instances of the Component and their corresponding file paths. + These logs can be collected for further analysis and monitoring. + + + The `logConfigs` field is an optional list of LogConfig objects, where each object represents + a specific log type and its configuration. + It allows you to specify multiple log types and their respective file paths for the Component. + + + Examples: + + + ```yaml + logConfigs: + - filePathPattern: /data/mysql/log/mysqld-error.log + name: error + - filePathPattern: /data/mysql/log/mysqld.log + name: general + - filePathPattern: /data/mysql/log/mysqld-slowquery.log + name: slow + ``` + + + This field is immutable. + items: + properties: + filePathPattern: + description: |- + Specifies the paths or patterns identifying where the log files are stored. + This field allows the system to locate and manage log files effectively. + + + Examples: + + + - /home/postgres/pgdata/pgroot/data/log/postgresql-* + - /data/mysql/log/mysqld-error.log + maxLength: 4096 + type: string + name: + description: |- + Specifies a descriptive label for the log type, such as 'slow' for a MySQL slow log file. + It provides a clear identification of the log's purpose and content. + maxLength: 128 + type: string + required: + - filePathPattern + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + minReadySeconds: + default: 0 + description: |- + `minReadySeconds` is the minimum duration in seconds that a new Pod should remain in the ready + state without any of its containers crashing to be considered available. + This ensures the Pod's stability and readiness to serve requests. + + + A default value of 0 seconds means the Pod is considered available as soon as it enters the ready state. + format: int32 + minimum: 0 + type: integer + podManagementPolicy: + description: |- + InstanceSet controls the creation of pods during initial scale up, replacement of pods on nodes, and scaling down. + + + - `OrderedReady`: Creates pods in increasing order (pod-0, then pod-1, etc). The controller waits until each pod + is ready before continuing. Pods are removed in reverse order when scaling down. + - `Parallel`: Creates pods in parallel to match the desired scale without waiting. All pods are deleted at once + when scaling down. + type: string + policyRules: + description: |- + Defines the namespaced policy rules required by the Component. + + + The `policyRules` field is an array of `rbacv1.PolicyRule` objects that define the policy rules + needed by the Component to operate within a namespace. + These policy rules determine the permissions and verbs the Component is allowed to perform on + Kubernetes resources within the namespace. + + + The purpose of this field is to automatically generate the necessary RBAC roles + for the Component based on the specified policy rules. + This ensures that the Pods in the Component has appropriate permissions to function. + + + Note: This field is currently non-functional and is reserved for future implementation. + + + This field is immutable. + items: + description: |- + PolicyRule holds information that describes a policy rule, but does not contain information + about who the rule applies to or which namespace the rule applies to. + properties: + apiGroups: + description: |- + APIGroups is the name of the APIGroup that contains the resources. If multiple API groups are specified, any action requested against one of + the enumerated resources in any API group will be allowed. "" represents the core API group and "*" represents all API groups. + items: + type: string + type: array + nonResourceURLs: + description: |- + NonResourceURLs is a set of partial urls that a user should have access to. *s are allowed, but only as the full, final step in the path + Since non-resource URLs are not namespaced, this field is only applicable for ClusterRoles referenced from a ClusterRoleBinding. + Rules can either apply to API resources (such as "pods" or "secrets") or non-resource URL paths (such as "/api"), but not both. + items: + type: string + type: array + resourceNames: + description: ResourceNames is an optional white list of names + that the rule applies to. An empty set means that everything + is allowed. + items: + type: string + type: array + resources: + description: Resources is a list of resources this rule applies + to. '*' represents all resources. + items: + type: string + type: array + verbs: + description: Verbs is a list of Verbs that apply to ALL the + ResourceKinds contained in this rule. '*' represents all verbs. + items: + type: string + type: array + required: + - verbs + type: object + type: array + provider: + description: |- + Specifies the name of the Component provider, typically the vendor or developer name. + It identifies the entity responsible for creating and maintaining the Component. + + + When specifying the provider name, consider the following guidelines: + + + - Keep the name concise and relevant to the Component. + - Use a consistent naming convention across Components from the same provider. + - Avoid using trademarked or copyrighted names without proper permission. + maxLength: 32 + type: string + replicasLimit: + description: |- + Defines the upper limit of the number of replicas supported by the Component. + + + It defines the maximum number of replicas that can be created for the Component. + This field allows you to set a limit on the scalability of the Component, preventing it from exceeding a certain number of replicas. + + + This field is immutable. + properties: + maxReplicas: + description: The maximum limit of replicas. + format: int32 + type: integer + minReplicas: + description: The minimum limit of replicas. + format: int32 + type: integer + required: + - maxReplicas + - minReplicas + type: object + x-kubernetes-validations: + - message: the minimum and maximum limit of replicas should be in + the range of [0, 16384] + rule: self.minReplicas >= 0 && self.maxReplicas <= 16384 + - message: the minimum replicas limit should be no greater than the + maximum + rule: self.minReplicas <= self.maxReplicas + roles: + description: |- + Enumerate all possible roles assigned to each replica of the Component, influencing its behavior. + + + A replica can have zero to multiple roles. + KubeBlocks operator determines the roles of each replica by invoking the `lifecycleActions.roleProbe` method. + This action returns a list of roles for each replica, and the returned roles must be predefined in the `roles` field. + + + The roles assigned to a replica can influence various aspects of the Component's behavior, such as: + + + - Service selection: The Component's exposed Services may target replicas based on their roles using `roleSelector`. + - Update order: The roles can determine the order in which replicas are updated during a Component update. + For instance, replicas with a "follower" role can be updated first, while the replica with the "leader" + role is updated last. This helps minimize the number of leader changes during the update process. + + + This field is immutable. + items: + description: ReplicaRole represents a role that can be assumed by + a component instance. + properties: + name: + description: |- + Defines the role's identifier. It is used to set the "apps.kubeblocks.io/role" label value + on the corresponding object. + + + This field is immutable once set. + maxLength: 32 + pattern: ^.*[^\s]+.*$ + type: string + serviceable: + default: false + description: |- + Indicates whether a replica assigned this role is capable of providing services. + + + This field is immutable once set. + type: boolean + votable: + default: false + description: |- + Specifies whether a replica with this role has voting rights. + In distributed systems, this typically means the replica can participate in consensus decisions, + configuration changes, or other processes that require a quorum. + + + This field is immutable once set. + type: boolean + writable: + default: false + description: |- + Determines if a replica in this role has the authority to perform write operations. + A writable replica can modify data, handle update operations. + + + This field is immutable once set. + type: boolean + required: + - name + type: object + type: array + runtime: + description: |- + Specifies the PodSpec template used in the Component. + It includes the following elements: + + + - Init containers + - Containers + - Image + - Commands + - Args + - Envs + - Mounts + - Ports + - Security context + - Probes + - Lifecycle + - Volumes + + + This field is intended to define static settings that remain consistent across all instantiated Components. + Dynamic settings such as CPU and memory resource limits, as well as scheduling settings (affinity, + toleration, priority), may vary among different instantiated Components. + They should be specified in the `cluster.spec.componentSpecs` (ClusterComponentSpec). + + + Specific instances of a Component may override settings defined here, such as using a different container image + or modifying environment variable values. + These instance-specific overrides can be specified in `cluster.spec.componentSpecs[*].instances`. + + + This field is immutable and cannot be updated once set. + properties: + activeDeadlineSeconds: + description: |- + Optional duration in seconds the pod may be active on the node relative to + StartTime before the system will actively try to mark it failed and kill associated containers. + Value must be a positive integer. + format: int64 + type: integer + affinity: + description: If specified, the pod's scheduling constraints + properties: + nodeAffinity: + description: Describes node affinity scheduling rules for + the pod. + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node matches the corresponding matchExpressions; the + node(s) with the highest sum are the most preferred. + items: + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). + properties: + preference: + description: A node selector term, associated with + the corresponding weight. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + weight: + description: Weight associated with matching the + corresponding nodeSelectorTerm, in the range 1-100. + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. + properties: + nodeSelectorTerms: + description: Required. A list of node selector terms. + The terms are ORed. + items: + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + type: array + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + description: Describes pod affinity scheduling rules (e.g. + co-locate this pod in the same node, zone, etc. as some + other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred + node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated + with the corresponding weight. + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. + Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: |- + weight associated with matching the corresponding podAffinityTerm, + in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. + items: + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. + Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + description: Describes pod anti-affinity scheduling rules + (e.g. avoid putting this pod in the same node, zone, etc. + as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the anti-affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred + node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated + with the corresponding weight. + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. + Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: |- + weight associated with matching the corresponding podAffinityTerm, + in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the anti-affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the anti-affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. + items: + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. + Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + automountServiceAccountToken: + description: AutomountServiceAccountToken indicates whether a + service account token should be automatically mounted. + type: boolean + containers: + description: |- + List of containers belonging to the pod. + Containers cannot currently be added or removed. + There must be at least one container in a Pod. + Cannot be updated. + items: + description: A single application container that you want to + run within a pod. + properties: + args: + description: |- + Arguments to the entrypoint. + The container image's CMD is used if this is not provided. + Variable references $(VAR_NAME) are expanded using the container's environment. If a variable + cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will + produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless + of whether the variable exists or not. Cannot be updated. + More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell + items: + type: string + type: array + command: + description: |- + Entrypoint array. Not executed within a shell. + The container image's ENTRYPOINT is used if this is not provided. + Variable references $(VAR_NAME) are expanded using the container's environment. If a variable + cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will + produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless + of whether the variable exists or not. Cannot be updated. + More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell + items: + type: string + type: array + env: + description: |- + List of environment variables to set in the container. + Cannot be updated. + items: + description: EnvVar represents an environment variable + present in a Container. + properties: + name: + description: Name of the environment variable. Must + be a C_IDENTIFIER. + type: string + value: + description: |- + Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in the container and + any service environment variables. If a variable cannot be resolved, + the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless of whether the variable + exists or not. + Defaults to "". + type: string + valueFrom: + description: Source for the environment variable's + value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in + the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required for + volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of + the exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in the + pod's namespace + properties: + key: + description: The key of the secret to select + from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or + its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + envFrom: + description: |- + List of sources to populate environment variables in the container. + The keys defined within a source must be a C_IDENTIFIER. All invalid keys + will be reported as an event when the container is starting. When a key exists in multiple + sources, the value associated with the last source will take precedence. + Values defined by an Env with a duplicate key will take precedence. + Cannot be updated. + items: + description: EnvFromSource represents the source of a + set of ConfigMaps + properties: + configMapRef: + description: The ConfigMap to select from + 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 + optional: + description: Specify whether the ConfigMap must + be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + description: An optional identifier to prepend to + each key in the ConfigMap. Must be a C_IDENTIFIER. + type: string + secretRef: + description: The Secret to select from + 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 + optional: + description: Specify whether the Secret must be + defined + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + image: + description: |- + Container image name. + More info: https://kubernetes.io/docs/concepts/containers/images + This field is optional to allow higher level config management to default or override + container images in workload controllers like Deployments and StatefulSets. + type: string + imagePullPolicy: + description: |- + Image pull policy. + One of Always, Never, IfNotPresent. + Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/containers/images#updating-images + type: string + lifecycle: + description: |- + Actions that the management system should take in response to container lifecycle events. + Cannot be updated. + properties: + postStart: + description: |- + PostStart is called immediately after a container is created. If the handler fails, + the container is terminated and restarted according to its restart policy. + Other management of the container blocks until the hook completes. + More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + sleep: + description: Sleep represents the duration that + the container should sleep before being terminated. + properties: + seconds: + description: Seconds is the number of seconds + to sleep. + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + description: |- + Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept + for the backward compatibility. There are no validation of this field and + lifecycle hooks will fail in runtime when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + description: |- + PreStop is called immediately before a container is terminated due to an + API request or management event such as liveness/startup probe failure, + preemption, resource contention, etc. The handler is not called if the + container crashes or exits. The Pod's termination grace period countdown begins before the + PreStop hook is executed. Regardless of the outcome of the handler, the + container will eventually terminate within the Pod's termination grace + period (unless delayed by finalizers). Other management of the container blocks until the hook completes + or until the termination grace period is reached. + More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + sleep: + description: Sleep represents the duration that + the container should sleep before being terminated. + properties: + seconds: + description: Seconds is the number of seconds + to sleep. + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + description: |- + Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept + for the backward compatibility. There are no validation of this field and + lifecycle hooks will fail in runtime when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + description: |- + Periodic probe of container liveness. + Container will be restarted if the probe fails. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC + port. + properties: + port: + description: Port number of the gRPC service. Number + must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, + defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + name: + description: |- + Name of the container specified as a DNS_LABEL. + Each container in a pod must have a unique name (DNS_LABEL). + Cannot be updated. + type: string + ports: + description: |- + List of ports to expose from the container. Not specifying a port here + DOES NOT prevent that port from being exposed. Any port which is + listening on the default "0.0.0.0" address inside a container will be + accessible from the network. + Modifying this array with strategic merge patch may corrupt the data. + For more information See https://github.com/kubernetes/kubernetes/issues/108255. + Cannot be updated. + items: + description: ContainerPort represents a network port in + a single container. + properties: + containerPort: + description: |- + Number of port to expose on the pod's IP address. + This must be a valid port number, 0 < x < 65536. + format: int32 + type: integer + hostIP: + description: What host IP to bind the external port + to. + type: string + hostPort: + description: |- + Number of port to expose on the host. + If specified, this must be a valid port number, 0 < x < 65536. + If HostNetwork is specified, this must match ContainerPort. + Most containers do not need this. + format: int32 + type: integer + name: + description: |- + If specified, this must be an IANA_SVC_NAME and unique within the pod. Each + named port in a pod must have a unique name. Name for the port that can be + referred to by services. + type: string + protocol: + default: TCP + description: |- + Protocol for port. Must be UDP, TCP, or SCTP. + Defaults to "TCP". + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + description: |- + Periodic probe of container service readiness. + Container will be removed from service endpoints if the probe fails. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC + port. + properties: + port: + description: Port number of the gRPC service. Number + must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, + defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + resizePolicy: + description: Resources resize policy for the container. + items: + description: ContainerResizePolicy represents resource + resize policy for the container. + properties: + resourceName: + description: |- + Name of the resource to which this resource resize policy applies. + Supported values: cpu, memory. + type: string + restartPolicy: + description: |- + Restart policy to apply when specified resource is resized. + If not specified, it defaults to NotRequired. + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + description: |- + Compute Resources required by this container. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + properties: + claims: + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + + + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + + + This field is immutable. It can only be set for containers. + items: + description: ResourceClaim references one entry in + PodSpec.ResourceClaims. + properties: + name: + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + restartPolicy: + description: |- + RestartPolicy defines the restart behavior of individual containers in a pod. + This field may only be set for init containers, and the only allowed value is "Always". + For non-init containers or when this field is not specified, + the restart behavior is defined by the Pod's restart policy and the container type. + Setting the RestartPolicy as "Always" for the init container will have the following effect: + this init container will be continually restarted on + exit until all regular containers have terminated. Once all regular + containers have completed, all init containers with restartPolicy "Always" + will be shut down. This lifecycle differs from normal init containers and + is often referred to as a "sidecar" container. Although this init + container still starts in the init container sequence, it does not wait + for the container to complete before proceeding to the next init + container. Instead, the next init container starts immediately after this + init container is started, or after any startupProbe has successfully + completed. + type: string + securityContext: + description: |- + SecurityContext defines the security options the container should be run with. + If set, the fields of SecurityContext override the equivalent fields of PodSecurityContext. + More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ + properties: + allowPrivilegeEscalation: + description: |- + AllowPrivilegeEscalation controls whether a process can gain more + privileges than its parent process. This bool directly controls if + the no_new_privs flag will be set on the container process. + AllowPrivilegeEscalation is true always when the container is: + 1) run as Privileged + 2) has CAP_SYS_ADMIN + Note that this field cannot be set when spec.os.name is windows. + type: boolean + capabilities: + description: |- + The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the container runtime. + Note that this field cannot be set when spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + type: object + privileged: + description: |- + Run container in privileged mode. + Processes in privileged containers are essentially equivalent to root on the host. + Defaults to false. + Note that this field cannot be set when spec.os.name is windows. + type: boolean + procMount: + description: |- + procMount denotes the type of proc mount to use for the containers. + The default is DefaultProcMount which uses the container runtime defaults for + readonly paths and masked paths. + This requires the ProcMountType feature flag to be enabled. + Note that this field cannot be set when spec.os.name is windows. + type: string + readOnlyRootFilesystem: + description: |- + Whether this container has a read-only root filesystem. + Default is false. + Note that this field cannot be set when spec.os.name is windows. + type: boolean + runAsGroup: + description: |- + The GID to run the entrypoint of the container process. + Uses runtime default if unset. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: |- + Indicates that the container must run as a non-root user. + If true, the Kubelet will validate the image at runtime to ensure that it + does not run as UID 0 (root) and fail to start the container if it does. + If unset or false, no such validation will be performed. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: |- + The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: |- + The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random SELinux context for each + container. May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies + to the container. + type: string + role: + description: Role is a SELinux role label that applies + to the container. + type: string + type: + description: Type is a SELinux type label that applies + to the container. + type: string + user: + description: User is a SELinux user label that applies + to the container. + type: string + type: object + seccompProfile: + description: |- + The seccomp options to use by this container. If seccomp options are + provided at both the pod & container level, the container options + override the pod options. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile defined in a file on the node should be used. + The profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be set for any other type. + type: string + type: + description: |- + type indicates which kind of seccomp profile will be applied. + Valid options are: + + + Localhost - a profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile should be used. + Unconfined - no profile should be applied. + type: string + required: + - type + type: object + windowsOptions: + description: |- + The Windows specific settings applied to all containers. + If unspecified, the options from the PodSecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: |- + GMSACredentialSpec is where the GMSA admission webhook + (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the + GMSA credential spec named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name + of the GMSA credential spec to use. + type: string + hostProcess: + description: |- + HostProcess determines if a container should be run as a 'Host Process' container. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: |- + The UserName in Windows to run the entrypoint of the container process. + Defaults to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: string + type: object + type: object + startupProbe: + description: |- + StartupProbe indicates that the Pod has successfully initialized. + If specified, no other probes are executed until this completes successfully. + If this probe fails, the Pod will be restarted, just as if the livenessProbe failed. + This can be used to provide different probe parameters at the beginning of a Pod's lifecycle, + when it might take a long time to load data or warm a cache, than during steady-state operation. + This cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC + port. + properties: + port: + description: Port number of the gRPC service. Number + must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, + defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + stdin: + description: |- + Whether this container should allocate a buffer for stdin in the container runtime. If this + is not set, reads from stdin in the container will always result in EOF. + Default is false. + type: boolean + stdinOnce: + description: |- + Whether the container runtime should close the stdin channel after it has been opened by + a single attach. When stdin is true the stdin stream will remain open across multiple attach + sessions. If stdinOnce is set to true, stdin is opened on container start, is empty until the + first client attaches to stdin, and then remains open and accepts data until the client disconnects, + at which time stdin is closed and remains closed until the container is restarted. If this + flag is false, a container processes that reads from stdin will never receive an EOF. + Default is false + type: boolean + terminationMessagePath: + description: |- + Optional: Path at which the file to which the container's termination message + will be written is mounted into the container's filesystem. + Message written is intended to be brief final status, such as an assertion failure message. + Will be truncated by the node if greater than 4096 bytes. The total message length across + all containers will be limited to 12kb. + Defaults to /dev/termination-log. + Cannot be updated. + type: string + terminationMessagePolicy: + description: |- + Indicate how the termination message should be populated. File will use the contents of + terminationMessagePath to populate the container status message on both success and failure. + FallbackToLogsOnError will use the last chunk of container log output if the termination + message file is empty and the container exited with an error. + The log output is limited to 2048 bytes or 80 lines, whichever is smaller. + Defaults to File. + Cannot be updated. + type: string + tty: + description: |- + Whether this container should allocate a TTY for itself, also requires 'stdin' to be true. + Default is false. + type: boolean + volumeDevices: + description: volumeDevices is the list of block devices + to be used by the container. + items: + description: volumeDevice describes a mapping of a raw + block device within a container. + properties: + devicePath: + description: devicePath is the path inside of the + container that the device will be mapped to. + type: string + name: + description: name must match the name of a persistentVolumeClaim + in the pod + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + description: |- + Pod volumes to mount into the container's filesystem. + Cannot be updated. + items: + description: VolumeMount describes a mounting of a Volume + within a container. + properties: + mountPath: + description: |- + Path within the container at which the volume should be mounted. Must + not contain ':'. + type: string + mountPropagation: + description: |- + mountPropagation determines how mounts are propagated from the host + to container and the other way around. + When not set, MountPropagationNone is used. + This field is beta in 1.10. + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: |- + Mounted read-only if true, read-write otherwise (false or unspecified). + Defaults to false. + type: boolean + subPath: + description: |- + Path within the volume from which the container's volume should be mounted. + Defaults to "" (volume's root). + type: string + subPathExpr: + description: |- + Expanded path within the volume from which the container's volume should be mounted. + Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment. + Defaults to "" (volume's root). + SubPathExpr and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + description: |- + Container's working directory. + If not specified, the container runtime's default will be used, which + might be configured in the container image. + Cannot be updated. + type: string + required: + - name + type: object + type: array + dnsConfig: + description: |- + Specifies the DNS parameters of a pod. + Parameters specified here will be merged to the generated DNS + configuration based on DNSPolicy. + properties: + nameservers: + description: |- + A list of DNS name server IP addresses. + This will be appended to the base nameservers generated from DNSPolicy. + Duplicated nameservers will be removed. + items: + type: string + type: array + options: + description: |- + A list of DNS resolver options. + This will be merged with the base options generated from DNSPolicy. + Duplicated entries will be removed. Resolution options given in Options + will override those that appear in the base DNSPolicy. + items: + description: PodDNSConfigOption defines DNS resolver options + of a pod. + properties: + name: + description: Required. + type: string + value: + type: string + type: object + type: array + searches: + description: |- + A list of DNS search domains for host-name lookup. + This will be appended to the base search paths generated from DNSPolicy. + Duplicated search paths will be removed. + items: + type: string + type: array + type: object + dnsPolicy: + description: |- + Set DNS policy for the pod. + Defaults to "ClusterFirst". + Valid values are 'ClusterFirstWithHostNet', 'ClusterFirst', 'Default' or 'None'. + DNS parameters given in DNSConfig will be merged with the policy selected with DNSPolicy. + To have DNS options set along with hostNetwork, you have to specify DNS policy + explicitly to 'ClusterFirstWithHostNet'. + type: string + enableServiceLinks: + description: |- + EnableServiceLinks indicates whether information about services should be injected into pod's + environment variables, matching the syntax of Docker links. + Optional: Defaults to true. + type: boolean + ephemeralContainers: + description: |- + List of ephemeral containers run in this pod. Ephemeral containers may be run in an existing + pod to perform user-initiated actions such as debugging. This list cannot be specified when + creating a pod, and it cannot be modified by updating the pod spec. In order to add an + ephemeral container to an existing pod, use the pod's ephemeralcontainers subresource. + items: + description: |- + An EphemeralContainer is a temporary container that you may add to an existing Pod for + user-initiated activities such as debugging. Ephemeral containers have no resource or + scheduling guarantees, and they will not be restarted when they exit or when a Pod is + removed or restarted. The kubelet may evict a Pod if an ephemeral container causes the + Pod to exceed its resource allocation. + + + To add an ephemeral container, use the ephemeralcontainers subresource of an existing + Pod. Ephemeral containers may not be removed or restarted. + properties: + args: + description: |- + Arguments to the entrypoint. + The image's CMD is used if this is not provided. + Variable references $(VAR_NAME) are expanded using the container's environment. If a variable + cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will + produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless + of whether the variable exists or not. Cannot be updated. + More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell + items: + type: string + type: array + command: + description: |- + Entrypoint array. Not executed within a shell. + The image's ENTRYPOINT is used if this is not provided. + Variable references $(VAR_NAME) are expanded using the container's environment. If a variable + cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will + produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless + of whether the variable exists or not. Cannot be updated. + More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell + items: + type: string + type: array + env: + description: |- + List of environment variables to set in the container. + Cannot be updated. + items: + description: EnvVar represents an environment variable + present in a Container. + properties: + name: + description: Name of the environment variable. Must + be a C_IDENTIFIER. + type: string + value: + description: |- + Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in the container and + any service environment variables. If a variable cannot be resolved, + the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless of whether the variable + exists or not. + Defaults to "". + type: string + valueFrom: + description: Source for the environment variable's + value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in + the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required for + volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of + the exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in the + pod's namespace + properties: + key: + description: The key of the secret to select + from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or + its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + envFrom: + description: |- + List of sources to populate environment variables in the container. + The keys defined within a source must be a C_IDENTIFIER. All invalid keys + will be reported as an event when the container is starting. When a key exists in multiple + sources, the value associated with the last source will take precedence. + Values defined by an Env with a duplicate key will take precedence. + Cannot be updated. + items: + description: EnvFromSource represents the source of a + set of ConfigMaps + properties: + configMapRef: + description: The ConfigMap to select from + 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 + optional: + description: Specify whether the ConfigMap must + be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + description: An optional identifier to prepend to + each key in the ConfigMap. Must be a C_IDENTIFIER. + type: string + secretRef: + description: The Secret to select from + 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 + optional: + description: Specify whether the Secret must be + defined + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + image: + description: |- + Container image name. + More info: https://kubernetes.io/docs/concepts/containers/images + type: string + imagePullPolicy: + description: |- + Image pull policy. + One of Always, Never, IfNotPresent. + Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/containers/images#updating-images + type: string + lifecycle: + description: Lifecycle is not allowed for ephemeral containers. + properties: + postStart: + description: |- + PostStart is called immediately after a container is created. If the handler fails, + the container is terminated and restarted according to its restart policy. + Other management of the container blocks until the hook completes. + More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + sleep: + description: Sleep represents the duration that + the container should sleep before being terminated. + properties: + seconds: + description: Seconds is the number of seconds + to sleep. + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + description: |- + Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept + for the backward compatibility. There are no validation of this field and + lifecycle hooks will fail in runtime when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + description: |- + PreStop is called immediately before a container is terminated due to an + API request or management event such as liveness/startup probe failure, + preemption, resource contention, etc. The handler is not called if the + container crashes or exits. The Pod's termination grace period countdown begins before the + PreStop hook is executed. Regardless of the outcome of the handler, the + container will eventually terminate within the Pod's termination grace + period (unless delayed by finalizers). Other management of the container blocks until the hook completes + or until the termination grace period is reached. + More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + sleep: + description: Sleep represents the duration that + the container should sleep before being terminated. + properties: + seconds: + description: Seconds is the number of seconds + to sleep. + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + description: |- + Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept + for the backward compatibility. There are no validation of this field and + lifecycle hooks will fail in runtime when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + description: Probes are not allowed for ephemeral containers. + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC + port. + properties: + port: + description: Port number of the gRPC service. Number + must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, + defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + name: + description: |- + Name of the ephemeral container specified as a DNS_LABEL. + This name must be unique among all containers, init containers and ephemeral containers. + type: string + ports: + description: Ports are not allowed for ephemeral containers. + items: + description: ContainerPort represents a network port in + a single container. + properties: + containerPort: + description: |- + Number of port to expose on the pod's IP address. + This must be a valid port number, 0 < x < 65536. + format: int32 + type: integer + hostIP: + description: What host IP to bind the external port + to. + type: string + hostPort: + description: |- + Number of port to expose on the host. + If specified, this must be a valid port number, 0 < x < 65536. + If HostNetwork is specified, this must match ContainerPort. + Most containers do not need this. + format: int32 + type: integer + name: + description: |- + If specified, this must be an IANA_SVC_NAME and unique within the pod. Each + named port in a pod must have a unique name. Name for the port that can be + referred to by services. + type: string + protocol: + default: TCP + description: |- + Protocol for port. Must be UDP, TCP, or SCTP. + Defaults to "TCP". + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + description: Probes are not allowed for ephemeral containers. + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC + port. + properties: + port: + description: Port number of the gRPC service. Number + must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, + defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + resizePolicy: + description: Resources resize policy for the container. + items: + description: ContainerResizePolicy represents resource + resize policy for the container. + properties: + resourceName: + description: |- + Name of the resource to which this resource resize policy applies. + Supported values: cpu, memory. + type: string + restartPolicy: + description: |- + Restart policy to apply when specified resource is resized. + If not specified, it defaults to NotRequired. + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + description: |- + Resources are not allowed for ephemeral containers. Ephemeral containers use spare resources + already allocated to the pod. + properties: + claims: + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + + + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + + + This field is immutable. It can only be set for containers. + items: + description: ResourceClaim references one entry in + PodSpec.ResourceClaims. + properties: + name: + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + restartPolicy: + description: |- + Restart policy for the container to manage the restart behavior of each + container within a pod. + This may only be set for init containers. You cannot set this field on + ephemeral containers. + type: string + securityContext: + description: |- + Optional: SecurityContext defines the security options the ephemeral container should be run with. + If set, the fields of SecurityContext override the equivalent fields of PodSecurityContext. + properties: + allowPrivilegeEscalation: + description: |- + AllowPrivilegeEscalation controls whether a process can gain more + privileges than its parent process. This bool directly controls if + the no_new_privs flag will be set on the container process. + AllowPrivilegeEscalation is true always when the container is: + 1) run as Privileged + 2) has CAP_SYS_ADMIN + Note that this field cannot be set when spec.os.name is windows. + type: boolean + capabilities: + description: |- + The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the container runtime. + Note that this field cannot be set when spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + type: object + privileged: + description: |- + Run container in privileged mode. + Processes in privileged containers are essentially equivalent to root on the host. + Defaults to false. + Note that this field cannot be set when spec.os.name is windows. + type: boolean + procMount: + description: |- + procMount denotes the type of proc mount to use for the containers. + The default is DefaultProcMount which uses the container runtime defaults for + readonly paths and masked paths. + This requires the ProcMountType feature flag to be enabled. + Note that this field cannot be set when spec.os.name is windows. + type: string + readOnlyRootFilesystem: + description: |- + Whether this container has a read-only root filesystem. + Default is false. + Note that this field cannot be set when spec.os.name is windows. + type: boolean + runAsGroup: + description: |- + The GID to run the entrypoint of the container process. + Uses runtime default if unset. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: |- + Indicates that the container must run as a non-root user. + If true, the Kubelet will validate the image at runtime to ensure that it + does not run as UID 0 (root) and fail to start the container if it does. + If unset or false, no such validation will be performed. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: |- + The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: |- + The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random SELinux context for each + container. May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies + to the container. + type: string + role: + description: Role is a SELinux role label that applies + to the container. + type: string + type: + description: Type is a SELinux type label that applies + to the container. + type: string + user: + description: User is a SELinux user label that applies + to the container. + type: string + type: object + seccompProfile: + description: |- + The seccomp options to use by this container. If seccomp options are + provided at both the pod & container level, the container options + override the pod options. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile defined in a file on the node should be used. + The profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be set for any other type. + type: string + type: + description: |- + type indicates which kind of seccomp profile will be applied. + Valid options are: + + + Localhost - a profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile should be used. + Unconfined - no profile should be applied. + type: string + required: + - type + type: object + windowsOptions: + description: |- + The Windows specific settings applied to all containers. + If unspecified, the options from the PodSecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: |- + GMSACredentialSpec is where the GMSA admission webhook + (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the + GMSA credential spec named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name + of the GMSA credential spec to use. + type: string + hostProcess: + description: |- + HostProcess determines if a container should be run as a 'Host Process' container. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: |- + The UserName in Windows to run the entrypoint of the container process. + Defaults to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: string + type: object + type: object + startupProbe: + description: Probes are not allowed for ephemeral containers. + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC + port. + properties: + port: + description: Port number of the gRPC service. Number + must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, + defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + stdin: + description: |- + Whether this container should allocate a buffer for stdin in the container runtime. If this + is not set, reads from stdin in the container will always result in EOF. + Default is false. + type: boolean + stdinOnce: + description: |- + Whether the container runtime should close the stdin channel after it has been opened by + a single attach. When stdin is true the stdin stream will remain open across multiple attach + sessions. If stdinOnce is set to true, stdin is opened on container start, is empty until the + first client attaches to stdin, and then remains open and accepts data until the client disconnects, + at which time stdin is closed and remains closed until the container is restarted. If this + flag is false, a container processes that reads from stdin will never receive an EOF. + Default is false + type: boolean + targetContainerName: + description: |- + If set, the name of the container from PodSpec that this ephemeral container targets. + The ephemeral container will be run in the namespaces (IPC, PID, etc) of this container. + If not set then the ephemeral container uses the namespaces configured in the Pod spec. + + + The container runtime must implement support for this feature. If the runtime does not + support namespace targeting then the result of setting this field is undefined. + type: string + terminationMessagePath: + description: |- + Optional: Path at which the file to which the container's termination message + will be written is mounted into the container's filesystem. + Message written is intended to be brief final status, such as an assertion failure message. + Will be truncated by the node if greater than 4096 bytes. The total message length across + all containers will be limited to 12kb. + Defaults to /dev/termination-log. + Cannot be updated. + type: string + terminationMessagePolicy: + description: |- + Indicate how the termination message should be populated. File will use the contents of + terminationMessagePath to populate the container status message on both success and failure. + FallbackToLogsOnError will use the last chunk of container log output if the termination + message file is empty and the container exited with an error. + The log output is limited to 2048 bytes or 80 lines, whichever is smaller. + Defaults to File. + Cannot be updated. + type: string + tty: + description: |- + Whether this container should allocate a TTY for itself, also requires 'stdin' to be true. + Default is false. + type: boolean + volumeDevices: + description: volumeDevices is the list of block devices + to be used by the container. + items: + description: volumeDevice describes a mapping of a raw + block device within a container. + properties: + devicePath: + description: devicePath is the path inside of the + container that the device will be mapped to. + type: string + name: + description: name must match the name of a persistentVolumeClaim + in the pod + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + description: |- + Pod volumes to mount into the container's filesystem. Subpath mounts are not allowed for ephemeral containers. + Cannot be updated. + items: + description: VolumeMount describes a mounting of a Volume + within a container. + properties: + mountPath: + description: |- + Path within the container at which the volume should be mounted. Must + not contain ':'. + type: string + mountPropagation: + description: |- + mountPropagation determines how mounts are propagated from the host + to container and the other way around. + When not set, MountPropagationNone is used. + This field is beta in 1.10. + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: |- + Mounted read-only if true, read-write otherwise (false or unspecified). + Defaults to false. + type: boolean + subPath: + description: |- + Path within the volume from which the container's volume should be mounted. + Defaults to "" (volume's root). + type: string + subPathExpr: + description: |- + Expanded path within the volume from which the container's volume should be mounted. + Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment. + Defaults to "" (volume's root). + SubPathExpr and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + description: |- + Container's working directory. + If not specified, the container runtime's default will be used, which + might be configured in the container image. + Cannot be updated. + type: string + required: + - name + type: object + type: array + hostAliases: + description: |- + HostAliases is an optional list of hosts and IPs that will be injected into the pod's hosts + file if specified. This is only valid for non-hostNetwork pods. + items: + description: |- + HostAlias holds the mapping between IP and hostnames that will be injected as an entry in the + pod's hosts file. + properties: + hostnames: + description: Hostnames for the above IP address. + items: + type: string + type: array + ip: + description: IP address of the host file entry. + type: string + type: object + type: array + hostIPC: + description: |- + Use the host's ipc namespace. + Optional: Default to false. + type: boolean + hostNetwork: + description: |- + Host networking requested for this pod. Use the host's network namespace. + If this option is set, the ports that will be used must be specified. + Default to false. + type: boolean + hostPID: + description: |- + Use the host's pid namespace. + Optional: Default to false. + type: boolean + hostUsers: + description: |- + Use the host's user namespace. + Optional: Default to true. + If set to true or not present, the pod will be run in the host user namespace, useful + for when the pod needs a feature only available to the host user namespace, such as + loading a kernel module with CAP_SYS_MODULE. + When set to false, a new userns is created for the pod. Setting false is useful for + mitigating container breakout vulnerabilities even allowing users to run their + containers as root without actually having root privileges on the host. + This field is alpha-level and is only honored by servers that enable the UserNamespacesSupport feature. + type: boolean + hostname: + description: |- + Specifies the hostname of the Pod + If not specified, the pod's hostname will be set to a system-defined value. + type: string + imagePullSecrets: + description: |- + ImagePullSecrets is an optional list of references to secrets in the same namespace to use for pulling any of the images used by this PodSpec. + If specified, these secrets will be passed to individual puller implementations for them to use. + More info: https://kubernetes.io/docs/concepts/containers/images#specifying-imagepullsecrets-on-a-pod + items: + 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? + type: string + type: object + x-kubernetes-map-type: atomic + type: array + initContainers: + description: |- + List of initialization containers belonging to the pod. + Init containers are executed in order prior to containers being started. If any + init container fails, the pod is considered to have failed and is handled according + to its restartPolicy. The name for an init container or normal container must be + unique among all containers. + Init containers may not have Lifecycle actions, Readiness probes, Liveness probes, or Startup probes. + The resourceRequirements of an init container are taken into account during scheduling + by finding the highest request/limit for each resource type, and then using the max of + of that value or the sum of the normal containers. Limits are applied to init containers + in a similar fashion. + Init containers cannot currently be added or removed. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/init-containers/ + items: + description: A single application container that you want to + run within a pod. + properties: + args: + description: |- + Arguments to the entrypoint. + The container image's CMD is used if this is not provided. + Variable references $(VAR_NAME) are expanded using the container's environment. If a variable + cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will + produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless + of whether the variable exists or not. Cannot be updated. + More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell + items: + type: string + type: array + command: + description: |- + Entrypoint array. Not executed within a shell. + The container image's ENTRYPOINT is used if this is not provided. + Variable references $(VAR_NAME) are expanded using the container's environment. If a variable + cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will + produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless + of whether the variable exists or not. Cannot be updated. + More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell + items: + type: string + type: array + env: + description: |- + List of environment variables to set in the container. + Cannot be updated. + items: + description: EnvVar represents an environment variable + present in a Container. + properties: + name: + description: Name of the environment variable. Must + be a C_IDENTIFIER. + type: string + value: + description: |- + Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in the container and + any service environment variables. If a variable cannot be resolved, + the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless of whether the variable + exists or not. + Defaults to "". + type: string + valueFrom: + description: Source for the environment variable's + value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in + the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required for + volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of + the exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in the + pod's namespace + properties: + key: + description: The key of the secret to select + from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or + its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + envFrom: + description: |- + List of sources to populate environment variables in the container. + The keys defined within a source must be a C_IDENTIFIER. All invalid keys + will be reported as an event when the container is starting. When a key exists in multiple + sources, the value associated with the last source will take precedence. + Values defined by an Env with a duplicate key will take precedence. + Cannot be updated. + items: + description: EnvFromSource represents the source of a + set of ConfigMaps + properties: + configMapRef: + description: The ConfigMap to select from + 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 + optional: + description: Specify whether the ConfigMap must + be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + description: An optional identifier to prepend to + each key in the ConfigMap. Must be a C_IDENTIFIER. + type: string + secretRef: + description: The Secret to select from + 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 + optional: + description: Specify whether the Secret must be + defined + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + image: + description: |- + Container image name. + More info: https://kubernetes.io/docs/concepts/containers/images + This field is optional to allow higher level config management to default or override + container images in workload controllers like Deployments and StatefulSets. + type: string + imagePullPolicy: + description: |- + Image pull policy. + One of Always, Never, IfNotPresent. + Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/containers/images#updating-images + type: string + lifecycle: + description: |- + Actions that the management system should take in response to container lifecycle events. + Cannot be updated. + properties: + postStart: + description: |- + PostStart is called immediately after a container is created. If the handler fails, + the container is terminated and restarted according to its restart policy. + Other management of the container blocks until the hook completes. + More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + sleep: + description: Sleep represents the duration that + the container should sleep before being terminated. + properties: + seconds: + description: Seconds is the number of seconds + to sleep. + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + description: |- + Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept + for the backward compatibility. There are no validation of this field and + lifecycle hooks will fail in runtime when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + description: |- + PreStop is called immediately before a container is terminated due to an + API request or management event such as liveness/startup probe failure, + preemption, resource contention, etc. The handler is not called if the + container crashes or exits. The Pod's termination grace period countdown begins before the + PreStop hook is executed. Regardless of the outcome of the handler, the + container will eventually terminate within the Pod's termination grace + period (unless delayed by finalizers). Other management of the container blocks until the hook completes + or until the termination grace period is reached. + More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + sleep: + description: Sleep represents the duration that + the container should sleep before being terminated. + properties: + seconds: + description: Seconds is the number of seconds + to sleep. + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + description: |- + Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept + for the backward compatibility. There are no validation of this field and + lifecycle hooks will fail in runtime when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + description: |- + Periodic probe of container liveness. + Container will be restarted if the probe fails. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC + port. + properties: + port: + description: Port number of the gRPC service. Number + must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, + defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + name: + description: |- + Name of the container specified as a DNS_LABEL. + Each container in a pod must have a unique name (DNS_LABEL). + Cannot be updated. + type: string + ports: + description: |- + List of ports to expose from the container. Not specifying a port here + DOES NOT prevent that port from being exposed. Any port which is + listening on the default "0.0.0.0" address inside a container will be + accessible from the network. + Modifying this array with strategic merge patch may corrupt the data. + For more information See https://github.com/kubernetes/kubernetes/issues/108255. + Cannot be updated. + items: + description: ContainerPort represents a network port in + a single container. + properties: + containerPort: + description: |- + Number of port to expose on the pod's IP address. + This must be a valid port number, 0 < x < 65536. + format: int32 + type: integer + hostIP: + description: What host IP to bind the external port + to. + type: string + hostPort: + description: |- + Number of port to expose on the host. + If specified, this must be a valid port number, 0 < x < 65536. + If HostNetwork is specified, this must match ContainerPort. + Most containers do not need this. + format: int32 + type: integer + name: + description: |- + If specified, this must be an IANA_SVC_NAME and unique within the pod. Each + named port in a pod must have a unique name. Name for the port that can be + referred to by services. + type: string + protocol: + default: TCP + description: |- + Protocol for port. Must be UDP, TCP, or SCTP. + Defaults to "TCP". + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + description: |- + Periodic probe of container service readiness. + Container will be removed from service endpoints if the probe fails. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC + port. + properties: + port: + description: Port number of the gRPC service. Number + must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, + defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + resizePolicy: + description: Resources resize policy for the container. + items: + description: ContainerResizePolicy represents resource + resize policy for the container. + properties: + resourceName: + description: |- + Name of the resource to which this resource resize policy applies. + Supported values: cpu, memory. + type: string + restartPolicy: + description: |- + Restart policy to apply when specified resource is resized. + If not specified, it defaults to NotRequired. + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + description: |- + Compute Resources required by this container. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + properties: + claims: + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + + + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + + + This field is immutable. It can only be set for containers. + items: + description: ResourceClaim references one entry in + PodSpec.ResourceClaims. + properties: + name: + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + restartPolicy: + description: |- + RestartPolicy defines the restart behavior of individual containers in a pod. + This field may only be set for init containers, and the only allowed value is "Always". + For non-init containers or when this field is not specified, + the restart behavior is defined by the Pod's restart policy and the container type. + Setting the RestartPolicy as "Always" for the init container will have the following effect: + this init container will be continually restarted on + exit until all regular containers have terminated. Once all regular + containers have completed, all init containers with restartPolicy "Always" + will be shut down. This lifecycle differs from normal init containers and + is often referred to as a "sidecar" container. Although this init + container still starts in the init container sequence, it does not wait + for the container to complete before proceeding to the next init + container. Instead, the next init container starts immediately after this + init container is started, or after any startupProbe has successfully + completed. + type: string + securityContext: + description: |- + SecurityContext defines the security options the container should be run with. + If set, the fields of SecurityContext override the equivalent fields of PodSecurityContext. + More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ + properties: + allowPrivilegeEscalation: + description: |- + AllowPrivilegeEscalation controls whether a process can gain more + privileges than its parent process. This bool directly controls if + the no_new_privs flag will be set on the container process. + AllowPrivilegeEscalation is true always when the container is: + 1) run as Privileged + 2) has CAP_SYS_ADMIN + Note that this field cannot be set when spec.os.name is windows. + type: boolean + capabilities: + description: |- + The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the container runtime. + Note that this field cannot be set when spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + type: object + privileged: + description: |- + Run container in privileged mode. + Processes in privileged containers are essentially equivalent to root on the host. + Defaults to false. + Note that this field cannot be set when spec.os.name is windows. + type: boolean + procMount: + description: |- + procMount denotes the type of proc mount to use for the containers. + The default is DefaultProcMount which uses the container runtime defaults for + readonly paths and masked paths. + This requires the ProcMountType feature flag to be enabled. + Note that this field cannot be set when spec.os.name is windows. + type: string + readOnlyRootFilesystem: + description: |- + Whether this container has a read-only root filesystem. + Default is false. + Note that this field cannot be set when spec.os.name is windows. + type: boolean + runAsGroup: + description: |- + The GID to run the entrypoint of the container process. + Uses runtime default if unset. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: |- + Indicates that the container must run as a non-root user. + If true, the Kubelet will validate the image at runtime to ensure that it + does not run as UID 0 (root) and fail to start the container if it does. + If unset or false, no such validation will be performed. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: |- + The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: |- + The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random SELinux context for each + container. May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies + to the container. + type: string + role: + description: Role is a SELinux role label that applies + to the container. + type: string + type: + description: Type is a SELinux type label that applies + to the container. + type: string + user: + description: User is a SELinux user label that applies + to the container. + type: string + type: object + seccompProfile: + description: |- + The seccomp options to use by this container. If seccomp options are + provided at both the pod & container level, the container options + override the pod options. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile defined in a file on the node should be used. + The profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be set for any other type. + type: string + type: + description: |- + type indicates which kind of seccomp profile will be applied. + Valid options are: + + + Localhost - a profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile should be used. + Unconfined - no profile should be applied. + type: string + required: + - type + type: object + windowsOptions: + description: |- + The Windows specific settings applied to all containers. + If unspecified, the options from the PodSecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: |- + GMSACredentialSpec is where the GMSA admission webhook + (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the + GMSA credential spec named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name + of the GMSA credential spec to use. + type: string + hostProcess: + description: |- + HostProcess determines if a container should be run as a 'Host Process' container. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: |- + The UserName in Windows to run the entrypoint of the container process. + Defaults to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: string + type: object + type: object + startupProbe: + description: |- + StartupProbe indicates that the Pod has successfully initialized. + If specified, no other probes are executed until this completes successfully. + If this probe fails, the Pod will be restarted, just as if the livenessProbe failed. + This can be used to provide different probe parameters at the beginning of a Pod's lifecycle, + when it might take a long time to load data or warm a cache, than during steady-state operation. + This cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC + port. + properties: + port: + description: Port number of the gRPC service. Number + must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, + defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + stdin: + description: |- + Whether this container should allocate a buffer for stdin in the container runtime. If this + is not set, reads from stdin in the container will always result in EOF. + Default is false. + type: boolean + stdinOnce: + description: |- + Whether the container runtime should close the stdin channel after it has been opened by + a single attach. When stdin is true the stdin stream will remain open across multiple attach + sessions. If stdinOnce is set to true, stdin is opened on container start, is empty until the + first client attaches to stdin, and then remains open and accepts data until the client disconnects, + at which time stdin is closed and remains closed until the container is restarted. If this + flag is false, a container processes that reads from stdin will never receive an EOF. + Default is false + type: boolean + terminationMessagePath: + description: |- + Optional: Path at which the file to which the container's termination message + will be written is mounted into the container's filesystem. + Message written is intended to be brief final status, such as an assertion failure message. + Will be truncated by the node if greater than 4096 bytes. The total message length across + all containers will be limited to 12kb. + Defaults to /dev/termination-log. + Cannot be updated. + type: string + terminationMessagePolicy: + description: |- + Indicate how the termination message should be populated. File will use the contents of + terminationMessagePath to populate the container status message on both success and failure. + FallbackToLogsOnError will use the last chunk of container log output if the termination + message file is empty and the container exited with an error. + The log output is limited to 2048 bytes or 80 lines, whichever is smaller. + Defaults to File. + Cannot be updated. + type: string + tty: + description: |- + Whether this container should allocate a TTY for itself, also requires 'stdin' to be true. + Default is false. + type: boolean + volumeDevices: + description: volumeDevices is the list of block devices + to be used by the container. + items: + description: volumeDevice describes a mapping of a raw + block device within a container. + properties: + devicePath: + description: devicePath is the path inside of the + container that the device will be mapped to. + type: string + name: + description: name must match the name of a persistentVolumeClaim + in the pod + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + description: |- + Pod volumes to mount into the container's filesystem. + Cannot be updated. + items: + description: VolumeMount describes a mounting of a Volume + within a container. + properties: + mountPath: + description: |- + Path within the container at which the volume should be mounted. Must + not contain ':'. + type: string + mountPropagation: + description: |- + mountPropagation determines how mounts are propagated from the host + to container and the other way around. + When not set, MountPropagationNone is used. + This field is beta in 1.10. + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: |- + Mounted read-only if true, read-write otherwise (false or unspecified). + Defaults to false. + type: boolean + subPath: + description: |- + Path within the volume from which the container's volume should be mounted. + Defaults to "" (volume's root). + type: string + subPathExpr: + description: |- + Expanded path within the volume from which the container's volume should be mounted. + Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment. + Defaults to "" (volume's root). + SubPathExpr and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + description: |- + Container's working directory. + If not specified, the container runtime's default will be used, which + might be configured in the container image. + Cannot be updated. + type: string + required: + - name + type: object + type: array + nodeName: + description: |- + NodeName is a request to schedule this pod onto a specific node. If it is non-empty, + the scheduler simply schedules this pod onto that node, assuming that it fits resource + requirements. + type: string + nodeSelector: + additionalProperties: + type: string + description: |- + NodeSelector is a selector which must be true for the pod to fit on a node. + Selector which must match a node's labels for the pod to be scheduled on that node. + More info: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ + type: object + x-kubernetes-map-type: atomic + os: + description: |- + Specifies the OS of the containers in the pod. + Some pod and container fields are restricted if this is set. + + + If the OS field is set to linux, the following fields must be unset: + -securityContext.windowsOptions + + + If the OS field is set to windows, following fields must be unset: + - spec.hostPID + - spec.hostIPC + - spec.hostUsers + - spec.securityContext.seLinuxOptions + - spec.securityContext.seccompProfile + - spec.securityContext.fsGroup + - spec.securityContext.fsGroupChangePolicy + - spec.securityContext.sysctls + - spec.shareProcessNamespace + - spec.securityContext.runAsUser + - spec.securityContext.runAsGroup + - spec.securityContext.supplementalGroups + - spec.containers[*].securityContext.seLinuxOptions + - spec.containers[*].securityContext.seccompProfile + - spec.containers[*].securityContext.capabilities + - spec.containers[*].securityContext.readOnlyRootFilesystem + - spec.containers[*].securityContext.privileged + - spec.containers[*].securityContext.allowPrivilegeEscalation + - spec.containers[*].securityContext.procMount + - spec.containers[*].securityContext.runAsUser + - spec.containers[*].securityContext.runAsGroup + properties: + name: + description: |- + Name is the name of the operating system. The currently supported values are linux and windows. + Additional value may be defined in future and can be one of: + https://github.com/opencontainers/runtime-spec/blob/master/config.md#platform-specific-configuration + Clients should expect to handle additional values and treat unrecognized values in this field as os: null + type: string + required: + - name + type: object + overhead: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Overhead represents the resource overhead associated with running a pod for a given RuntimeClass. + This field will be autopopulated at admission time by the RuntimeClass admission controller. If + the RuntimeClass admission controller is enabled, overhead must not be set in Pod create requests. + The RuntimeClass admission controller will reject Pod create requests which have the overhead already + set. If RuntimeClass is configured and selected in the PodSpec, Overhead will be set to the value + defined in the corresponding RuntimeClass, otherwise it will remain unset and treated as zero. + More info: https://git.k8s.io/enhancements/keps/sig-node/688-pod-overhead/README.md + type: object + preemptionPolicy: + description: |- + PreemptionPolicy is the Policy for preempting pods with lower priority. + One of Never, PreemptLowerPriority. + Defaults to PreemptLowerPriority if unset. + type: string + priority: + description: |- + The priority value. Various system components use this field to find the + priority of the pod. When Priority Admission Controller is enabled, it + prevents users from setting this field. The admission controller populates + this field from PriorityClassName. + The higher the value, the higher the priority. + format: int32 + type: integer + priorityClassName: + description: |- + If specified, indicates the pod's priority. "system-node-critical" and + "system-cluster-critical" are two special keywords which indicate the + highest priorities with the former being the highest priority. Any other + name must be defined by creating a PriorityClass object with that name. + If not specified, the pod priority will be default or zero if there is no + default. + type: string + readinessGates: + description: |- + If specified, all readiness gates will be evaluated for pod readiness. + A pod is ready when all its containers are ready AND + all conditions specified in the readiness gates have status equal to "True" + More info: https://git.k8s.io/enhancements/keps/sig-network/580-pod-readiness-gates + items: + description: PodReadinessGate contains the reference to a pod + condition + properties: + conditionType: + description: ConditionType refers to a condition in the + pod's condition list with matching type. + type: string + required: + - conditionType + type: object + type: array + resourceClaims: + description: |- + ResourceClaims defines which ResourceClaims must be allocated + and reserved before the Pod is allowed to start. The resources + will be made available to those containers which consume them + by name. + + + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + + + This field is immutable. + items: + description: |- + PodResourceClaim references exactly one ResourceClaim through a ClaimSource. + It adds a name to it that uniquely identifies the ResourceClaim inside the Pod. + Containers that need access to the ResourceClaim reference it with this name. + properties: + name: + description: |- + Name uniquely identifies this resource claim inside the pod. + This must be a DNS_LABEL. + type: string + source: + description: Source describes where to find the ResourceClaim. + properties: + resourceClaimName: + description: |- + ResourceClaimName is the name of a ResourceClaim object in the same + namespace as this pod. + type: string + resourceClaimTemplateName: + description: |- + ResourceClaimTemplateName is the name of a ResourceClaimTemplate + object in the same namespace as this pod. + + + The template will be used to create a new ResourceClaim, which will + be bound to this pod. When this pod is deleted, the ResourceClaim + will also be deleted. The pod name and resource name, along with a + generated component, will be used to form a unique name for the + ResourceClaim, which will be recorded in pod.status.resourceClaimStatuses. + + + This field is immutable and no changes will be made to the + corresponding ResourceClaim by the control plane after creating the + ResourceClaim. + type: string + type: object + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + restartPolicy: + description: |- + Restart policy for all containers within the pod. + One of Always, OnFailure, Never. In some contexts, only a subset of those values may be permitted. + Default to Always. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#restart-policy + type: string + runtimeClassName: + description: |- + RuntimeClassName refers to a RuntimeClass object in the node.k8s.io group, which should be used + to run this pod. If no RuntimeClass resource matches the named class, the pod will not be run. + If unset or empty, the "legacy" RuntimeClass will be used, which is an implicit class with an + empty definition that uses the default runtime handler. + More info: https://git.k8s.io/enhancements/keps/sig-node/585-runtime-class + type: string + schedulerName: + description: |- + If specified, the pod will be dispatched by specified scheduler. + If not specified, the pod will be dispatched by default scheduler. + type: string + schedulingGates: + description: |- + SchedulingGates is an opaque list of values that if specified will block scheduling the pod. + If schedulingGates is not empty, the pod will stay in the SchedulingGated state and the + scheduler will not attempt to schedule the pod. + + + SchedulingGates can only be set at pod creation time, and be removed only afterwards. + + + This is a beta feature enabled by the PodSchedulingReadiness feature gate. + items: + description: PodSchedulingGate is associated to a Pod to guard + its scheduling. + properties: + name: + description: |- + Name of the scheduling gate. + Each scheduling gate must have a unique name field. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + securityContext: + description: |- + SecurityContext holds pod-level security attributes and common container settings. + Optional: Defaults to empty. See type description for default values of each field. + properties: + fsGroup: + description: |- + A special supplemental group that applies to all containers in a pod. + Some volume types allow the Kubelet to change the ownership of that volume + to be owned by the pod: + + + 1. The owning GID will be the FSGroup + 2. The setgid bit is set (new files created in the volume will be owned by FSGroup) + 3. The permission bits are OR'd with rw-rw---- + + + If unset, the Kubelet will not modify the ownership and permissions of any volume. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + fsGroupChangePolicy: + description: |- + fsGroupChangePolicy defines behavior of changing ownership and permission of the volume + before being exposed inside Pod. This field will only apply to + volume types which support fsGroup based ownership(and permissions). + It will have no effect on ephemeral volume types such as: secret, configmaps + and emptydir. + Valid values are "OnRootMismatch" and "Always". If not specified, "Always" is used. + Note that this field cannot be set when spec.os.name is windows. + type: string + runAsGroup: + description: |- + The GID to run the entrypoint of the container process. + Uses runtime default if unset. + May also be set in SecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence + for that container. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: |- + Indicates that the container must run as a non-root user. + If true, the Kubelet will validate the image at runtime to ensure that it + does not run as UID 0 (root) and fail to start the container if it does. + If unset or false, no such validation will be performed. + May also be set in SecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: |- + The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in SecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence + for that container. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: |- + The SELinux context to be applied to all containers. + If unspecified, the container runtime will allocate a random SELinux context for each + container. May also be set in SecurityContext. If set in + both SecurityContext and PodSecurityContext, the value specified in SecurityContext + takes precedence for that container. + Note that this field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies + to the container. + type: string + role: + description: Role is a SELinux role label that applies + to the container. + type: string + type: + description: Type is a SELinux type label that applies + to the container. + type: string + user: + description: User is a SELinux user label that applies + to the container. + type: string + type: object + seccompProfile: + description: |- + The seccomp options to use by the containers in this pod. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile defined in a file on the node should be used. + The profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be set for any other type. + type: string + type: + description: |- + type indicates which kind of seccomp profile will be applied. + Valid options are: + + + Localhost - a profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile should be used. + Unconfined - no profile should be applied. + type: string + required: + - type + type: object + supplementalGroups: + description: |- + A list of groups applied to the first process run in each container, in addition + to the container's primary GID, the fsGroup (if specified), and group memberships + defined in the container image for the uid of the container process. If unspecified, + no additional groups are added to any container. Note that group memberships + defined in the container image for the uid of the container process are still effective, + even if they are not included in this list. + Note that this field cannot be set when spec.os.name is windows. + items: + format: int64 + type: integer + type: array + sysctls: + description: |- + Sysctls hold a list of namespaced sysctls used for the pod. Pods with unsupported + sysctls (by the container runtime) might fail to launch. + Note that this field cannot be set when spec.os.name is windows. + items: + description: Sysctl defines a kernel parameter to be set + properties: + name: + description: Name of a property to set + type: string + value: + description: Value of a property to set + type: string + required: + - name + - value + type: object + type: array + windowsOptions: + description: |- + The Windows specific settings applied to all containers. + If unspecified, the options within a container's SecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: |- + GMSACredentialSpec is where the GMSA admission webhook + (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the + GMSA credential spec named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the + GMSA credential spec to use. + type: string + hostProcess: + description: |- + HostProcess determines if a container should be run as a 'Host Process' container. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: |- + The UserName in Windows to run the entrypoint of the container process. + Defaults to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: string + type: object + type: object + serviceAccount: + description: |- + DeprecatedServiceAccount is a depreciated alias for ServiceAccountName. + Deprecated: Use serviceAccountName instead. + type: string + serviceAccountName: + description: |- + ServiceAccountName is the name of the ServiceAccount to use to run this pod. + More info: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/ + type: string + setHostnameAsFQDN: + description: |- + If true the pod's hostname will be configured as the pod's FQDN, rather than the leaf name (the default). + In Linux containers, this means setting the FQDN in the hostname field of the kernel (the nodename field of struct utsname). + In Windows containers, this means setting the registry value of hostname for the registry key HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters to FQDN. + If a pod does not have FQDN, this has no effect. + Default to false. + type: boolean + shareProcessNamespace: + description: |- + Share a single process namespace between all of the containers in a pod. + When this is set containers will be able to view and signal processes from other containers + in the same pod, and the first process in each container will not be assigned PID 1. + HostPID and ShareProcessNamespace cannot both be set. + Optional: Default to false. + type: boolean + subdomain: + description: |- + If specified, the fully qualified Pod hostname will be "...svc.". + If not specified, the pod will not have a domainname at all. + type: string + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully. May be decreased in delete request. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + If this value is nil, the default grace period will be used instead. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + Defaults to 30 seconds. + format: int64 + type: integer + tolerations: + description: If specified, the pod's tolerations. + items: + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . + properties: + effect: + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. + type: string + operator: + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. + type: string + tolerationSeconds: + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. + format: int64 + type: integer + value: + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. + type: string + type: object + type: array + topologySpreadConstraints: + description: |- + TopologySpreadConstraints describes how a group of pods ought to spread across topology + domains. Scheduler will schedule pods in a way which abides by the constraints. + All topologySpreadConstraints are ANDed. + items: + description: TopologySpreadConstraint specifies how to spread + matching pods among the given topology. + properties: + labelSelector: + description: |- + LabelSelector is used to find matching pods. + Pods that match this label selector are counted to determine the number of pods + in their corresponding topology domain. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select the pods over which + spreading will be calculated. The keys are used to lookup values from the + incoming pod labels, those key-value labels are ANDed with labelSelector + to select the group of existing pods over which spreading will be calculated + for the incoming pod. The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + MatchLabelKeys cannot be set when LabelSelector isn't set. + Keys that don't exist in the incoming pod labels will + be ignored. A null or empty list means only match against labelSelector. + + + This is a beta field and requires the MatchLabelKeysInPodTopologySpread feature gate to be enabled (enabled by default). + items: + type: string + type: array + x-kubernetes-list-type: atomic + maxSkew: + description: |- + MaxSkew describes the degree to which pods may be unevenly distributed. + When `whenUnsatisfiable=DoNotSchedule`, it is the maximum permitted difference + between the number of matching pods in the target topology and the global minimum. + The global minimum is the minimum number of matching pods in an eligible domain + or zero if the number of eligible domains is less than MinDomains. + For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same + labelSelector spread as 2/2/1: + In this case, the global minimum is 1. + | zone1 | zone2 | zone3 | + | P P | P P | P | + - if MaxSkew is 1, incoming pod can only be scheduled to zone3 to become 2/2/2; + scheduling it onto zone1(zone2) would make the ActualSkew(3-1) on zone1(zone2) + violate MaxSkew(1). + - if MaxSkew is 2, incoming pod can be scheduled onto any zone. + When `whenUnsatisfiable=ScheduleAnyway`, it is used to give higher precedence + to topologies that satisfy it. + It's a required field. Default value is 1 and 0 is not allowed. + format: int32 + type: integer + minDomains: + description: |- + MinDomains indicates a minimum number of eligible domains. + When the number of eligible domains with matching topology keys is less than minDomains, + Pod Topology Spread treats "global minimum" as 0, and then the calculation of Skew is performed. + And when the number of eligible domains with matching topology keys equals or greater than minDomains, + this value has no effect on scheduling. + As a result, when the number of eligible domains is less than minDomains, + scheduler won't schedule more than maxSkew Pods to those domains. + If value is nil, the constraint behaves as if MinDomains is equal to 1. + Valid values are integers greater than 0. + When value is not nil, WhenUnsatisfiable must be DoNotSchedule. + + + For example, in a 3-zone cluster, MaxSkew is set to 2, MinDomains is set to 5 and pods with the same + labelSelector spread as 2/2/2: + | zone1 | zone2 | zone3 | + | P P | P P | P P | + The number of domains is less than 5(MinDomains), so "global minimum" is treated as 0. + In this situation, new pod with the same labelSelector cannot be scheduled, + because computed skew will be 3(3 - 0) if new Pod is scheduled to any of the three zones, + it will violate MaxSkew. + + + This is a beta field and requires the MinDomainsInPodTopologySpread feature gate to be enabled (enabled by default). + format: int32 + type: integer + nodeAffinityPolicy: + description: |- + NodeAffinityPolicy indicates how we will treat Pod's nodeAffinity/nodeSelector + when calculating pod topology spread skew. Options are: + - Honor: only nodes matching nodeAffinity/nodeSelector are included in the calculations. + - Ignore: nodeAffinity/nodeSelector are ignored. All nodes are included in the calculations. + + + If this value is nil, the behavior is equivalent to the Honor policy. + This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag. + type: string + nodeTaintsPolicy: + description: |- + NodeTaintsPolicy indicates how we will treat node taints when calculating + pod topology spread skew. Options are: + - Honor: nodes without taints, along with tainted nodes for which the incoming pod + has a toleration, are included. + - Ignore: node taints are ignored. All nodes are included. + + + If this value is nil, the behavior is equivalent to the Ignore policy. + This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag. + type: string + topologyKey: + description: |- + TopologyKey is the key of node labels. Nodes that have a label with this key + and identical values are considered to be in the same topology. + We consider each as a "bucket", and try to put balanced number + of pods into each bucket. + We define a domain as a particular instance of a topology. + Also, we define an eligible domain as a domain whose nodes meet the requirements of + nodeAffinityPolicy and nodeTaintsPolicy. + e.g. If TopologyKey is "kubernetes.io/hostname", each Node is a domain of that topology. + And, if TopologyKey is "topology.kubernetes.io/zone", each zone is a domain of that topology. + It's a required field. + type: string + whenUnsatisfiable: + description: |- + WhenUnsatisfiable indicates how to deal with a pod if it doesn't satisfy + the spread constraint. + - DoNotSchedule (default) tells the scheduler not to schedule it. + - ScheduleAnyway tells the scheduler to schedule the pod in any location, + but giving higher precedence to topologies that would help reduce the + skew. + A constraint is considered "Unsatisfiable" for an incoming pod + if and only if every possible node assignment for that pod would violate + "MaxSkew" on some topology. + For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same + labelSelector spread as 3/1/1: + | zone1 | zone2 | zone3 | + | P P P | P | P | + If WhenUnsatisfiable is set to DoNotSchedule, incoming pod can only be scheduled + to zone2(zone3) to become 3/2/1(3/1/2) as ActualSkew(2-1) on zone2(zone3) satisfies + MaxSkew(1). In other words, the cluster can still be imbalanced, but scheduler + won't make it *more* imbalanced. + It's a required field. + type: string + required: + - maxSkew + - topologyKey + - whenUnsatisfiable + type: object + type: array + x-kubernetes-list-map-keys: + - topologyKey + - whenUnsatisfiable + x-kubernetes-list-type: map + volumes: + description: |- + List of volumes that can be mounted by containers belonging to the pod. + More info: https://kubernetes.io/docs/concepts/storage/volumes + items: + description: Volume represents a named volume in a pod that + may be accessed by any container in the pod. + properties: + awsElasticBlockStore: + description: |- + awsElasticBlockStore represents an AWS Disk resource that is attached to a + kubelet's host machine and then exposed to the pod. + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + properties: + fsType: + description: |- + fsType is the filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + partition: + description: |- + partition is the partition in the volume that you want to mount. + If omitted, the default is to mount by volume name. + Examples: For volume /dev/sda1, you specify the partition as "1". + Similarly, the volume partition for /dev/sda is "0" (or you can leave the property empty). + format: int32 + type: integer + readOnly: + description: |- + readOnly value true will force the readOnly setting in VolumeMounts. + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + type: boolean + volumeID: + description: |- + volumeID is unique ID of the persistent disk resource in AWS (Amazon EBS volume). + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + type: string + required: + - volumeID + type: object + azureDisk: + description: azureDisk represents an Azure Data Disk mount + on the host and bind mount to the pod. + properties: + cachingMode: + description: 'cachingMode is the Host Caching mode: + None, Read Only, Read Write.' + type: string + diskName: + description: diskName is the Name of the data disk in + the blob storage + type: string + diskURI: + description: diskURI is the URI of data disk in the + blob storage + type: string + fsType: + description: |- + fsType is Filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + kind: + description: 'kind expected values are Shared: multiple + blob disks per storage account Dedicated: single + blob disk per storage account Managed: azure managed + data disk (only in managed availability set). defaults + to shared' + type: string + readOnly: + description: |- + readOnly Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + description: azureFile represents an Azure File Service + mount on the host and bind mount to the pod. + properties: + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretName: + description: secretName is the name of secret that + contains Azure Storage Account Name and Key + type: string + shareName: + description: shareName is the azure share Name + type: string + required: + - secretName + - shareName + type: object + cephfs: + description: cephFS represents a Ceph FS mount on the host + that shares a pod's lifetime + properties: + monitors: + description: |- + monitors is Required: Monitors is a collection of Ceph monitors + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + items: + type: string + type: array + path: + description: 'path is Optional: Used as the mounted + root, rather than the full Ceph tree, default is /' + type: string + readOnly: + description: |- + readOnly is Optional: Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + type: boolean + secretFile: + description: |- + secretFile is Optional: SecretFile is the path to key ring for User, default is /etc/ceph/user.secret + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + type: string + secretRef: + description: |- + secretRef is Optional: SecretRef is reference to the authentication secret for User, default is empty. + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + 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 + user: + description: |- + user is optional: User is the rados user name, default is admin + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + type: string + required: + - monitors + type: object + cinder: + description: |- + cinder represents a cinder volume attached and mounted on kubelets host machine. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + type: string + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + type: boolean + secretRef: + description: |- + secretRef is optional: points to a secret object containing parameters used to connect + to OpenStack. + 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 + volumeID: + description: |- + volumeID used to identify the volume in cinder. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + type: string + required: + - volumeID + type: object + configMap: + description: configMap represents a configMap that should + populate this volume + properties: + defaultMode: + description: |- + defaultMode is optional: mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + items: + description: |- + items if unspecified, each key-value pair in the Data field of the referenced + ConfigMap will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the ConfigMap, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within a + volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + 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 + optional: + description: optional specify whether the ConfigMap + or its keys must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + csi: + description: csi (Container Storage Interface) represents + ephemeral storage that is handled by certain external + CSI drivers (Beta feature). + properties: + driver: + description: |- + driver is the name of the CSI driver that handles this volume. + Consult with your admin for the correct name as registered in the cluster. + type: string + fsType: + description: |- + fsType to mount. Ex. "ext4", "xfs", "ntfs". + If not provided, the empty value is passed to the associated CSI driver + which will determine the default filesystem to apply. + type: string + nodePublishSecretRef: + description: |- + nodePublishSecretRef is a reference to the secret object containing + sensitive information to pass to the CSI driver to complete the CSI + NodePublishVolume and NodeUnpublishVolume calls. + This field is optional, and may be empty if no secret is required. If the + secret object contains more than one secret, all secret references are passed. + 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 + readOnly: + description: |- + readOnly specifies a read-only configuration for the volume. + Defaults to false (read/write). + type: boolean + volumeAttributes: + additionalProperties: + type: string + description: |- + volumeAttributes stores driver-specific properties that are passed to the CSI + driver. Consult your driver's documentation for supported values. + type: object + required: + - driver + type: object + downwardAPI: + description: downwardAPI represents downward API about the + pod that should populate this volume + properties: + defaultMode: + description: |- + Optional: mode bits to use on created files by default. Must be a + Optional: mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + items: + description: Items is a list of downward API volume + file + items: + description: DownwardAPIVolumeFile represents information + to create the file containing the pod field + properties: + fieldRef: + description: 'Required: Selects a field of the + pod: only annotations, labels, name and namespace + are supported.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in + the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + description: |- + Optional: mode bits used to set permissions on this file, must be an octal value + between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: 'Required: Path is the relative + path name of the file to be created. Must not + be absolute or contain the ''..'' path. Must + be utf-8 encoded. The first item of the relative + path must not start with ''..''' + type: string + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported. + properties: + containerName: + description: 'Container name: required for + volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of + the exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + type: object + emptyDir: + description: |- + emptyDir represents a temporary directory that shares a pod's lifetime. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir + properties: + medium: + description: |- + medium represents what type of storage medium should back this directory. + The default is "" which means to use the node's default medium. + Must be an empty string (default) or Memory. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + description: |- + sizeLimit is the total amount of local storage required for this EmptyDir volume. + The size limit is also applicable for memory medium. + The maximum usage on memory medium EmptyDir would be the minimum value between + the SizeLimit specified here and the sum of memory limits of all containers in a pod. + The default is nil which means that the limit is undefined. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + description: |- + ephemeral represents a volume that is handled by a cluster storage driver. + The volume's lifecycle is tied to the pod that defines it - it will be created before the pod starts, + and deleted when the pod is removed. + + + Use this if: + a) the volume is only needed while the pod runs, + b) features of normal volumes like restoring from snapshot or capacity + tracking are needed, + c) the storage driver is specified through a storage class, and + d) the storage driver supports dynamic volume provisioning through + a PersistentVolumeClaim (see EphemeralVolumeSource for more + information on the connection between this volume type + and PersistentVolumeClaim). + + + Use PersistentVolumeClaim or one of the vendor-specific + APIs for volumes that persist for longer than the lifecycle + of an individual pod. + + + Use CSI for light-weight local ephemeral volumes if the CSI driver is meant to + be used that way - see the documentation of the driver for + more information. + + + A pod can use both types of ephemeral volumes and + persistent volumes at the same time. + properties: + volumeClaimTemplate: + description: |- + Will be used to create a stand-alone PVC to provision the volume. + The pod in which this EphemeralVolumeSource is embedded will be the + owner of the PVC, i.e. the PVC will be deleted together with the + pod. The name of the PVC will be `-` where + `` is the name from the `PodSpec.Volumes` array + entry. Pod validation will reject the pod if the concatenated name + is not valid for a PVC (for example, too long). + + + An existing PVC with that name that is not owned by the pod + will *not* be used for the pod to avoid using an unrelated + volume by mistake. Starting the pod is then blocked until + the unrelated PVC is removed. If such a pre-created PVC is + meant to be used by the pod, the PVC has to updated with an + owner reference to the pod once the pod exists. Normally + this should not be necessary, but it may be useful when + manually reconstructing a broken cluster. + + + This field is read-only and no changes will be made by Kubernetes + to the PVC after it has been created. + + + Required, must not be nil. + properties: + metadata: + description: |- + May contain labels and annotations that will be copied into the PVC + when creating it. No other fields are allowed and will be rejected during + validation. + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + description: |- + The specification for the PersistentVolumeClaim. The entire content is + copied unchanged into the PVC that gets created from this + template. The same fields as in a PersistentVolumeClaim + are also valid here. + properties: + accessModes: + description: |- + accessModes contains the desired access modes the volume should have. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1 + items: + type: string + type: array + dataSource: + description: |- + dataSource field can be used to specify either: + * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) + * An existing PVC (PersistentVolumeClaim) + If the provisioner or an external controller can support the specified data source, + it will create a new volume based on the contents of the specified data source. + When the AnyVolumeDataSource feature gate is enabled, dataSource contents will be copied to dataSourceRef, + and dataSourceRef contents will be copied to dataSource when dataSourceRef.namespace is not specified. + If the namespace is specified, then dataSourceRef will not be copied to dataSource. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource + being referenced + type: string + name: + description: Name is the name of resource + being referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + description: |- + dataSourceRef specifies the object from which to populate the volume with data, if a non-empty + volume is desired. This may be any object from a non-empty API group (non + core object) or a PersistentVolumeClaim object. + When this field is specified, volume binding will only succeed if the type of + the specified object matches some installed volume populator or dynamic + provisioner. + This field will replace the functionality of the dataSource field and as such + if both fields are non-empty, they must have the same value. For backwards + compatibility, when namespace isn't specified in dataSourceRef, + both fields (dataSource and dataSourceRef) will be set to the same + value automatically if one of them is empty and the other is non-empty. + When namespace is specified in dataSourceRef, + dataSource isn't set to the same value and must be empty. + There are three important differences between dataSource and dataSourceRef: + * While dataSource only allows two specific types of objects, dataSourceRef + allows any non-core object, as well as PersistentVolumeClaim objects. + * While dataSource ignores disallowed values (dropping them), dataSourceRef + preserves all values, and generates an error if a disallowed value is + specified. + * While dataSource only allows local objects, dataSourceRef allows objects + in any namespaces. + (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled. + (Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource + being referenced + type: string + name: + description: Name is the name of resource + being referenced + type: string + namespace: + description: |- + Namespace is the namespace of resource being referenced + Note that when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details. + (Alpha) This field requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + type: string + required: + - kind + - name + type: object + resources: + description: |- + resources represents the minimum resources the volume should have. + If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements + that are lower than previous value but must still be higher than capacity recorded in the + status field of the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + selector: + description: selector is a label query over + volumes to consider for binding. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + description: |- + storageClassName is the name of the StorageClass required by the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1 + type: string + volumeAttributesClassName: + description: |- + volumeAttributesClassName may be used to set the VolumeAttributesClass used by this claim. + If specified, the CSI driver will create or update the volume with the attributes defined + in the corresponding VolumeAttributesClass. This has a different purpose than storageClassName, + it can be changed after the claim is created. An empty string value means that no VolumeAttributesClass + will be applied to the claim but it's not allowed to reset this field to empty string once it is set. + If unspecified and the PersistentVolumeClaim is unbound, the default VolumeAttributesClass + will be set by the persistentvolume controller if it exists. + If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be + set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource + exists. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#volumeattributesclass + (Alpha) Using this field requires the VolumeAttributesClass feature gate to be enabled. + type: string + volumeMode: + description: |- + volumeMode defines what type of volume is required by the claim. + Value of Filesystem is implied when not included in claim spec. + type: string + volumeName: + description: volumeName is the binding reference + to the PersistentVolume backing this claim. + type: string + type: object + required: + - spec + type: object + type: object + fc: + description: fc represents a Fibre Channel resource that + is attached to a kubelet's host machine and then exposed + to the pod. + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + lun: + description: 'lun is Optional: FC target lun number' + format: int32 + type: integer + readOnly: + description: |- + readOnly is Optional: Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + targetWWNs: + description: 'targetWWNs is Optional: FC target worldwide + names (WWNs)' + items: + type: string + type: array + wwids: + description: |- + wwids Optional: FC volume world wide identifiers (wwids) + Either wwids or combination of targetWWNs and lun must be set, but not both simultaneously. + items: + type: string + type: array + type: object + flexVolume: + description: |- + flexVolume represents a generic volume resource that is + provisioned/attached using an exec based plugin. + properties: + driver: + description: driver is the name of the driver to use + for this volume. + type: string + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". The default filesystem depends on FlexVolume script. + type: string + options: + additionalProperties: + type: string + description: 'options is Optional: this field holds + extra command options if any.' + type: object + readOnly: + description: |- + readOnly is Optional: defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: |- + secretRef is Optional: secretRef is reference to the secret object containing + sensitive information to pass to the plugin scripts. This may be + empty if no secret object is specified. If the secret object + contains more than one secret, all secrets are passed to the plugin + scripts. + 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 + required: + - driver + type: object + flocker: + description: flocker represents a Flocker volume attached + to a kubelet's host machine. This depends on the Flocker + control service being running + properties: + datasetName: + description: |- + datasetName is Name of the dataset stored as metadata -> name on the dataset for Flocker + should be considered as deprecated + type: string + datasetUUID: + description: datasetUUID is the UUID of the dataset. + This is unique identifier of a Flocker dataset + type: string + type: object + gcePersistentDisk: + description: |- + gcePersistentDisk represents a GCE Disk resource that is attached to a + kubelet's host machine and then exposed to the pod. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + properties: + fsType: + description: |- + fsType is filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + partition: + description: |- + partition is the partition in the volume that you want to mount. + If omitted, the default is to mount by volume name. + Examples: For volume /dev/sda1, you specify the partition as "1". + Similarly, the volume partition for /dev/sda is "0" (or you can leave the property empty). + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + format: int32 + type: integer + pdName: + description: |- + pdName is unique name of the PD resource in GCE. Used to identify the disk in GCE. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + type: string + readOnly: + description: |- + readOnly here will force the ReadOnly setting in VolumeMounts. + Defaults to false. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + type: boolean + required: + - pdName + type: object + gitRepo: + description: |- + gitRepo represents a git repository at a particular revision. + DEPRECATED: GitRepo is deprecated. To provision a container with a git repo, mount an + EmptyDir into an InitContainer that clones the repo using git, then mount the EmptyDir + into the Pod's container. + properties: + directory: + description: |- + directory is the target directory name. + Must not contain or start with '..'. If '.' is supplied, the volume directory will be the + git repository. Otherwise, if specified, the volume will contain the git repository in + the subdirectory with the given name. + type: string + repository: + description: repository is the URL + type: string + revision: + description: revision is the commit hash for the specified + revision. + type: string + required: + - repository + type: object + glusterfs: + description: |- + glusterfs represents a Glusterfs mount on the host that shares a pod's lifetime. + More info: https://examples.k8s.io/volumes/glusterfs/README.md + properties: + endpoints: + description: |- + endpoints is the endpoint name that details Glusterfs topology. + More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod + type: string + path: + description: |- + path is the Glusterfs volume path. + More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod + type: string + readOnly: + description: |- + readOnly here will force the Glusterfs volume to be mounted with read-only permissions. + Defaults to false. + More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod + type: boolean + required: + - endpoints + - path + type: object + hostPath: + description: |- + hostPath represents a pre-existing file or directory on the host + machine that is directly exposed to the container. This is generally + used for system agents or other privileged things that are allowed + to see the host machine. Most containers will NOT need this. + More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + --- + TODO(jonesdl) We need to restrict who can use host directory mounts and who can/can not + mount host directories as read/write. + properties: + path: + description: |- + path of the directory on the host. + If the path is a symlink, it will follow the link to the real path. + More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + type: string + type: + description: |- + type for HostPath Volume + Defaults to "" + More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + type: string + required: + - path + type: object + iscsi: + description: |- + iscsi represents an ISCSI Disk resource that is attached to a + kubelet's host machine and then exposed to the pod. + More info: https://examples.k8s.io/volumes/iscsi/README.md + properties: + chapAuthDiscovery: + description: chapAuthDiscovery defines whether support + iSCSI Discovery CHAP authentication + type: boolean + chapAuthSession: + description: chapAuthSession defines whether support + iSCSI Session CHAP authentication + type: boolean + fsType: + description: |- + fsType is the filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#iscsi + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + initiatorName: + description: |- + initiatorName is the custom iSCSI Initiator Name. + If initiatorName is specified with iscsiInterface simultaneously, new iSCSI interface + : will be created for the connection. + type: string + iqn: + description: iqn is the target iSCSI Qualified Name. + type: string + iscsiInterface: + description: |- + iscsiInterface is the interface Name that uses an iSCSI transport. + Defaults to 'default' (tcp). + type: string + lun: + description: lun represents iSCSI Target Lun number. + format: int32 + type: integer + portals: + description: |- + portals is the iSCSI Target Portal List. The portal is either an IP or ip_addr:port if the port + is other than default (typically TCP ports 860 and 3260). + items: + type: string + type: array + readOnly: + description: |- + readOnly here will force the ReadOnly setting in VolumeMounts. + Defaults to false. + type: boolean + secretRef: + description: secretRef is the CHAP Secret for iSCSI + target and initiator authentication + 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 + targetPortal: + description: |- + targetPortal is iSCSI Target Portal. The Portal is either an IP or ip_addr:port if the port + is other than default (typically TCP ports 860 and 3260). + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + description: |- + name of the volume. + Must be a DNS_LABEL and unique within the pod. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + nfs: + description: |- + nfs represents an NFS mount on the host that shares a pod's lifetime + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + properties: + path: + description: |- + path that is exported by the NFS server. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + type: string + readOnly: + description: |- + readOnly here will force the NFS export to be mounted with read-only permissions. + Defaults to false. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + type: boolean + server: + description: |- + server is the hostname or IP address of the NFS server. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + description: |- + persistentVolumeClaimVolumeSource represents a reference to a + PersistentVolumeClaim in the same namespace. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims + properties: + claimName: + description: |- + claimName is the name of a PersistentVolumeClaim in the same namespace as the pod using this volume. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims + type: string + readOnly: + description: |- + readOnly Will force the ReadOnly setting in VolumeMounts. + Default false. + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + description: photonPersistentDisk represents a PhotonController + persistent disk attached and mounted on kubelets host + machine + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + pdID: + description: pdID is the ID that identifies Photon Controller + persistent disk + type: string + required: + - pdID + type: object + portworxVolume: + description: portworxVolume represents a portworx volume + attached and mounted on kubelets host machine + properties: + fsType: + description: |- + fSType represents the filesystem type to mount + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs". Implicitly inferred to be "ext4" if unspecified. + type: string + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + volumeID: + description: volumeID uniquely identifies a Portworx + volume + type: string + required: + - volumeID + type: object + projected: + description: projected items for all in one resources secrets, + configmaps, and downward API + properties: + defaultMode: + description: |- + defaultMode are the mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + sources: + description: sources is the list of volume projections + items: + description: Projection that may be projected along + with other supported volume types + properties: + clusterTrustBundle: + description: |- + ClusterTrustBundle allows a pod to access the `.spec.trustBundle` field + of ClusterTrustBundle objects in an auto-updating file. + + + Alpha, gated by the ClusterTrustBundleProjection feature gate. + + + ClusterTrustBundle objects can either be selected by name, or by the + combination of signer name and a label selector. + + + Kubelet performs aggressive normalization of the PEM contents written + into the pod filesystem. Esoteric PEM features such as inter-block + comments and block headers are stripped. Certificates are deduplicated. + The ordering of certificates within the file is arbitrary, and Kubelet + may change the order over time. + properties: + labelSelector: + description: |- + Select all ClusterTrustBundles that match this label selector. Only has + effect if signerName is set. Mutually-exclusive with name. If unset, + interpreted as "match nothing". If set but empty, interpreted as "match + everything". + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + name: + description: |- + Select a single ClusterTrustBundle by object name. Mutually-exclusive + with signerName and labelSelector. + type: string + optional: + description: |- + If true, don't block pod startup if the referenced ClusterTrustBundle(s) + aren't available. If using name, then the named ClusterTrustBundle is + allowed not to exist. If using signerName, then the combination of + signerName and labelSelector is allowed to match zero + ClusterTrustBundles. + type: boolean + path: + description: Relative path from the volume + root to write the bundle. + type: string + signerName: + description: |- + Select all ClusterTrustBundles that match this signer name. + Mutually-exclusive with name. The contents of all selected + ClusterTrustBundles will be unified and deduplicated. + type: string + required: + - path + type: object + configMap: + description: configMap information about the configMap + data to project + properties: + items: + description: |- + items if unspecified, each key-value pair in the Data field of the referenced + ConfigMap will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the ConfigMap, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path + within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + 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 + optional: + description: optional specify whether the + ConfigMap or its keys must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + downwardAPI: + description: downwardAPI information about the + downwardAPI data to project + properties: + items: + description: Items is a list of DownwardAPIVolume + file + items: + description: DownwardAPIVolumeFile represents + information to create the file containing + the pod field + properties: + fieldRef: + description: 'Required: Selects a field + of the pod: only annotations, labels, + name and namespace are supported.' + properties: + apiVersion: + description: Version of the schema + the FieldPath is written in terms + of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to + select in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + description: |- + Optional: mode bits used to set permissions on this file, must be an octal value + between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: 'Required: Path is the + relative path name of the file to + be created. Must not be absolute or + contain the ''..'' path. Must be utf-8 + encoded. The first item of the relative + path must not start with ''..''' + type: string + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported. + properties: + containerName: + description: 'Container name: required + for volumes, optional for env + vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output + format of the exposed resources, + defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource + to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + type: object + secret: + description: secret information about the secret + data to project + properties: + items: + description: |- + items if unspecified, each key-value pair in the Data field of the referenced + Secret will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the Secret, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path + within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + 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 + optional: + description: optional field specify whether + the Secret or its key must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + serviceAccountToken: + description: serviceAccountToken is information + about the serviceAccountToken data to project + properties: + audience: + description: |- + audience is the intended audience of the token. A recipient of a token + must identify itself with an identifier specified in the audience of the + token, and otherwise should reject the token. The audience defaults to the + identifier of the apiserver. + type: string + expirationSeconds: + description: |- + expirationSeconds is the requested duration of validity of the service + account token. As the token approaches expiration, the kubelet volume + plugin will proactively rotate the service account token. The kubelet will + start trying to rotate the token if the token is older than 80 percent of + its time to live or if the token is older than 24 hours.Defaults to 1 hour + and must be at least 10 minutes. + format: int64 + type: integer + path: + description: |- + path is the path relative to the mount point of the file to project the + token into. + type: string + required: + - path + type: object + type: object + type: array + type: object + quobyte: + description: quobyte represents a Quobyte mount on the host + that shares a pod's lifetime + properties: + group: + description: |- + group to map volume access to + Default is no group + type: string + readOnly: + description: |- + readOnly here will force the Quobyte volume to be mounted with read-only permissions. + Defaults to false. + type: boolean + registry: + description: |- + registry represents a single or multiple Quobyte Registry services + specified as a string as host:port pair (multiple entries are separated with commas) + which acts as the central registry for volumes + type: string + tenant: + description: |- + tenant owning the given Quobyte volume in the Backend + Used with dynamically provisioned Quobyte volumes, value is set by the plugin + type: string + user: + description: |- + user to map volume access to + Defaults to serivceaccount user + type: string + volume: + description: volume is a string that references an already + created Quobyte volume by name. + type: string + required: + - registry + - volume + type: object + rbd: + description: |- + rbd represents a Rados Block Device mount on the host that shares a pod's lifetime. + More info: https://examples.k8s.io/volumes/rbd/README.md + properties: + fsType: + description: |- + fsType is the filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#rbd + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + image: + description: |- + image is the rados image name. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + keyring: + description: |- + keyring is the path to key ring for RBDUser. + Default is /etc/ceph/keyring. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + monitors: + description: |- + monitors is a collection of Ceph monitors. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + items: + type: string + type: array + pool: + description: |- + pool is the rados pool name. + Default is rbd. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + readOnly: + description: |- + readOnly here will force the ReadOnly setting in VolumeMounts. + Defaults to false. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: boolean + secretRef: + description: |- + secretRef is name of the authentication secret for RBDUser. If provided + overrides keyring. + Default is nil. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + 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 + user: + description: |- + user is the rados user name. + Default is admin. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + required: + - image + - monitors + type: object + scaleIO: + description: scaleIO represents a ScaleIO persistent volume + attached and mounted on Kubernetes nodes. + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". + Default is "xfs". + type: string + gateway: + description: gateway is the host address of the ScaleIO + API Gateway. + type: string + protectionDomain: + description: protectionDomain is the name of the ScaleIO + Protection Domain for the configured storage. + type: string + readOnly: + description: |- + readOnly Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: |- + secretRef references to the secret for ScaleIO user and other + sensitive information. If this is not provided, Login operation will fail. + 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 + sslEnabled: + description: sslEnabled Flag enable/disable SSL communication + with Gateway, default false + type: boolean + storageMode: + description: |- + storageMode indicates whether the storage for a volume should be ThickProvisioned or ThinProvisioned. + Default is ThinProvisioned. + type: string + storagePool: + description: storagePool is the ScaleIO Storage Pool + associated with the protection domain. + type: string + system: + description: system is the name of the storage system + as configured in ScaleIO. + type: string + volumeName: + description: |- + volumeName is the name of a volume already created in the ScaleIO system + that is associated with this volume source. + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + description: |- + secret represents a secret that should populate this volume. + More info: https://kubernetes.io/docs/concepts/storage/volumes#secret + properties: + defaultMode: + description: |- + defaultMode is Optional: mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values + for mode bits. Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + items: + description: |- + items If unspecified, each key-value pair in the Data field of the referenced + Secret will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the Secret, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within a + volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + optional: + description: optional field specify whether the Secret + or its keys must be defined + type: boolean + secretName: + description: |- + secretName is the name of the secret in the pod's namespace to use. + More info: https://kubernetes.io/docs/concepts/storage/volumes#secret + type: string + type: object + storageos: + description: storageOS represents a StorageOS volume attached + and mounted on Kubernetes nodes. + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: |- + secretRef specifies the secret to use for obtaining the StorageOS API + credentials. If not specified, default values will be attempted. + 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 + volumeName: + description: |- + volumeName is the human-readable name of the StorageOS volume. Volume + names are only unique within a namespace. + type: string + volumeNamespace: + description: |- + volumeNamespace specifies the scope of the volume within StorageOS. If no + namespace is specified then the Pod's namespace will be used. This allows the + Kubernetes name scoping to be mirrored within StorageOS for tighter integration. + Set VolumeName to any name to override the default behaviour. + Set to "default" if you are not using namespaces within StorageOS. + Namespaces that do not pre-exist within StorageOS will be created. + type: string + type: object + vsphereVolume: + description: vsphereVolume represents a vSphere volume attached + and mounted on kubelets host machine + properties: + fsType: + description: |- + fsType is filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + storagePolicyID: + description: storagePolicyID is the storage Policy Based + Management (SPBM) profile ID associated with the StoragePolicyName. + type: string + storagePolicyName: + description: storagePolicyName is the storage Policy + Based Management (SPBM) profile name. + type: string + volumePath: + description: volumePath is the path that identifies + vSphere volume vmdk + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + required: + - containers + type: object + x-kubernetes-preserve-unknown-fields: true + scripts: + description: |- + Specifies groups of scripts, each provided via a ConfigMap, to be mounted as volumes in the container. + These scripts can be executed during container startup or via specific actions. + + + Each script group is encapsulated in a ComponentTemplateSpec that includes: + + + - The ConfigMap containing the scripts. + - The mount point where the scripts will be mounted inside the container. + + + This field is immutable. + items: + properties: + defaultMode: + description: |- + The operator attempts to set default file permissions for scripts (0555) and configurations (0444). + However, certain database engines may require different file permissions. + You can specify the desired file permissions here. + + + Must be specified as an octal value between 0000 and 0777 (inclusive), + or as a decimal value between 0 and 511 (inclusive). + YAML supports both octal and decimal values for file permissions. + + + Please note that this setting only affects the permissions of the files themselves. + Directories within the specified path are not impacted by this setting. + It's important to be aware that this setting might conflict with other options + that influence the file mode, such as fsGroup. + In such cases, the resulting file mode may have additional bits set. + Refers to documents of k8s.ConfigMapVolumeSource.defaultMode for more information. + format: int32 + type: integer + name: + description: Specifies the name of the configuration template. + maxLength: 63 + pattern: ^[a-z0-9]([a-z0-9\.\-]*[a-z0-9])?$ + type: string + namespace: + default: default + description: |- + Specifies the namespace of the referenced configuration template ConfigMap object. + An empty namespace is equivalent to the "default" namespace. + maxLength: 63 + pattern: ^[a-z0-9]([a-z0-9\-]*[a-z0-9])?$ + type: string + templateRef: + description: Specifies the name of the referenced configuration + template ConfigMap object. + maxLength: 63 + pattern: ^[a-z0-9]([a-z0-9\.\-]*[a-z0-9])?$ + type: string + volumeName: + description: |- + Refers to the volume name of PodTemplate. The configuration file produced through the configuration + template will be mounted to the corresponding volume. Must be a DNS_LABEL name. + The volume name must be defined in podSpec.containers[*].volumeMounts. + maxLength: 63 + pattern: ^[a-z]([a-z0-9\-]*[a-z0-9])?$ + type: string + required: + - name + - volumeName + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + serviceKind: + description: |- + Defines the type of well-known service protocol that the Component provides. + It specifies the standard or widely recognized protocol used by the Component to offer its Services. + + + The `serviceKind` field allows users to quickly identify the type of Service provided by the Component + based on common protocols or service types. This information helps in understanding the compatibility, + interoperability, and usage of the Component within a system. + + + Some examples of well-known service protocols include: + + + - "MySQL": Indicates that the Component provides a MySQL database service. + - "PostgreSQL": Indicates that the Component offers a PostgreSQL database service. + - "Redis": Signifies that the Component functions as a Redis key-value store. + - "ETCD": Denotes that the Component serves as an ETCD distributed key-value store. + + + The `serviceKind` value is case-insensitive, allowing for flexibility in specifying the protocol name. + + + When specifying the `serviceKind`, consider the following guidelines: + + + - Use well-established and widely recognized protocol names or service types. + - Ensure that the `serviceKind` accurately represents the primary service type offered by the Component. + - If the Component provides multiple services, choose the most prominent or commonly used protocol. + - Limit the `serviceKind` to a maximum of 32 characters for conciseness and readability. + + + Note: The `serviceKind` field is optional and can be left empty if the Component does not fit into a well-known + service category or if the protocol is not widely recognized. It is primarily used to convey information about + the Component's service type to users and facilitate discovery and integration. + + + The `serviceKind` field is immutable and cannot be updated. + maxLength: 32 + type: string + serviceRefDeclarations: + description: |- + Lists external service dependencies of the Component, including services from other Clusters or outside the K8s environment. + + + This field is immutable. + items: + description: |- + ServiceRefDeclaration represents a reference to a service that can be either provided by a KubeBlocks Cluster + or an external service. + It acts as a placeholder for the actual service reference, which is determined later when a Cluster is created. + + + The purpose of ServiceRefDeclaration is to declare a service dependency without specifying the concrete details + of the service. + It allows for flexibility and abstraction in defining service references within a Component. + By using ServiceRefDeclaration, you can define service dependencies in a declarative manner, enabling loose coupling + and easier management of service references across different components and clusters. + + + Upon Cluster creation, the ServiceRefDeclaration is bound to an actual service through the ServiceRef field, + effectively resolving and connecting to the specified service. + properties: + name: + description: Specifies the name of the ServiceRefDeclaration. + type: string + optional: + description: |- + Specifies whether the service reference can be optional. + + + For an optional service-ref, the component can still be created even if the service-ref is not provided. + type: boolean + serviceRefDeclarationSpecs: + description: |- + Defines a list of constraints and requirements for services that can be bound to this ServiceRefDeclaration + upon Cluster creation. + Each ServiceRefDeclarationSpec defines a ServiceKind and ServiceVersion, + outlining the acceptable service types and versions that are compatible. + + + This flexibility allows a ServiceRefDeclaration to be fulfilled by any one of the provided specs. + For example, if it requires an OLTP database, specs for both MySQL and PostgreSQL are listed, + either MySQL or PostgreSQL services can be used when binding. + items: + properties: + serviceKind: + description: |- + Specifies the type or nature of the service. This should be a well-known application cluster type, such as + {mysql, redis, mongodb}. + The field is case-insensitive and supports abbreviations for some well-known databases. + For instance, both `zk` and `zookeeper` are considered as a ZooKeeper cluster, while `pg`, `postgres`, `postgresql` + are all recognized as a PostgreSQL cluster. + type: string + serviceVersion: + description: |- + Defines the service version of the service reference. This is a regular expression that matches a version number pattern. + For instance, `^8.0.8$`, `8.0.\d{1,2}$`, `^[v\-]*?(\d{1,2}\.){0,3}\d{1,2}$` are all valid patterns. + type: string + required: + - serviceKind + - serviceVersion + type: object + type: array + required: + - name + - serviceRefDeclarationSpecs + type: object + type: array + serviceVersion: + description: |- + Specifies the version of the Service provided by the Component. + It follows the syntax and semantics of the "Semantic Versioning" specification (http://semver.org/). + + + The Semantic Versioning specification defines a version number format of X.Y.Z (MAJOR.MINOR.PATCH), where: + + + - X represents the major version and indicates incompatible API changes. + - Y represents the minor version and indicates added functionality in a backward-compatible manner. + - Z represents the patch version and indicates backward-compatible bug fixes. + + + Additional labels for pre-release and build metadata are available as extensions to the X.Y.Z format: + + + - Use pre-release labels (e.g., -alpha, -beta) for versions that are not yet stable or ready for production use. + - Use build metadata (e.g., +build.1) for additional version information if needed. + + + Examples of valid ServiceVersion values: + + + - "1.0.0" + - "2.3.1" + - "3.0.0-alpha.1" + - "4.5.2+build.1" + + + The `serviceVersion` field is immutable and cannot be updated. + maxLength: 32 + type: string + services: + description: |- + Defines additional Services to expose the Component's endpoints. + + + A default headless Service, named `{cluster.name}-{component.name}-headless`, is automatically created + for internal Cluster communication. + + + This field enables customization of additional Services to expose the Component's endpoints to + other Components within the same or different Clusters, and to external applications. + Each Service entry in this list can include properties such as ports, type, and selectors. + + + - For intra-Cluster access, Components can reference Services using variables declared in + `componentDefinition.spec.vars[*].valueFrom.serviceVarRef`. + - For inter-Cluster access, reference Services use variables declared in + `componentDefinition.spec.vars[*].valueFrom.serviceRefVarRef`, + and bind Services at Cluster creation time with `clusterComponentSpec.ServiceRef[*].clusterServiceSelector`. + + + This field is immutable. + items: + description: |- + ComponentService defines a service that would be exposed as an inter-component service within a Cluster. + A Service defined in the ComponentService is expected to be accessed by other Components within the same Cluster. + + + When a Component needs to use a ComponentService provided by another Component within the same Cluster, + it can declare a variable in the `componentDefinition.spec.vars` section and bind it to the specific exposed address + of the ComponentService using the `serviceVarRef` field. + properties: + annotations: + additionalProperties: + type: string + description: |- + If ServiceType is LoadBalancer, cloud provider related parameters can be put here + More info: https://kubernetes.io/docs/concepts/services-networking/service/#loadbalancer. + type: object + disableAutoProvision: + description: |- + Indicates whether the automatic provisioning of the service should be disabled. + + + If set to true, the service will not be automatically created at the component provisioning. + Instead, you can enable the creation of this service by specifying it explicitly in the cluster API. + type: boolean + name: + description: |- + Name defines the name of the service. + otherwise, it indicates the name of the service. + Others can refer to this service by its name. (e.g., connection credential) + Cannot be updated. + maxLength: 25 + type: string + podService: + default: false + description: |- + Indicates whether to create a corresponding Service for each Pod of the selected Component. + When set to true, a set of Services will be automatically generated for each Pod, + and the `roleSelector` field will be ignored. + + + The names of the generated Services will follow the same suffix naming pattern: `$(serviceName)-$(podOrdinal)`. + The total number of generated Services will be equal to the number of replicas specified for the Component. + + + Example usage: + + + ```yaml + name: my-service + serviceName: my-service + podService: true + disableAutoProvision: true + spec: + type: NodePort + ports: + - name: http + port: 80 + targetPort: 8080 + ``` + + + In this example, if the Component has 3 replicas, three Services will be generated: + - my-service-0: Points to the first Pod (podOrdinal: 0) + - my-service-1: Points to the second Pod (podOrdinal: 1) + - my-service-2: Points to the third Pod (podOrdinal: 2) + + + Each generated Service will have the specified spec configuration and will target its respective Pod. + + + This feature is useful when you need to expose each Pod of a Component individually, allowing external access + to specific instances of the Component. + type: boolean + roleSelector: + description: "Extends the above `serviceSpec.selector` by allowing + you to specify defined role as selector for the service.\nWhen + `roleSelector` is set, it adds a label selector \"kubeblocks.io/role: + {roleSelector}\"\nto the `serviceSpec.selector`.\nExample + usage:\n\n\n\t roleSelector: \"leader\"\n\n\nIn this example, + setting `roleSelector` to \"leader\" will add a label selector\n\"kubeblocks.io/role: + leader\" to the `serviceSpec.selector`.\nThis means that the + service will select and route traffic to Pods with the label\n\"kubeblocks.io/role\" + set to \"leader\".\n\n\nNote that if `podService` sets to + true, RoleSelector will be ignored.\nThe `podService` flag + takes precedence over `roleSelector` and generates a service + for each Pod." + type: string + serviceName: + description: |- + ServiceName defines the name of the underlying service object. + If not specified, the default service name with different patterns will be used: + + + - CLUSTER_NAME: for cluster-level services + - CLUSTER_NAME-COMPONENT_NAME: for component-level services + + + Only one default service name is allowed. + Cannot be updated. + maxLength: 25 + pattern: ^[a-z]([a-z0-9\-]*[a-z0-9])?$ + type: string + spec: + description: |- + Spec defines the behavior of a service. + https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status + properties: + allocateLoadBalancerNodePorts: + description: |- + allocateLoadBalancerNodePorts defines if NodePorts will be automatically + allocated for services with type LoadBalancer. Default is "true". It + may be set to "false" if the cluster load-balancer does not rely on + NodePorts. If the caller requests specific NodePorts (by specifying a + value), those requests will be respected, regardless of this field. + This field may only be set for services with type LoadBalancer and will + be cleared if the type is changed to any other type. + type: boolean + clusterIP: + description: |- + clusterIP is the IP address of the service and is usually assigned + randomly. If an address is specified manually, is in-range (as per + system configuration), and is not in use, it will be allocated to the + service; otherwise creation of the service will fail. This field may not + be changed through updates unless the type field is also being changed + to ExternalName (which requires this field to be blank) or the type + field is being changed from ExternalName (in which case this field may + optionally be specified, as describe above). Valid values are "None", + empty string (""), or a valid IP address. Setting this to "None" makes a + "headless service" (no virtual IP), which is useful when direct endpoint + connections are preferred and proxying is not required. Only applies to + types ClusterIP, NodePort, and LoadBalancer. If this field is specified + when creating a Service of type ExternalName, creation will fail. This + field will be wiped when updating a Service to type ExternalName. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + type: string + clusterIPs: + description: |- + ClusterIPs is a list of IP addresses assigned to this service, and are + usually assigned randomly. If an address is specified manually, is + in-range (as per system configuration), and is not in use, it will be + allocated to the service; otherwise creation of the service will fail. + This field may not be changed through updates unless the type field is + also being changed to ExternalName (which requires this field to be + empty) or the type field is being changed from ExternalName (in which + case this field may optionally be specified, as describe above). Valid + values are "None", empty string (""), or a valid IP address. Setting + this to "None" makes a "headless service" (no virtual IP), which is + useful when direct endpoint connections are preferred and proxying is + not required. Only applies to types ClusterIP, NodePort, and + LoadBalancer. If this field is specified when creating a Service of type + ExternalName, creation will fail. This field will be wiped when updating + a Service to type ExternalName. If this field is not specified, it will + be initialized from the clusterIP field. If this field is specified, + clients must ensure that clusterIPs[0] and clusterIP have the same + value. + + + This field may hold a maximum of two entries (dual-stack IPs, in either order). + These IPs must correspond to the values of the ipFamilies field. Both + clusterIPs and ipFamilies are governed by the ipFamilyPolicy field. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalIPs: + description: |- + externalIPs is a list of IP addresses for which nodes in the cluster + will also accept traffic for this service. These IPs are not managed by + Kubernetes. The user is responsible for ensuring that traffic arrives + at a node with this IP. A common example is external load-balancers + that are not part of the Kubernetes system. + items: + type: string + type: array + externalName: + description: |- + externalName is the external reference that discovery mechanisms will + return as an alias for this service (e.g. a DNS CNAME record). No + proxying will be involved. Must be a lowercase RFC-1123 hostname + (https://tools.ietf.org/html/rfc1123) and requires `type` to be "ExternalName". + type: string + externalTrafficPolicy: + description: |- + externalTrafficPolicy describes how nodes distribute service traffic they + receive on one of the Service's "externally-facing" addresses (NodePorts, + ExternalIPs, and LoadBalancer IPs). If set to "Local", the proxy will configure + the service in a way that assumes that external load balancers will take care + of balancing the service traffic between nodes, and so each node will deliver + traffic only to the node-local endpoints of the service, without masquerading + the client source IP. (Traffic mistakenly sent to a node with no endpoints will + be dropped.) The default value, "Cluster", uses the standard behavior of + routing to all endpoints evenly (possibly modified by topology and other + features). Note that traffic sent to an External IP or LoadBalancer IP from + within the cluster will always get "Cluster" semantics, but clients sending to + a NodePort from within the cluster may need to take traffic policy into account + when picking a node. + type: string + healthCheckNodePort: + description: |- + healthCheckNodePort specifies the healthcheck nodePort for the service. + This only applies when type is set to LoadBalancer and + externalTrafficPolicy is set to Local. If a value is specified, is + in-range, and is not in use, it will be used. If not specified, a value + will be automatically allocated. External systems (e.g. load-balancers) + can use this port to determine if a given node holds endpoints for this + service or not. If this field is specified when creating a Service + which does not need it, creation will fail. This field will be wiped + when updating a Service to no longer need it (e.g. changing type). + This field cannot be updated once set. + format: int32 + type: integer + internalTrafficPolicy: + description: |- + InternalTrafficPolicy describes how nodes distribute service traffic they + receive on the ClusterIP. If set to "Local", the proxy will assume that pods + only want to talk to endpoints of the service on the same node as the pod, + dropping the traffic if there are no local endpoints. The default value, + "Cluster", uses the standard behavior of routing to all endpoints evenly + (possibly modified by topology and other features). + type: string + ipFamilies: + description: |- + IPFamilies is a list of IP families (e.g. IPv4, IPv6) assigned to this + service. This field is usually assigned automatically based on cluster + configuration and the ipFamilyPolicy field. If this field is specified + manually, the requested family is available in the cluster, + and ipFamilyPolicy allows it, it will be used; otherwise creation of + the service will fail. This field is conditionally mutable: it allows + for adding or removing a secondary IP family, but it does not allow + changing the primary IP family of the Service. Valid values are "IPv4" + and "IPv6". This field only applies to Services of types ClusterIP, + NodePort, and LoadBalancer, and does apply to "headless" services. + This field will be wiped when updating a Service to type ExternalName. + + + This field may hold a maximum of two entries (dual-stack families, in + either order). These families must correspond to the values of the + clusterIPs field, if specified. Both clusterIPs and ipFamilies are + governed by the ipFamilyPolicy field. + items: + description: |- + IPFamily represents the IP Family (IPv4 or IPv6). This type is used + to express the family of an IP expressed by a type (e.g. service.spec.ipFamilies). + type: string + type: array + x-kubernetes-list-type: atomic + ipFamilyPolicy: + description: |- + IPFamilyPolicy represents the dual-stack-ness requested or required by + this Service. If there is no value provided, then this field will be set + to SingleStack. Services can be "SingleStack" (a single IP family), + "PreferDualStack" (two IP families on dual-stack configured clusters or + a single IP family on single-stack clusters), or "RequireDualStack" + (two IP families on dual-stack configured clusters, otherwise fail). The + ipFamilies and clusterIPs fields depend on the value of this field. This + field will be wiped when updating a service to type ExternalName. + type: string + loadBalancerClass: + description: |- + loadBalancerClass is the class of the load balancer implementation this Service belongs to. + If specified, the value of this field must be a label-style identifier, with an optional prefix, + e.g. "internal-vip" or "example.com/internal-vip". Unprefixed names are reserved for end-users. + This field can only be set when the Service type is 'LoadBalancer'. If not set, the default load + balancer implementation is used, today this is typically done through the cloud provider integration, + but should apply for any default implementation. If set, it is assumed that a load balancer + implementation is watching for Services with a matching class. Any default load balancer + implementation (e.g. cloud providers) should ignore Services that set this field. + This field can only be set when creating or updating a Service to type 'LoadBalancer'. + Once set, it can not be changed. This field will be wiped when a service is updated to a non 'LoadBalancer' type. + type: string + loadBalancerIP: + description: |- + Only applies to Service Type: LoadBalancer. + This feature depends on whether the underlying cloud-provider supports specifying + the loadBalancerIP when a load balancer is created. + This field will be ignored if the cloud-provider does not support the feature. + Deprecated: This field was under-specified and its meaning varies across implementations. + Using it is non-portable and it may not support dual-stack. + Users are encouraged to use implementation-specific annotations when available. + type: string + loadBalancerSourceRanges: + description: |- + If specified and supported by the platform, this will restrict traffic through the cloud-provider + load-balancer will be restricted to the specified client IPs. This field will be ignored if the + cloud-provider does not support the feature." + More info: https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/ + items: + type: string + type: array + ports: + description: |- + The list of ports that are exposed by this service. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + items: + description: ServicePort contains information on service's + port. + properties: + appProtocol: + description: |- + The application protocol for this port. + This is used as a hint for implementations to offer richer behavior for protocols that they understand. + This field follows standard Kubernetes label syntax. + Valid values are either: + + + * Un-prefixed protocol names - reserved for IANA standard service names (as per + RFC-6335 and https://www.iana.org/assignments/service-names). + + + * Kubernetes-defined prefixed names: + * 'kubernetes.io/h2c' - HTTP/2 prior knowledge over cleartext as described in https://www.rfc-editor.org/rfc/rfc9113.html#name-starting-http-2-with-prior- + * 'kubernetes.io/ws' - WebSocket over cleartext as described in https://www.rfc-editor.org/rfc/rfc6455 + * 'kubernetes.io/wss' - WebSocket over TLS as described in https://www.rfc-editor.org/rfc/rfc6455 + + + * Other protocols should use implementation-defined prefixed names such as + mycompany.com/my-custom-protocol. + type: string + name: + description: |- + The name of this port within the service. This must be a DNS_LABEL. + All ports within a ServiceSpec must have unique names. When considering + the endpoints for a Service, this must match the 'name' field in the + EndpointPort. + Optional if only one ServicePort is defined on this service. + type: string + nodePort: + description: |- + The port on each node on which this service is exposed when type is + NodePort or LoadBalancer. Usually assigned by the system. If a value is + specified, in-range, and not in use it will be used, otherwise the + operation will fail. If not specified, a port will be allocated if this + Service requires one. If this field is specified when creating a + Service which does not need it, creation will fail. This field will be + wiped when updating a Service to no longer need it (e.g. changing type + from NodePort to ClusterIP). + More info: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport + format: int32 + type: integer + port: + description: The port that will be exposed by this + service. + format: int32 + type: integer + protocol: + default: TCP + description: |- + The IP protocol for this port. Supports "TCP", "UDP", and "SCTP". + Default is TCP. + type: string + targetPort: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the pods targeted by the service. + Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + If this is a string, it will be looked up as a named port in the + target Pod's container ports. If this is not specified, the value + of the 'port' field is used (an identity map). + This field is ignored for services with clusterIP=None, and should be + omitted or set equal to the 'port' field. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#defining-a-service + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-map-keys: + - port + - protocol + x-kubernetes-list-type: map + publishNotReadyAddresses: + description: |- + publishNotReadyAddresses indicates that any agent which deals with endpoints for this + Service should disregard any indications of ready/not-ready. + The primary use case for setting this field is for a StatefulSet's Headless Service to + propagate SRV DNS records for its Pods for the purpose of peer discovery. + The Kubernetes controllers that generate Endpoints and EndpointSlice resources for + Services interpret this to mean that all endpoints are considered "ready" even if the + Pods themselves are not. Agents which consume only Kubernetes generated endpoints + through the Endpoints or EndpointSlice resources can safely assume this behavior. + type: boolean + selector: + additionalProperties: + type: string + description: |- + Route service traffic to pods with label keys and values matching this + selector. If empty or not present, the service is assumed to have an + external process managing its endpoints, which Kubernetes will not + modify. Only applies to types ClusterIP, NodePort, and LoadBalancer. + Ignored if type is ExternalName. + More info: https://kubernetes.io/docs/concepts/services-networking/service/ + type: object + x-kubernetes-map-type: atomic + sessionAffinity: + description: |- + Supports "ClientIP" and "None". Used to maintain session affinity. + Enable client IP based session affinity. + Must be ClientIP or None. + Defaults to None. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + type: string + sessionAffinityConfig: + description: sessionAffinityConfig contains the configurations + of session affinity. + properties: + clientIP: + description: clientIP contains the configurations of + Client IP based session affinity. + properties: + timeoutSeconds: + description: |- + timeoutSeconds specifies the seconds of ClientIP type session sticky time. + The value must be >0 && <=86400(for 1 day) if ServiceAffinity == "ClientIP". + Default value is 10800(for 3 hours). + format: int32 + type: integer + type: object + type: object + type: + description: |- + type determines how the Service is exposed. Defaults to ClusterIP. Valid + options are ExternalName, ClusterIP, NodePort, and LoadBalancer. + "ClusterIP" allocates a cluster-internal IP address for load-balancing + to endpoints. Endpoints are determined by the selector or if that is not + specified, by manual construction of an Endpoints object or + EndpointSlice objects. If clusterIP is "None", no virtual IP is + allocated and the endpoints are published as a set of endpoints rather + than a virtual IP. + "NodePort" builds on ClusterIP and allocates a port on every node which + routes to the same endpoints as the clusterIP. + "LoadBalancer" builds on NodePort and creates an external load-balancer + (if supported in the current cloud) which routes to the same endpoints + as the clusterIP. + "ExternalName" aliases this service to the specified externalName. + Several other fields do not apply to ExternalName services. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types + type: string + type: object + required: + - name + type: object + type: array + systemAccounts: + description: |- + An array of `SystemAccount` objects that define the system accounts needed + for the management operations of the Component. + + + Each `SystemAccount` includes: + + + - Account name. + - The SQL statement template: Used to create the system account. + - Password Source: Either generated based on certain rules or retrieved from a Secret. + + + Use cases for system accounts typically involve tasks like system initialization, backups, monitoring, + health checks, replication, and other system-level operations. + + + System accounts are distinct from user accounts, although both are database accounts. + + + - **System Accounts**: Created during Cluster setup by the KubeBlocks operator, + these accounts have higher privileges for system management and are fully managed + through a declarative API by the operator. + - **User Accounts**: Managed by users or administrator. + User account permissions should follow the principle of least privilege, + granting only the necessary access rights to complete their required tasks. + + + This field is immutable. + items: + properties: + initAccount: + default: false + description: |- + Indicates if this account is a system initialization account (e.g., MySQL root). + + + This field is immutable once set. + type: boolean + name: + description: |- + Specifies the unique identifier for the account. This name is used by other entities to reference the account. + + + This field is immutable once set. + type: string + passwordGenerationPolicy: + description: |- + Specifies the policy for generating the account's password. + + + This field is immutable once set. + properties: + length: + default: 16 + description: The length of the password. + format: int32 + maximum: 32 + minimum: 8 + type: integer + letterCase: + default: MixedCases + description: The case of the letters in the password. + enum: + - LowerCases + - UpperCases + - MixedCases + type: string + numDigits: + default: 4 + description: The number of digits in the password. + format: int32 + maximum: 8 + minimum: 0 + type: integer + numSymbols: + default: 0 + description: The number of symbols in the password. + format: int32 + maximum: 8 + minimum: 0 + type: integer + seed: + description: |- + Seed to generate the account's password. + Cannot be updated. + type: string + type: object + secretRef: + description: |- + Refers to the secret from which data will be copied to create the new account. + + + This field is immutable once set. + properties: + name: + description: The unique identifier of the secret. + type: string + namespace: + description: The namespace where the secret is located. + type: string + required: + - name + - namespace + type: object + statement: + description: |- + Defines the statement used to create the account with the necessary privileges. + + + This field is immutable once set. + type: string + required: + - name + type: object + type: array + updateStrategy: + default: Serial + description: "Specifies the concurrency strategy for updating multiple + instances of the Component.\nAvailable strategies:\n\n\n- `Serial`: + Updates replicas one at a time, ensuring minimal downtime by waiting + for each replica to become ready\n before updating the next.\n- + `Parallel`: Updates all replicas simultaneously, optimizing for + speed but potentially reducing availability\n during the update.\n- + `BestEffortParallel`: Updates replicas concurrently with a limit + on simultaneous updates to ensure a minimum\n number of operational + replicas for maintaining quorum.\n\t For example, in a 5-replica + component, updating a maximum of 2 replicas simultaneously keeps\n\t + at least 3 operational for quorum.\n\n\nThis field is immutable + and defaults to 'Serial'." + enum: + - Serial + - BestEffortParallel + - Parallel + type: string + vars: + description: |- + Defines variables which are determined after Cluster instantiation and reflect + dynamic or runtime attributes of instantiated Clusters. + These variables serve as placeholders for setting environment variables in Pods and Actions, + or for rendering configuration and script templates before actual values are finalized. + + + These variables are placed in front of the environment variables declared in the Pod if used as + environment variables. + + + Variable values can be sourced from: + + + - ConfigMap: Select and extract a value from a specific key within a ConfigMap. + - Secret: Select and extract a value from a specific key within a Secret. + - HostNetwork: Retrieves values (including ports) from host-network resources. + - Service: Retrieves values (including address, port, NodePort) from a selected Service. + Intended to obtain the address of a ComponentService within the same Cluster. + - Credential: Retrieves account name and password from a SystemAccount variable. + - ServiceRef: Retrieves address, port, account name and password from a selected ServiceRefDeclaration. + Designed to obtain the address bound to a ServiceRef, such as a ClusterService or + ComponentService of another cluster or an external service. + - Component: Retrieves values from a selected Component, including replicas and instance name list. + + + This field is immutable. + items: + description: EnvVar represents a variable present in the env of + Pod/Action or the template of config/script. + properties: + expression: + description: |- + A Go template expression that will be applied to the resolved value of the var. + + + The expression will only be evaluated if the var is successfully resolved to a non-credential value. + + + The resolved value can be accessed by its name within the expression, system vars and other user-defined + non-credential vars can be used within the expression in the same way. + Notice that, when accessing vars by its name, you should replace all the "-" in the name with "_", because of + that "-" is not a valid identifier in Go. + + + All expressions are evaluated in the order the vars are defined. If a var depends on any vars that also + have expressions defined, be careful about the evaluation order as it may use intermediate values. + + + The result of evaluation will be used as the final value of the var. If the expression fails to evaluate, + the resolving of var will also be considered failed. + type: string + name: + description: Name of the variable. Must be a C_IDENTIFIER. + type: string + value: + description: |- + Variable references `$(VAR_NAME)` are expanded using the previously defined variables in the current context. + + + If a variable cannot be resolved, the reference in the input string will be unchanged. + Double `$$` are reduced to a single `$`, which allows for escaping the `$(VAR_NAME)` syntax: i.e. + + + - `$$(VAR_NAME)` will produce the string literal `$(VAR_NAME)`. + + + Escaped references will never be expanded, regardless of whether the variable exists or not. + Defaults to "". + type: string + valueFrom: + description: Source for the variable's value. Cannot be used + if value is not empty. + properties: + clusterVarRef: + description: Selects a defined var of a Cluster. + properties: + clusterName: + description: Reference to the name of the Cluster object. + enum: + - Required + - Optional + type: string + clusterUID: + description: Reference to the UID of the Cluster object. + enum: + - Required + - Optional + type: string + namespace: + description: Reference to the namespace of the Cluster + object. + enum: + - Required + - Optional + type: string + type: object + componentVarRef: + description: Selects a defined var of a Component. + properties: + compDef: + description: |- + CompDef specifies the definition used by the component that the referent object resident in. + If not specified, the component itself will be used. + type: string + componentName: + description: Reference to the name of the Component + object. + enum: + - Required + - Optional + type: string + multipleClusterObjectOption: + description: |- + This option defines the behavior when multiple component objects match the specified @CompDef. + If not provided, an error will be raised when handling multiple matches. + properties: + combinedOption: + description: |- + Define the options for handling combined variables. + Valid only when the strategy is set to "combined". + properties: + flattenFormat: + description: 'The flatten format, default is: + $(comp-name-1):value,$(comp-name-2):value.' + properties: + delimiter: + default: ',' + description: Pair delimiter. + type: string + keyValueDelimiter: + default: ':' + description: Key-value delimiter. + type: string + required: + - delimiter + - keyValueDelimiter + type: object + newVarSuffix: + description: |- + If set, the existing variable will be kept, and a new variable will be defined with the specified suffix + in pattern: $(var.name)_$(suffix). + The new variable will be auto-created and placed behind the existing one. + If not set, the existing variable will be reused with the value format defined below. + type: string + valueFormat: + default: Flatten + description: The format of the value that the + operator will use to compose values from multiple + components. + type: string + type: object + strategy: + description: Define the strategy for handling multiple + cluster objects. + enum: + - individual + - combined + type: string + required: + - strategy + type: object + name: + description: Name of the referent object. + type: string + optional: + description: Specify whether the object must be defined. + type: boolean + podFQDNs: + description: |- + Reference to the pod FQDN list of the component. + The value will be presented in the following format: FQDN1,FQDN2,... + enum: + - Required + - Optional + type: string + podFQDNsForRole: + description: |- + Reference to the pod FQDN list of the component that have a specific role. + The value will be presented in the following format: FQDN1,FQDN2,... + properties: + option: + description: VarOption defines whether a variable + is required or optional. + enum: + - Required + - Optional + type: string + role: + type: string + type: object + podNames: + description: |- + Reference to the pod name list of the component. + and the value will be presented in the following format: name1,name2,... + enum: + - Required + - Optional + type: string + podNamesForRole: + description: |- + Reference to the pod name list of the component that have a specific role. + The value will be presented in the following format: name1,name2,... + properties: + option: + description: VarOption defines whether a variable + is required or optional. + enum: + - Required + - Optional + type: string + role: + type: string + type: object + replicas: + description: Reference to the replicas of the component. + enum: + - Required + - Optional + type: string + shortName: + description: Reference to the short name of the Component + object. + enum: + - Required + - Optional + type: string + type: object + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + credentialVarRef: + description: Selects a defined var of a Credential (SystemAccount). + properties: + compDef: + description: |- + CompDef specifies the definition used by the component that the referent object resident in. + If not specified, the component itself will be used. + type: string + multipleClusterObjectOption: + description: |- + This option defines the behavior when multiple component objects match the specified @CompDef. + If not provided, an error will be raised when handling multiple matches. + properties: + combinedOption: + description: |- + Define the options for handling combined variables. + Valid only when the strategy is set to "combined". + properties: + flattenFormat: + description: 'The flatten format, default is: + $(comp-name-1):value,$(comp-name-2):value.' + properties: + delimiter: + default: ',' + description: Pair delimiter. + type: string + keyValueDelimiter: + default: ':' + description: Key-value delimiter. + type: string + required: + - delimiter + - keyValueDelimiter + type: object + newVarSuffix: + description: |- + If set, the existing variable will be kept, and a new variable will be defined with the specified suffix + in pattern: $(var.name)_$(suffix). + The new variable will be auto-created and placed behind the existing one. + If not set, the existing variable will be reused with the value format defined below. + type: string + valueFormat: + default: Flatten + description: The format of the value that the + operator will use to compose values from multiple + components. + type: string + type: object + strategy: + description: Define the strategy for handling multiple + cluster objects. + enum: + - individual + - combined + type: string + required: + - strategy + type: object + name: + description: Name of the referent object. + type: string + optional: + description: Specify whether the object must be defined. + type: boolean + password: + description: VarOption defines whether a variable is + required or optional. + enum: + - Required + - Optional + type: string + username: + description: VarOption defines whether a variable is + required or optional. + enum: + - Required + - Optional + type: string + type: object + hostNetworkVarRef: + description: Selects a defined var of host-network resources. + properties: + compDef: + description: |- + CompDef specifies the definition used by the component that the referent object resident in. + If not specified, the component itself will be used. + type: string + container: + description: ContainerVars defines the vars that can + be referenced from a Container. + properties: + name: + description: The name of the container. + type: string + port: + description: Container port to reference. + properties: + name: + type: string + option: + description: VarOption defines whether a variable + is required or optional. + enum: + - Required + - Optional + type: string + type: object + required: + - name + type: object + multipleClusterObjectOption: + description: |- + This option defines the behavior when multiple component objects match the specified @CompDef. + If not provided, an error will be raised when handling multiple matches. + properties: + combinedOption: + description: |- + Define the options for handling combined variables. + Valid only when the strategy is set to "combined". + properties: + flattenFormat: + description: 'The flatten format, default is: + $(comp-name-1):value,$(comp-name-2):value.' + properties: + delimiter: + default: ',' + description: Pair delimiter. + type: string + keyValueDelimiter: + default: ':' + description: Key-value delimiter. + type: string + required: + - delimiter + - keyValueDelimiter + type: object + newVarSuffix: + description: |- + If set, the existing variable will be kept, and a new variable will be defined with the specified suffix + in pattern: $(var.name)_$(suffix). + The new variable will be auto-created and placed behind the existing one. + If not set, the existing variable will be reused with the value format defined below. + type: string + valueFormat: + default: Flatten + description: The format of the value that the + operator will use to compose values from multiple + components. + type: string + type: object + strategy: + description: Define the strategy for handling multiple + cluster objects. + enum: + - individual + - combined + type: string + required: + - strategy + type: object + name: + description: Name of the referent object. + type: string + optional: + description: Specify whether the object must be defined. + type: boolean + type: object + secretKeyRef: + description: Selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must + be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + serviceRefVarRef: + description: Selects a defined var of a ServiceRef. + properties: + compDef: + description: |- + CompDef specifies the definition used by the component that the referent object resident in. + If not specified, the component itself will be used. + type: string + endpoint: + description: VarOption defines whether a variable is + required or optional. + enum: + - Required + - Optional + type: string + host: + description: VarOption defines whether a variable is + required or optional. + enum: + - Required + - Optional + type: string + multipleClusterObjectOption: + description: |- + This option defines the behavior when multiple component objects match the specified @CompDef. + If not provided, an error will be raised when handling multiple matches. + properties: + combinedOption: + description: |- + Define the options for handling combined variables. + Valid only when the strategy is set to "combined". + properties: + flattenFormat: + description: 'The flatten format, default is: + $(comp-name-1):value,$(comp-name-2):value.' + properties: + delimiter: + default: ',' + description: Pair delimiter. + type: string + keyValueDelimiter: + default: ':' + description: Key-value delimiter. + type: string + required: + - delimiter + - keyValueDelimiter + type: object + newVarSuffix: + description: |- + If set, the existing variable will be kept, and a new variable will be defined with the specified suffix + in pattern: $(var.name)_$(suffix). + The new variable will be auto-created and placed behind the existing one. + If not set, the existing variable will be reused with the value format defined below. + type: string + valueFormat: + default: Flatten + description: The format of the value that the + operator will use to compose values from multiple + components. + type: string + type: object + strategy: + description: Define the strategy for handling multiple + cluster objects. + enum: + - individual + - combined + type: string + required: + - strategy + type: object + name: + description: Name of the referent object. + type: string + optional: + description: Specify whether the object must be defined. + type: boolean + password: + description: VarOption defines whether a variable is + required or optional. + enum: + - Required + - Optional + type: string + port: + description: VarOption defines whether a variable is + required or optional. + enum: + - Required + - Optional + type: string + username: + description: VarOption defines whether a variable is + required or optional. + enum: + - Required + - Optional + type: string + type: object + serviceVarRef: + description: Selects a defined var of a Service. + properties: + compDef: + description: |- + CompDef specifies the definition used by the component that the referent object resident in. + If not specified, the component itself will be used. + type: string + host: + description: VarOption defines whether a variable is + required or optional. + enum: + - Required + - Optional + type: string + loadBalancer: + description: |- + LoadBalancer represents the LoadBalancer ingress point of the service. + + + If multiple ingress points are available, the first one will be used automatically, choosing between IP and Hostname. + enum: + - Required + - Optional + type: string + multipleClusterObjectOption: + description: |- + This option defines the behavior when multiple component objects match the specified @CompDef. + If not provided, an error will be raised when handling multiple matches. + properties: + combinedOption: + description: |- + Define the options for handling combined variables. + Valid only when the strategy is set to "combined". + properties: + flattenFormat: + description: 'The flatten format, default is: + $(comp-name-1):value,$(comp-name-2):value.' + properties: + delimiter: + default: ',' + description: Pair delimiter. + type: string + keyValueDelimiter: + default: ':' + description: Key-value delimiter. + type: string + required: + - delimiter + - keyValueDelimiter + type: object + newVarSuffix: + description: |- + If set, the existing variable will be kept, and a new variable will be defined with the specified suffix + in pattern: $(var.name)_$(suffix). + The new variable will be auto-created and placed behind the existing one. + If not set, the existing variable will be reused with the value format defined below. + type: string + valueFormat: + default: Flatten + description: The format of the value that the + operator will use to compose values from multiple + components. + type: string + type: object + strategy: + description: Define the strategy for handling multiple + cluster objects. + enum: + - individual + - combined + type: string + required: + - strategy + type: object + name: + description: Name of the referent object. + type: string + optional: + description: Specify whether the object must be defined. + type: boolean + port: + description: |- + Port references a port or node-port defined in the service. + + + If the referenced service is a pod-service, there will be multiple service objects matched, + and the value will be presented in the following format: service1.name:port1,service2.name:port2... + properties: + name: + type: string + option: + description: VarOption defines whether a variable + is required or optional. + enum: + - Required + - Optional + type: string + type: object + serviceType: + description: ServiceType references the type of the + service. + enum: + - Required + - Optional + type: string + type: object + type: object + required: + - name + type: object + type: array + volumes: + description: |- + Defines the volumes used by the Component and some static attributes of the volumes. + After defining the volumes here, user can reference them in the + `cluster.spec.componentSpecs[*].volumeClaimTemplates` field to configure dynamic properties such as + volume capacity and storage class. + + + This field allows you to specify the following: + + + - Snapshot behavior: Determines whether a snapshot of the volume should be taken when performing + a snapshot backup of the Component. + - Disk high watermark: Sets the high watermark for the volume's disk usage. + When the disk usage reaches the specified threshold, it triggers an alert or action. + + + By configuring these volume behaviors, you can control how the volumes are managed and monitored within the Component. + + + This field is immutable. + items: + properties: + highWatermark: + default: 0 + description: |- + Sets the critical threshold for volume space utilization as a percentage (0-100). + + + Exceeding this percentage triggers the system to switch the volume to read-only mode as specified in + `componentDefinition.spec.lifecycleActions.readOnly`. + This precaution helps prevent space depletion while maintaining read-only access. + If the space utilization later falls below this threshold, the system reverts the volume to read-write mode + as defined in `componentDefinition.spec.lifecycleActions.readWrite`, restoring full functionality. + + + Note: This field cannot be updated. + maximum: 100 + minimum: 0 + type: integer + name: + description: |- + Specifies the name of the volume. + It must be a DNS_LABEL and unique within the pod. + More info can be found at: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + Note: This field cannot be updated. + type: string + needSnapshot: + default: false + description: |- + Specifies whether the creation of a snapshot of this volume is necessary when performing a backup of the Component. + + + Note: This field cannot be updated. + type: boolean + required: + - name + type: object + type: array + required: + - runtime type: object status: - description: ComponentDefinitionStatus defines the observed state of ComponentDefinition + description: ComponentDefinitionStatus defines the observed state of ComponentDefinition. + properties: + message: + description: Provides additional information about the current phase. + type: string + observedGeneration: + description: Refers to the most recent generation that has been observed + for the ComponentDefinition. + format: int64 + type: integer + phase: + description: |- + Represents the current status of the ComponentDefinition. Valid values include ``, `Available`, and `Unavailable`. + When the status is `Available`, the ComponentDefinition is ready and can be utilized by related objects. + enum: + - Available + - Unavailable + type: string type: object type: object served: true diff --git a/config/crd/bases/apps.kubeblocks.io_components.yaml b/config/crd/bases/apps.kubeblocks.io_components.yaml index 1aade3253e2..eec88d35964 100644 --- a/config/crd/bases/apps.kubeblocks.io_components.yaml +++ b/config/crd/bases/apps.kubeblocks.io_components.yaml @@ -75,13 +75,7434 @@ spec: spec: description: ComponentSpec defines the desired state of Component properties: - foo: - description: Foo is an example field of Component. Edit component_types.go - to remove/update + annotations: + additionalProperties: + type: string + description: Specifies Annotations to override or add for underlying + Pods. + type: object + compDef: + description: Specifies the name of the referenced ComponentDefinition. + maxLength: 64 type: string + configs: + description: Specifies the configuration content of a config template. + items: + description: ClusterComponentConfig represents a config with its + source bound. + properties: + configMap: + description: ConfigMap source for the config. + properties: + defaultMode: + description: |- + defaultMode is optional: mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + items: + description: |- + items if unspecified, each key-value pair in the Data field of the referenced + ConfigMap will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the ConfigMap, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + 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 + optional: + description: optional specify whether the ConfigMap or its + keys must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + name: + description: The name of the config. + type: string + type: object + type: array + disableExporter: + description: |- + Determines whether metrics exporter information is annotated on the Component's headless Service. + + + If set to true, the following annotations will not be patched into the Service: + + + - "monitor.kubeblocks.io/path" + - "monitor.kubeblocks.io/port" + - "monitor.kubeblocks.io/scheme" + + + These annotations allow the Prometheus installed by KubeBlocks to discover and scrape metrics from the exporter. + type: boolean + enabledLogs: + description: |- + Specifies which types of logs should be collected for the Cluster. + The log types are defined in the `componentDefinition.spec.logConfigs` field with the LogConfig entries. + + + The elements in the `enabledLogs` array correspond to the names of the LogConfig entries. + For example, if the `componentDefinition.spec.logConfigs` defines LogConfig entries with + names "slow_query_log" and "error_log", + you can enable the collection of these logs by including their names in the `enabledLogs` array: + ```yaml + enabledLogs: + - slow_query_log + - error_log + ``` + items: + type: string + type: array + x-kubernetes-list-type: set + env: + description: List of environment variables to add. + items: + description: EnvVar represents an environment variable present in + a Container. + properties: + name: + description: Name of the environment variable. Must be a C_IDENTIFIER. + type: string + value: + description: |- + Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in the container and + any service environment variables. If a variable cannot be resolved, + the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless of whether the variable + exists or not. + Defaults to "". + type: string + valueFrom: + description: Source for the environment variable's value. Cannot + be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the FieldPath is + written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the specified + API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the exposed + resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in the pod's namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must + be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + instances: + description: |- + Allows for the customization of configuration values for each instance within a Component. + An Instance represent a single replica (Pod and associated K8s resources like PVCs, Services, and ConfigMaps). + While instances typically share a common configuration as defined in the ClusterComponentSpec, + they can require unique settings in various scenarios: + + + For example: + - A database Component might require different resource allocations for primary and secondary instances, + with primaries needing more resources. + - During a rolling upgrade, a Component may first update the image for one or a few instances, + and then update the remaining instances after verifying that the updated instances are functioning correctly. + + + InstanceTemplate allows for specifying these unique configurations per instance. + Each instance's name is constructed using the pattern: $(component.name)-$(template.name)-$(ordinal), + starting with an ordinal of 0. + It is crucial to maintain unique names for each InstanceTemplate to avoid conflicts. + + + The sum of replicas across all InstanceTemplates should not exceed the total number of Replicas specified for the Component. + Any remaining replicas will be generated using the default template and will follow the default naming rules. + items: + description: InstanceTemplate allows customization of individual + replica configurations in a Component. + properties: + annotations: + additionalProperties: + type: string + description: |- + Specifies a map of key-value pairs to be merged into the Pod's existing annotations. + Existing keys will have their values overwritten, while new keys will be added to the annotations. + type: object + env: + description: |- + Defines Env to override. + Add new or override existing envs. + items: + description: EnvVar represents an environment variable present + in a Container. + properties: + name: + description: Name of the environment variable. Must be + a C_IDENTIFIER. + type: string + value: + description: |- + Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in the container and + any service environment variables. If a variable cannot be resolved, + the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless of whether the variable + exists or not. + Defaults to "". + type: string + valueFrom: + description: Source for the environment variable's value. + Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap or + its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the + specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the + exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in the pod's + namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its + key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + image: + description: Specifies an override for the first container's + image in the Pod. + type: string + labels: + additionalProperties: + type: string + description: |- + Specifies a map of key-value pairs that will be merged into the Pod's existing labels. + Values for existing keys will be overwritten, and new keys will be added. + type: object + name: + description: |- + Name specifies the unique name of the instance Pod created using this InstanceTemplate. + This name is constructed by concatenating the Component's name, the template's name, and the instance's ordinal + using the pattern: $(cluster.name)-$(component.name)-$(template.name)-$(ordinal). Ordinals start from 0. + The specified name overrides any default naming conventions or patterns. + maxLength: 54 + pattern: ^[a-z0-9]([a-z0-9\.\-]*[a-z0-9])?$ + type: string + replicas: + default: 1 + description: |- + Specifies the number of instances (Pods) to create from this InstanceTemplate. + This field allows setting how many replicated instances of the Component, + with the specific overrides in the InstanceTemplate, are created. + The default value is 1. A value of 0 disables instance creation. + format: int32 + minimum: 0 + type: integer + resources: + description: |- + Specifies an override for the resource requirements of the first container in the Pod. + This field allows for customizing resource allocation (CPU, memory, etc.) for the container. + properties: + claims: + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + + + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + + + This field is immutable. It can only be set for containers. + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + schedulingPolicy: + description: Specifies the scheduling policy for the Component. + properties: + affinity: + description: Specifies a group of affinity scheduling rules + of the Cluster, including NodeAffinity, PodAffinity, and + PodAntiAffinity. + properties: + nodeAffinity: + description: Describes node affinity scheduling rules + for the pod. + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node matches the corresponding matchExpressions; the + node(s) with the highest sum are the most preferred. + items: + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). + properties: + preference: + description: A node selector term, associated + with the corresponding weight. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that + the selector applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that + the selector applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + weight: + description: Weight associated with matching + the corresponding nodeSelectorTerm, in the + range 1-100. + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. + properties: + nodeSelectorTerms: + description: Required. A list of node selector + terms. The terms are ORed. + items: + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that + the selector applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that + the selector applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + type: array + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + description: Describes pod affinity scheduling rules + (e.g. co-locate this pod in the same node, zone, etc. + as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched + WeightedPodAffinityTerm fields are added per-node + to find the most preferred node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, + associated with the corresponding weight. + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a + list of label selector requirements. + The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. + Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a + list of label selector requirements. + The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: |- + weight associated with matching the corresponding podAffinityTerm, + in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. + items: + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. + Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + description: Describes pod anti-affinity scheduling + rules (e.g. avoid putting this pod in the same node, + zone, etc. as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the anti-affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched + WeightedPodAffinityTerm fields are added per-node + to find the most preferred node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, + associated with the corresponding weight. + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a + list of label selector requirements. + The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. + Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a + list of label selector requirements. + The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: |- + weight associated with matching the corresponding podAffinityTerm, + in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the anti-affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the anti-affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. + items: + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. + Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + nodeName: + description: |- + NodeName is a request to schedule this Pod onto a specific node. If it is non-empty, + the scheduler simply schedules this Pod onto that node, assuming that it fits resource + requirements. + type: string + nodeSelector: + additionalProperties: + type: string + description: |- + NodeSelector is a selector which must be true for the Pod to fit on a node. + Selector which must match a node's labels for the Pod to be scheduled on that node. + More info: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ + type: object + x-kubernetes-map-type: atomic + schedulerName: + description: |- + If specified, the Pod will be dispatched by specified scheduler. + If not specified, the Pod will be dispatched by default scheduler. + type: string + tolerations: + description: |- + Allows Pods to be scheduled onto nodes with matching taints. + Each toleration in the array allows the Pod to tolerate node taints based on + specified `key`, `value`, `effect`, and `operator`. + + + - The `key`, `value`, and `effect` identify the taint that the toleration matches. + - The `operator` determines how the toleration matches the taint. + + + Pods with matching tolerations are allowed to be scheduled on tainted nodes, typically reserved for specific purposes. + items: + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . + properties: + effect: + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. + type: string + operator: + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. + type: string + tolerationSeconds: + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. + format: int64 + type: integer + value: + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. + type: string + type: object + type: array + topologySpreadConstraints: + description: |- + TopologySpreadConstraints describes how a group of Pods ought to spread across topology + domains. Scheduler will schedule Pods in a way which abides by the constraints. + All topologySpreadConstraints are ANDed. + items: + description: TopologySpreadConstraint specifies how to + spread matching pods among the given topology. + properties: + labelSelector: + description: |- + LabelSelector is used to find matching pods. + Pods that match this label selector are counted to determine the number of pods + in their corresponding topology domain. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select the pods over which + spreading will be calculated. The keys are used to lookup values from the + incoming pod labels, those key-value labels are ANDed with labelSelector + to select the group of existing pods over which spreading will be calculated + for the incoming pod. The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + MatchLabelKeys cannot be set when LabelSelector isn't set. + Keys that don't exist in the incoming pod labels will + be ignored. A null or empty list means only match against labelSelector. + + + This is a beta field and requires the MatchLabelKeysInPodTopologySpread feature gate to be enabled (enabled by default). + items: + type: string + type: array + x-kubernetes-list-type: atomic + maxSkew: + description: |- + MaxSkew describes the degree to which pods may be unevenly distributed. + When `whenUnsatisfiable=DoNotSchedule`, it is the maximum permitted difference + between the number of matching pods in the target topology and the global minimum. + The global minimum is the minimum number of matching pods in an eligible domain + or zero if the number of eligible domains is less than MinDomains. + For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same + labelSelector spread as 2/2/1: + In this case, the global minimum is 1. + | zone1 | zone2 | zone3 | + | P P | P P | P | + - if MaxSkew is 1, incoming pod can only be scheduled to zone3 to become 2/2/2; + scheduling it onto zone1(zone2) would make the ActualSkew(3-1) on zone1(zone2) + violate MaxSkew(1). + - if MaxSkew is 2, incoming pod can be scheduled onto any zone. + When `whenUnsatisfiable=ScheduleAnyway`, it is used to give higher precedence + to topologies that satisfy it. + It's a required field. Default value is 1 and 0 is not allowed. + format: int32 + type: integer + minDomains: + description: |- + MinDomains indicates a minimum number of eligible domains. + When the number of eligible domains with matching topology keys is less than minDomains, + Pod Topology Spread treats "global minimum" as 0, and then the calculation of Skew is performed. + And when the number of eligible domains with matching topology keys equals or greater than minDomains, + this value has no effect on scheduling. + As a result, when the number of eligible domains is less than minDomains, + scheduler won't schedule more than maxSkew Pods to those domains. + If value is nil, the constraint behaves as if MinDomains is equal to 1. + Valid values are integers greater than 0. + When value is not nil, WhenUnsatisfiable must be DoNotSchedule. + + + For example, in a 3-zone cluster, MaxSkew is set to 2, MinDomains is set to 5 and pods with the same + labelSelector spread as 2/2/2: + | zone1 | zone2 | zone3 | + | P P | P P | P P | + The number of domains is less than 5(MinDomains), so "global minimum" is treated as 0. + In this situation, new pod with the same labelSelector cannot be scheduled, + because computed skew will be 3(3 - 0) if new Pod is scheduled to any of the three zones, + it will violate MaxSkew. + + + This is a beta field and requires the MinDomainsInPodTopologySpread feature gate to be enabled (enabled by default). + format: int32 + type: integer + nodeAffinityPolicy: + description: |- + NodeAffinityPolicy indicates how we will treat Pod's nodeAffinity/nodeSelector + when calculating pod topology spread skew. Options are: + - Honor: only nodes matching nodeAffinity/nodeSelector are included in the calculations. + - Ignore: nodeAffinity/nodeSelector are ignored. All nodes are included in the calculations. + + + If this value is nil, the behavior is equivalent to the Honor policy. + This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag. + type: string + nodeTaintsPolicy: + description: |- + NodeTaintsPolicy indicates how we will treat node taints when calculating + pod topology spread skew. Options are: + - Honor: nodes without taints, along with tainted nodes for which the incoming pod + has a toleration, are included. + - Ignore: node taints are ignored. All nodes are included. + + + If this value is nil, the behavior is equivalent to the Ignore policy. + This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag. + type: string + topologyKey: + description: |- + TopologyKey is the key of node labels. Nodes that have a label with this key + and identical values are considered to be in the same topology. + We consider each as a "bucket", and try to put balanced number + of pods into each bucket. + We define a domain as a particular instance of a topology. + Also, we define an eligible domain as a domain whose nodes meet the requirements of + nodeAffinityPolicy and nodeTaintsPolicy. + e.g. If TopologyKey is "kubernetes.io/hostname", each Node is a domain of that topology. + And, if TopologyKey is "topology.kubernetes.io/zone", each zone is a domain of that topology. + It's a required field. + type: string + whenUnsatisfiable: + description: |- + WhenUnsatisfiable indicates how to deal with a pod if it doesn't satisfy + the spread constraint. + - DoNotSchedule (default) tells the scheduler not to schedule it. + - ScheduleAnyway tells the scheduler to schedule the pod in any location, + but giving higher precedence to topologies that would help reduce the + skew. + A constraint is considered "Unsatisfiable" for an incoming pod + if and only if every possible node assignment for that pod would violate + "MaxSkew" on some topology. + For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same + labelSelector spread as 3/1/1: + | zone1 | zone2 | zone3 | + | P P P | P | P | + If WhenUnsatisfiable is set to DoNotSchedule, incoming pod can only be scheduled + to zone2(zone3) to become 3/2/1(3/1/2) as ActualSkew(2-1) on zone2(zone3) satisfies + MaxSkew(1). In other words, the cluster can still be imbalanced, but scheduler + won't make it *more* imbalanced. + It's a required field. + type: string + required: + - maxSkew + - topologyKey + - whenUnsatisfiable + type: object + type: array + type: object + volumeClaimTemplates: + description: |- + Defines VolumeClaimTemplates to override. + Add new or override existing volume claim templates. + items: + properties: + name: + description: |- + Refers to the name of a volumeMount defined in either: + + + - `componentDefinition.spec.runtime.containers[*].volumeMounts` + - `clusterDefinition.spec.componentDefs[*].podSpec.containers[*].volumeMounts` (deprecated) + + + The value of `name` must match the `name` field of a volumeMount specified in the corresponding `volumeMounts` array. + type: string + spec: + description: |- + Defines the desired characteristics of a PersistentVolumeClaim that will be created for the volume + with the mount name specified in the `name` field. + + + When a Pod is created for this ClusterComponent, a new PVC will be created based on the specification + defined in the `spec` field. The PVC will be associated with the volume mount specified by the `name` field. + properties: + accessModes: + description: |- + Contains the desired access modes the volume should have. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1. + items: + type: string + type: array + x-kubernetes-preserve-unknown-fields: true + resources: + description: |- + Represents the minimum resources the volume should have. + If the RecoverVolumeExpansionFailure feature is enabled, users are allowed to specify resource requirements that + are lower than the previous value but must still be higher than the capacity recorded in the status field of the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources. + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + x-kubernetes-preserve-unknown-fields: true + storageClassName: + description: |- + The name of the StorageClass required by the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1. + type: string + volumeMode: + description: Defines what type of volume is required + by the claim, either Block or Filesystem. + type: string + type: object + required: + - name + type: object + type: array + volumeMounts: + description: |- + Defines VolumeMounts to override. + Add new or override existing volume mounts of the first container in the Pod. + items: + description: VolumeMount describes a mounting of a Volume + within a container. + properties: + mountPath: + description: |- + Path within the container at which the volume should be mounted. Must + not contain ':'. + type: string + mountPropagation: + description: |- + mountPropagation determines how mounts are propagated from the host + to container and the other way around. + When not set, MountPropagationNone is used. + This field is beta in 1.10. + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: |- + Mounted read-only if true, read-write otherwise (false or unspecified). + Defaults to false. + type: boolean + subPath: + description: |- + Path within the volume from which the container's volume should be mounted. + Defaults to "" (volume's root). + type: string + subPathExpr: + description: |- + Expanded path within the volume from which the container's volume should be mounted. + Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment. + Defaults to "" (volume's root). + SubPathExpr and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + volumes: + description: |- + Defines Volumes to override. + Add new or override existing volumes. + items: + description: Volume represents a named volume in a pod that + may be accessed by any container in the pod. + properties: + awsElasticBlockStore: + description: |- + awsElasticBlockStore represents an AWS Disk resource that is attached to a + kubelet's host machine and then exposed to the pod. + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + properties: + fsType: + description: |- + fsType is the filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + partition: + description: |- + partition is the partition in the volume that you want to mount. + If omitted, the default is to mount by volume name. + Examples: For volume /dev/sda1, you specify the partition as "1". + Similarly, the volume partition for /dev/sda is "0" (or you can leave the property empty). + format: int32 + type: integer + readOnly: + description: |- + readOnly value true will force the readOnly setting in VolumeMounts. + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + type: boolean + volumeID: + description: |- + volumeID is unique ID of the persistent disk resource in AWS (Amazon EBS volume). + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + type: string + required: + - volumeID + type: object + azureDisk: + description: azureDisk represents an Azure Data Disk mount + on the host and bind mount to the pod. + properties: + cachingMode: + description: 'cachingMode is the Host Caching mode: + None, Read Only, Read Write.' + type: string + diskName: + description: diskName is the Name of the data disk + in the blob storage + type: string + diskURI: + description: diskURI is the URI of data disk in the + blob storage + type: string + fsType: + description: |- + fsType is Filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + kind: + description: 'kind expected values are Shared: multiple + blob disks per storage account Dedicated: single + blob disk per storage account Managed: azure managed + data disk (only in managed availability set). defaults + to shared' + type: string + readOnly: + description: |- + readOnly Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + description: azureFile represents an Azure File Service + mount on the host and bind mount to the pod. + properties: + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretName: + description: secretName is the name of secret that + contains Azure Storage Account Name and Key + type: string + shareName: + description: shareName is the azure share Name + type: string + required: + - secretName + - shareName + type: object + cephfs: + description: cephFS represents a Ceph FS mount on the + host that shares a pod's lifetime + properties: + monitors: + description: |- + monitors is Required: Monitors is a collection of Ceph monitors + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + items: + type: string + type: array + path: + description: 'path is Optional: Used as the mounted + root, rather than the full Ceph tree, default is + /' + type: string + readOnly: + description: |- + readOnly is Optional: Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + type: boolean + secretFile: + description: |- + secretFile is Optional: SecretFile is the path to key ring for User, default is /etc/ceph/user.secret + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + type: string + secretRef: + description: |- + secretRef is Optional: SecretRef is reference to the authentication secret for User, default is empty. + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + 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 + user: + description: |- + user is optional: User is the rados user name, default is admin + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + type: string + required: + - monitors + type: object + cinder: + description: |- + cinder represents a cinder volume attached and mounted on kubelets host machine. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + type: string + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + type: boolean + secretRef: + description: |- + secretRef is optional: points to a secret object containing parameters used to connect + to OpenStack. + 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 + volumeID: + description: |- + volumeID used to identify the volume in cinder. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + type: string + required: + - volumeID + type: object + configMap: + description: configMap represents a configMap that should + populate this volume + properties: + defaultMode: + description: |- + defaultMode is optional: mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + items: + description: |- + items if unspecified, each key-value pair in the Data field of the referenced + ConfigMap will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the ConfigMap, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within + a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + 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 + optional: + description: optional specify whether the ConfigMap + or its keys must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + csi: + description: csi (Container Storage Interface) represents + ephemeral storage that is handled by certain external + CSI drivers (Beta feature). + properties: + driver: + description: |- + driver is the name of the CSI driver that handles this volume. + Consult with your admin for the correct name as registered in the cluster. + type: string + fsType: + description: |- + fsType to mount. Ex. "ext4", "xfs", "ntfs". + If not provided, the empty value is passed to the associated CSI driver + which will determine the default filesystem to apply. + type: string + nodePublishSecretRef: + description: |- + nodePublishSecretRef is a reference to the secret object containing + sensitive information to pass to the CSI driver to complete the CSI + NodePublishVolume and NodeUnpublishVolume calls. + This field is optional, and may be empty if no secret is required. If the + secret object contains more than one secret, all secret references are passed. + 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 + readOnly: + description: |- + readOnly specifies a read-only configuration for the volume. + Defaults to false (read/write). + type: boolean + volumeAttributes: + additionalProperties: + type: string + description: |- + volumeAttributes stores driver-specific properties that are passed to the CSI + driver. Consult your driver's documentation for supported values. + type: object + required: + - driver + type: object + downwardAPI: + description: downwardAPI represents downward API about + the pod that should populate this volume + properties: + defaultMode: + description: |- + Optional: mode bits to use on created files by default. Must be a + Optional: mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + items: + description: Items is a list of downward API volume + file + items: + description: DownwardAPIVolumeFile represents information + to create the file containing the pod field + properties: + fieldRef: + description: 'Required: Selects a field of the + pod: only annotations, labels, name and namespace + are supported.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select + in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + description: |- + Optional: mode bits used to set permissions on this file, must be an octal value + between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: 'Required: Path is the relative + path name of the file to be created. Must + not be absolute or contain the ''..'' path. + Must be utf-8 encoded. The first item of the + relative path must not start with ''..''' + type: string + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported. + properties: + containerName: + description: 'Container name: required for + volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format + of the exposed resources, defaults to + "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + type: object + emptyDir: + description: |- + emptyDir represents a temporary directory that shares a pod's lifetime. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir + properties: + medium: + description: |- + medium represents what type of storage medium should back this directory. + The default is "" which means to use the node's default medium. + Must be an empty string (default) or Memory. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + description: |- + sizeLimit is the total amount of local storage required for this EmptyDir volume. + The size limit is also applicable for memory medium. + The maximum usage on memory medium EmptyDir would be the minimum value between + the SizeLimit specified here and the sum of memory limits of all containers in a pod. + The default is nil which means that the limit is undefined. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + description: |- + ephemeral represents a volume that is handled by a cluster storage driver. + The volume's lifecycle is tied to the pod that defines it - it will be created before the pod starts, + and deleted when the pod is removed. + + + Use this if: + a) the volume is only needed while the pod runs, + b) features of normal volumes like restoring from snapshot or capacity + tracking are needed, + c) the storage driver is specified through a storage class, and + d) the storage driver supports dynamic volume provisioning through + a PersistentVolumeClaim (see EphemeralVolumeSource for more + information on the connection between this volume type + and PersistentVolumeClaim). + + + Use PersistentVolumeClaim or one of the vendor-specific + APIs for volumes that persist for longer than the lifecycle + of an individual pod. + + + Use CSI for light-weight local ephemeral volumes if the CSI driver is meant to + be used that way - see the documentation of the driver for + more information. + + + A pod can use both types of ephemeral volumes and + persistent volumes at the same time. + properties: + volumeClaimTemplate: + description: |- + Will be used to create a stand-alone PVC to provision the volume. + The pod in which this EphemeralVolumeSource is embedded will be the + owner of the PVC, i.e. the PVC will be deleted together with the + pod. The name of the PVC will be `-` where + `` is the name from the `PodSpec.Volumes` array + entry. Pod validation will reject the pod if the concatenated name + is not valid for a PVC (for example, too long). + + + An existing PVC with that name that is not owned by the pod + will *not* be used for the pod to avoid using an unrelated + volume by mistake. Starting the pod is then blocked until + the unrelated PVC is removed. If such a pre-created PVC is + meant to be used by the pod, the PVC has to updated with an + owner reference to the pod once the pod exists. Normally + this should not be necessary, but it may be useful when + manually reconstructing a broken cluster. + + + This field is read-only and no changes will be made by Kubernetes + to the PVC after it has been created. + + + Required, must not be nil. + properties: + metadata: + description: |- + May contain labels and annotations that will be copied into the PVC + when creating it. No other fields are allowed and will be rejected during + validation. + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + description: |- + The specification for the PersistentVolumeClaim. The entire content is + copied unchanged into the PVC that gets created from this + template. The same fields as in a PersistentVolumeClaim + are also valid here. + properties: + accessModes: + description: |- + accessModes contains the desired access modes the volume should have. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1 + items: + type: string + type: array + dataSource: + description: |- + dataSource field can be used to specify either: + * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) + * An existing PVC (PersistentVolumeClaim) + If the provisioner or an external controller can support the specified data source, + it will create a new volume based on the contents of the specified data source. + When the AnyVolumeDataSource feature gate is enabled, dataSource contents will be copied to dataSourceRef, + and dataSourceRef contents will be copied to dataSource when dataSourceRef.namespace is not specified. + If the namespace is specified, then dataSourceRef will not be copied to dataSource. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource + being referenced + type: string + name: + description: Name is the name of resource + being referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + description: |- + dataSourceRef specifies the object from which to populate the volume with data, if a non-empty + volume is desired. This may be any object from a non-empty API group (non + core object) or a PersistentVolumeClaim object. + When this field is specified, volume binding will only succeed if the type of + the specified object matches some installed volume populator or dynamic + provisioner. + This field will replace the functionality of the dataSource field and as such + if both fields are non-empty, they must have the same value. For backwards + compatibility, when namespace isn't specified in dataSourceRef, + both fields (dataSource and dataSourceRef) will be set to the same + value automatically if one of them is empty and the other is non-empty. + When namespace is specified in dataSourceRef, + dataSource isn't set to the same value and must be empty. + There are three important differences between dataSource and dataSourceRef: + * While dataSource only allows two specific types of objects, dataSourceRef + allows any non-core object, as well as PersistentVolumeClaim objects. + * While dataSource ignores disallowed values (dropping them), dataSourceRef + preserves all values, and generates an error if a disallowed value is + specified. + * While dataSource only allows local objects, dataSourceRef allows objects + in any namespaces. + (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled. + (Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource + being referenced + type: string + name: + description: Name is the name of resource + being referenced + type: string + namespace: + description: |- + Namespace is the namespace of resource being referenced + Note that when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details. + (Alpha) This field requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + type: string + required: + - kind + - name + type: object + resources: + description: |- + resources represents the minimum resources the volume should have. + If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements + that are lower than previous value but must still be higher than capacity recorded in the + status field of the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + selector: + description: selector is a label query over + volumes to consider for binding. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + description: |- + storageClassName is the name of the StorageClass required by the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1 + type: string + volumeAttributesClassName: + description: |- + volumeAttributesClassName may be used to set the VolumeAttributesClass used by this claim. + If specified, the CSI driver will create or update the volume with the attributes defined + in the corresponding VolumeAttributesClass. This has a different purpose than storageClassName, + it can be changed after the claim is created. An empty string value means that no VolumeAttributesClass + will be applied to the claim but it's not allowed to reset this field to empty string once it is set. + If unspecified and the PersistentVolumeClaim is unbound, the default VolumeAttributesClass + will be set by the persistentvolume controller if it exists. + If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be + set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource + exists. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#volumeattributesclass + (Alpha) Using this field requires the VolumeAttributesClass feature gate to be enabled. + type: string + volumeMode: + description: |- + volumeMode defines what type of volume is required by the claim. + Value of Filesystem is implied when not included in claim spec. + type: string + volumeName: + description: volumeName is the binding reference + to the PersistentVolume backing this claim. + type: string + type: object + required: + - spec + type: object + type: object + fc: + description: fc represents a Fibre Channel resource that + is attached to a kubelet's host machine and then exposed + to the pod. + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + lun: + description: 'lun is Optional: FC target lun number' + format: int32 + type: integer + readOnly: + description: |- + readOnly is Optional: Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + targetWWNs: + description: 'targetWWNs is Optional: FC target worldwide + names (WWNs)' + items: + type: string + type: array + wwids: + description: |- + wwids Optional: FC volume world wide identifiers (wwids) + Either wwids or combination of targetWWNs and lun must be set, but not both simultaneously. + items: + type: string + type: array + type: object + flexVolume: + description: |- + flexVolume represents a generic volume resource that is + provisioned/attached using an exec based plugin. + properties: + driver: + description: driver is the name of the driver to use + for this volume. + type: string + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". The default filesystem depends on FlexVolume script. + type: string + options: + additionalProperties: + type: string + description: 'options is Optional: this field holds + extra command options if any.' + type: object + readOnly: + description: |- + readOnly is Optional: defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: |- + secretRef is Optional: secretRef is reference to the secret object containing + sensitive information to pass to the plugin scripts. This may be + empty if no secret object is specified. If the secret object + contains more than one secret, all secrets are passed to the plugin + scripts. + 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 + required: + - driver + type: object + flocker: + description: flocker represents a Flocker volume attached + to a kubelet's host machine. This depends on the Flocker + control service being running + properties: + datasetName: + description: |- + datasetName is Name of the dataset stored as metadata -> name on the dataset for Flocker + should be considered as deprecated + type: string + datasetUUID: + description: datasetUUID is the UUID of the dataset. + This is unique identifier of a Flocker dataset + type: string + type: object + gcePersistentDisk: + description: |- + gcePersistentDisk represents a GCE Disk resource that is attached to a + kubelet's host machine and then exposed to the pod. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + properties: + fsType: + description: |- + fsType is filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + partition: + description: |- + partition is the partition in the volume that you want to mount. + If omitted, the default is to mount by volume name. + Examples: For volume /dev/sda1, you specify the partition as "1". + Similarly, the volume partition for /dev/sda is "0" (or you can leave the property empty). + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + format: int32 + type: integer + pdName: + description: |- + pdName is unique name of the PD resource in GCE. Used to identify the disk in GCE. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + type: string + readOnly: + description: |- + readOnly here will force the ReadOnly setting in VolumeMounts. + Defaults to false. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + type: boolean + required: + - pdName + type: object + gitRepo: + description: |- + gitRepo represents a git repository at a particular revision. + DEPRECATED: GitRepo is deprecated. To provision a container with a git repo, mount an + EmptyDir into an InitContainer that clones the repo using git, then mount the EmptyDir + into the Pod's container. + properties: + directory: + description: |- + directory is the target directory name. + Must not contain or start with '..'. If '.' is supplied, the volume directory will be the + git repository. Otherwise, if specified, the volume will contain the git repository in + the subdirectory with the given name. + type: string + repository: + description: repository is the URL + type: string + revision: + description: revision is the commit hash for the specified + revision. + type: string + required: + - repository + type: object + glusterfs: + description: |- + glusterfs represents a Glusterfs mount on the host that shares a pod's lifetime. + More info: https://examples.k8s.io/volumes/glusterfs/README.md + properties: + endpoints: + description: |- + endpoints is the endpoint name that details Glusterfs topology. + More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod + type: string + path: + description: |- + path is the Glusterfs volume path. + More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod + type: string + readOnly: + description: |- + readOnly here will force the Glusterfs volume to be mounted with read-only permissions. + Defaults to false. + More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod + type: boolean + required: + - endpoints + - path + type: object + hostPath: + description: |- + hostPath represents a pre-existing file or directory on the host + machine that is directly exposed to the container. This is generally + used for system agents or other privileged things that are allowed + to see the host machine. Most containers will NOT need this. + More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + --- + TODO(jonesdl) We need to restrict who can use host directory mounts and who can/can not + mount host directories as read/write. + properties: + path: + description: |- + path of the directory on the host. + If the path is a symlink, it will follow the link to the real path. + More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + type: string + type: + description: |- + type for HostPath Volume + Defaults to "" + More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + type: string + required: + - path + type: object + iscsi: + description: |- + iscsi represents an ISCSI Disk resource that is attached to a + kubelet's host machine and then exposed to the pod. + More info: https://examples.k8s.io/volumes/iscsi/README.md + properties: + chapAuthDiscovery: + description: chapAuthDiscovery defines whether support + iSCSI Discovery CHAP authentication + type: boolean + chapAuthSession: + description: chapAuthSession defines whether support + iSCSI Session CHAP authentication + type: boolean + fsType: + description: |- + fsType is the filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#iscsi + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + initiatorName: + description: |- + initiatorName is the custom iSCSI Initiator Name. + If initiatorName is specified with iscsiInterface simultaneously, new iSCSI interface + : will be created for the connection. + type: string + iqn: + description: iqn is the target iSCSI Qualified Name. + type: string + iscsiInterface: + description: |- + iscsiInterface is the interface Name that uses an iSCSI transport. + Defaults to 'default' (tcp). + type: string + lun: + description: lun represents iSCSI Target Lun number. + format: int32 + type: integer + portals: + description: |- + portals is the iSCSI Target Portal List. The portal is either an IP or ip_addr:port if the port + is other than default (typically TCP ports 860 and 3260). + items: + type: string + type: array + readOnly: + description: |- + readOnly here will force the ReadOnly setting in VolumeMounts. + Defaults to false. + type: boolean + secretRef: + description: secretRef is the CHAP Secret for iSCSI + target and initiator authentication + 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 + targetPortal: + description: |- + targetPortal is iSCSI Target Portal. The Portal is either an IP or ip_addr:port if the port + is other than default (typically TCP ports 860 and 3260). + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + description: |- + name of the volume. + Must be a DNS_LABEL and unique within the pod. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + nfs: + description: |- + nfs represents an NFS mount on the host that shares a pod's lifetime + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + properties: + path: + description: |- + path that is exported by the NFS server. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + type: string + readOnly: + description: |- + readOnly here will force the NFS export to be mounted with read-only permissions. + Defaults to false. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + type: boolean + server: + description: |- + server is the hostname or IP address of the NFS server. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + description: |- + persistentVolumeClaimVolumeSource represents a reference to a + PersistentVolumeClaim in the same namespace. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims + properties: + claimName: + description: |- + claimName is the name of a PersistentVolumeClaim in the same namespace as the pod using this volume. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims + type: string + readOnly: + description: |- + readOnly Will force the ReadOnly setting in VolumeMounts. + Default false. + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + description: photonPersistentDisk represents a PhotonController + persistent disk attached and mounted on kubelets host + machine + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + pdID: + description: pdID is the ID that identifies Photon + Controller persistent disk + type: string + required: + - pdID + type: object + portworxVolume: + description: portworxVolume represents a portworx volume + attached and mounted on kubelets host machine + properties: + fsType: + description: |- + fSType represents the filesystem type to mount + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs". Implicitly inferred to be "ext4" if unspecified. + type: string + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + volumeID: + description: volumeID uniquely identifies a Portworx + volume + type: string + required: + - volumeID + type: object + projected: + description: projected items for all in one resources + secrets, configmaps, and downward API + properties: + defaultMode: + description: |- + defaultMode are the mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + sources: + description: sources is the list of volume projections + items: + description: Projection that may be projected along + with other supported volume types + properties: + clusterTrustBundle: + description: |- + ClusterTrustBundle allows a pod to access the `.spec.trustBundle` field + of ClusterTrustBundle objects in an auto-updating file. + + + Alpha, gated by the ClusterTrustBundleProjection feature gate. + + + ClusterTrustBundle objects can either be selected by name, or by the + combination of signer name and a label selector. + + + Kubelet performs aggressive normalization of the PEM contents written + into the pod filesystem. Esoteric PEM features such as inter-block + comments and block headers are stripped. Certificates are deduplicated. + The ordering of certificates within the file is arbitrary, and Kubelet + may change the order over time. + properties: + labelSelector: + description: |- + Select all ClusterTrustBundles that match this label selector. Only has + effect if signerName is set. Mutually-exclusive with name. If unset, + interpreted as "match nothing". If set but empty, interpreted as "match + everything". + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + name: + description: |- + Select a single ClusterTrustBundle by object name. Mutually-exclusive + with signerName and labelSelector. + type: string + optional: + description: |- + If true, don't block pod startup if the referenced ClusterTrustBundle(s) + aren't available. If using name, then the named ClusterTrustBundle is + allowed not to exist. If using signerName, then the combination of + signerName and labelSelector is allowed to match zero + ClusterTrustBundles. + type: boolean + path: + description: Relative path from the volume + root to write the bundle. + type: string + signerName: + description: |- + Select all ClusterTrustBundles that match this signer name. + Mutually-exclusive with name. The contents of all selected + ClusterTrustBundles will be unified and deduplicated. + type: string + required: + - path + type: object + configMap: + description: configMap information about the + configMap data to project + properties: + items: + description: |- + items if unspecified, each key-value pair in the Data field of the referenced + ConfigMap will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the ConfigMap, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path + within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + 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 + optional: + description: optional specify whether the + ConfigMap or its keys must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + downwardAPI: + description: downwardAPI information about the + downwardAPI data to project + properties: + items: + description: Items is a list of DownwardAPIVolume + file + items: + description: DownwardAPIVolumeFile represents + information to create the file containing + the pod field + properties: + fieldRef: + description: 'Required: Selects a + field of the pod: only annotations, + labels, name and namespace are supported.' + properties: + apiVersion: + description: Version of the schema + the FieldPath is written in + terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field + to select in the specified API + version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + description: |- + Optional: mode bits used to set permissions on this file, must be an octal value + between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: 'Required: Path is the + relative path name of the file to + be created. Must not be absolute + or contain the ''..'' path. Must + be utf-8 encoded. The first item + of the relative path must not start + with ''..''' + type: string + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported. + properties: + containerName: + description: 'Container name: + required for volumes, optional + for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output + format of the exposed resources, + defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource + to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + type: object + secret: + description: secret information about the secret + data to project + properties: + items: + description: |- + items if unspecified, each key-value pair in the Data field of the referenced + Secret will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the Secret, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path + within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + 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 + optional: + description: optional field specify whether + the Secret or its key must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + serviceAccountToken: + description: serviceAccountToken is information + about the serviceAccountToken data to project + properties: + audience: + description: |- + audience is the intended audience of the token. A recipient of a token + must identify itself with an identifier specified in the audience of the + token, and otherwise should reject the token. The audience defaults to the + identifier of the apiserver. + type: string + expirationSeconds: + description: |- + expirationSeconds is the requested duration of validity of the service + account token. As the token approaches expiration, the kubelet volume + plugin will proactively rotate the service account token. The kubelet will + start trying to rotate the token if the token is older than 80 percent of + its time to live or if the token is older than 24 hours.Defaults to 1 hour + and must be at least 10 minutes. + format: int64 + type: integer + path: + description: |- + path is the path relative to the mount point of the file to project the + token into. + type: string + required: + - path + type: object + type: object + type: array + type: object + quobyte: + description: quobyte represents a Quobyte mount on the + host that shares a pod's lifetime + properties: + group: + description: |- + group to map volume access to + Default is no group + type: string + readOnly: + description: |- + readOnly here will force the Quobyte volume to be mounted with read-only permissions. + Defaults to false. + type: boolean + registry: + description: |- + registry represents a single or multiple Quobyte Registry services + specified as a string as host:port pair (multiple entries are separated with commas) + which acts as the central registry for volumes + type: string + tenant: + description: |- + tenant owning the given Quobyte volume in the Backend + Used with dynamically provisioned Quobyte volumes, value is set by the plugin + type: string + user: + description: |- + user to map volume access to + Defaults to serivceaccount user + type: string + volume: + description: volume is a string that references an + already created Quobyte volume by name. + type: string + required: + - registry + - volume + type: object + rbd: + description: |- + rbd represents a Rados Block Device mount on the host that shares a pod's lifetime. + More info: https://examples.k8s.io/volumes/rbd/README.md + properties: + fsType: + description: |- + fsType is the filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#rbd + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + image: + description: |- + image is the rados image name. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + keyring: + description: |- + keyring is the path to key ring for RBDUser. + Default is /etc/ceph/keyring. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + monitors: + description: |- + monitors is a collection of Ceph monitors. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + items: + type: string + type: array + pool: + description: |- + pool is the rados pool name. + Default is rbd. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + readOnly: + description: |- + readOnly here will force the ReadOnly setting in VolumeMounts. + Defaults to false. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: boolean + secretRef: + description: |- + secretRef is name of the authentication secret for RBDUser. If provided + overrides keyring. + Default is nil. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + 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 + user: + description: |- + user is the rados user name. + Default is admin. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + required: + - image + - monitors + type: object + scaleIO: + description: scaleIO represents a ScaleIO persistent volume + attached and mounted on Kubernetes nodes. + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". + Default is "xfs". + type: string + gateway: + description: gateway is the host address of the ScaleIO + API Gateway. + type: string + protectionDomain: + description: protectionDomain is the name of the ScaleIO + Protection Domain for the configured storage. + type: string + readOnly: + description: |- + readOnly Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: |- + secretRef references to the secret for ScaleIO user and other + sensitive information. If this is not provided, Login operation will fail. + 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 + sslEnabled: + description: sslEnabled Flag enable/disable SSL communication + with Gateway, default false + type: boolean + storageMode: + description: |- + storageMode indicates whether the storage for a volume should be ThickProvisioned or ThinProvisioned. + Default is ThinProvisioned. + type: string + storagePool: + description: storagePool is the ScaleIO Storage Pool + associated with the protection domain. + type: string + system: + description: system is the name of the storage system + as configured in ScaleIO. + type: string + volumeName: + description: |- + volumeName is the name of a volume already created in the ScaleIO system + that is associated with this volume source. + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + description: |- + secret represents a secret that should populate this volume. + More info: https://kubernetes.io/docs/concepts/storage/volumes#secret + properties: + defaultMode: + description: |- + defaultMode is Optional: mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values + for mode bits. Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + items: + description: |- + items If unspecified, each key-value pair in the Data field of the referenced + Secret will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the Secret, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within + a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + optional: + description: optional field specify whether the Secret + or its keys must be defined + type: boolean + secretName: + description: |- + secretName is the name of the secret in the pod's namespace to use. + More info: https://kubernetes.io/docs/concepts/storage/volumes#secret + type: string + type: object + storageos: + description: storageOS represents a StorageOS volume attached + and mounted on Kubernetes nodes. + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: |- + secretRef specifies the secret to use for obtaining the StorageOS API + credentials. If not specified, default values will be attempted. + 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 + volumeName: + description: |- + volumeName is the human-readable name of the StorageOS volume. Volume + names are only unique within a namespace. + type: string + volumeNamespace: + description: |- + volumeNamespace specifies the scope of the volume within StorageOS. If no + namespace is specified then the Pod's namespace will be used. This allows the + Kubernetes name scoping to be mirrored within StorageOS for tighter integration. + Set VolumeName to any name to override the default behaviour. + Set to "default" if you are not using namespaces within StorageOS. + Namespaces that do not pre-exist within StorageOS will be created. + type: string + type: object + vsphereVolume: + description: vsphereVolume represents a vSphere volume + attached and mounted on kubelets host machine + properties: + fsType: + description: |- + fsType is filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + storagePolicyID: + description: storagePolicyID is the storage Policy + Based Management (SPBM) profile ID associated with + the StoragePolicyName. + type: string + storagePolicyName: + description: storagePolicyName is the storage Policy + Based Management (SPBM) profile name. + type: string + volumePath: + description: volumePath is the path that identifies + vSphere volume vmdk + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + required: + - name + type: object + type: array + labels: + additionalProperties: + type: string + description: Specifies Labels to override or add for underlying Pods. + type: object + offlineInstances: + description: |- + Specifies the names of instances to be transitioned to offline status. + + + Marking an instance as offline results in the following: + + + 1. The associated Pod is stopped, and its PersistentVolumeClaim (PVC) is retained for potential + future reuse or data recovery, but it is no longer actively used. + 2. The ordinal number assigned to this instance is preserved, ensuring it remains unique + and avoiding conflicts with new instances. + + + Setting instances to offline allows for a controlled scale-in process, preserving their data and maintaining + ordinal consistency within the Cluster. + Note that offline instances and their associated resources, such as PVCs, are not automatically deleted. + The administrator must manually manage the cleanup and removal of these resources when they are no longer needed. + items: + type: string + type: array + parallelPodManagementConcurrency: + anyOf: + - type: integer + - type: string + description: |- + Controls the concurrency of pods during initial scale up, when replacing pods on nodes, + or when scaling down. It only used when `PodManagementPolicy` is set to `Parallel`. + The default Concurrency is 100%. + x-kubernetes-int-or-string: true + podUpdatePolicy: + description: |- + PodUpdatePolicy indicates how pods should be updated + + + - `StrictInPlace` indicates that only allows in-place upgrades. + Any attempt to modify other fields will be rejected. + - `PreferInPlace` indicates that we will first attempt an in-place upgrade of the Pod. + If that fails, it will fall back to the ReCreate, where pod will be recreated. + Default value is "PreferInPlace" + type: string + replicas: + default: 1 + description: Specifies the desired number of replicas in the Component + for enhancing availability and durability, or load balancing. + format: int32 + minimum: 0 + type: integer + resources: + description: |- + Specifies the resources required by the Component. + It allows defining the CPU, memory requirements and limits for the Component's containers. + properties: + claims: + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + + + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + + + This field is immutable. It can only be set for containers. + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + x-kubernetes-preserve-unknown-fields: true + runtimeClassName: + description: Defines runtimeClassName for all Pods managed by this + Component. + type: string + schedulingPolicy: + description: Specifies the scheduling policy for the Component. + properties: + affinity: + description: Specifies a group of affinity scheduling rules of + the Cluster, including NodeAffinity, PodAffinity, and PodAntiAffinity. + properties: + nodeAffinity: + description: Describes node affinity scheduling rules for + the pod. + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node matches the corresponding matchExpressions; the + node(s) with the highest sum are the most preferred. + items: + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). + properties: + preference: + description: A node selector term, associated with + the corresponding weight. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + weight: + description: Weight associated with matching the + corresponding nodeSelectorTerm, in the range 1-100. + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. + properties: + nodeSelectorTerms: + description: Required. A list of node selector terms. + The terms are ORed. + items: + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + type: array + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + description: Describes pod affinity scheduling rules (e.g. + co-locate this pod in the same node, zone, etc. as some + other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred + node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated + with the corresponding weight. + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. + Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: |- + weight associated with matching the corresponding podAffinityTerm, + in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. + items: + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. + Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + description: Describes pod anti-affinity scheduling rules + (e.g. avoid putting this pod in the same node, zone, etc. + as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the anti-affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred + node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated + with the corresponding weight. + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. + Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: |- + weight associated with matching the corresponding podAffinityTerm, + in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the anti-affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the anti-affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. + items: + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. + Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + nodeName: + description: |- + NodeName is a request to schedule this Pod onto a specific node. If it is non-empty, + the scheduler simply schedules this Pod onto that node, assuming that it fits resource + requirements. + type: string + nodeSelector: + additionalProperties: + type: string + description: |- + NodeSelector is a selector which must be true for the Pod to fit on a node. + Selector which must match a node's labels for the Pod to be scheduled on that node. + More info: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ + type: object + x-kubernetes-map-type: atomic + schedulerName: + description: |- + If specified, the Pod will be dispatched by specified scheduler. + If not specified, the Pod will be dispatched by default scheduler. + type: string + tolerations: + description: |- + Allows Pods to be scheduled onto nodes with matching taints. + Each toleration in the array allows the Pod to tolerate node taints based on + specified `key`, `value`, `effect`, and `operator`. + + + - The `key`, `value`, and `effect` identify the taint that the toleration matches. + - The `operator` determines how the toleration matches the taint. + + + Pods with matching tolerations are allowed to be scheduled on tainted nodes, typically reserved for specific purposes. + items: + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . + properties: + effect: + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. + type: string + operator: + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. + type: string + tolerationSeconds: + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. + format: int64 + type: integer + value: + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. + type: string + type: object + type: array + topologySpreadConstraints: + description: |- + TopologySpreadConstraints describes how a group of Pods ought to spread across topology + domains. Scheduler will schedule Pods in a way which abides by the constraints. + All topologySpreadConstraints are ANDed. + items: + description: TopologySpreadConstraint specifies how to spread + matching pods among the given topology. + properties: + labelSelector: + description: |- + LabelSelector is used to find matching pods. + Pods that match this label selector are counted to determine the number of pods + in their corresponding topology domain. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select the pods over which + spreading will be calculated. The keys are used to lookup values from the + incoming pod labels, those key-value labels are ANDed with labelSelector + to select the group of existing pods over which spreading will be calculated + for the incoming pod. The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + MatchLabelKeys cannot be set when LabelSelector isn't set. + Keys that don't exist in the incoming pod labels will + be ignored. A null or empty list means only match against labelSelector. + + + This is a beta field and requires the MatchLabelKeysInPodTopologySpread feature gate to be enabled (enabled by default). + items: + type: string + type: array + x-kubernetes-list-type: atomic + maxSkew: + description: |- + MaxSkew describes the degree to which pods may be unevenly distributed. + When `whenUnsatisfiable=DoNotSchedule`, it is the maximum permitted difference + between the number of matching pods in the target topology and the global minimum. + The global minimum is the minimum number of matching pods in an eligible domain + or zero if the number of eligible domains is less than MinDomains. + For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same + labelSelector spread as 2/2/1: + In this case, the global minimum is 1. + | zone1 | zone2 | zone3 | + | P P | P P | P | + - if MaxSkew is 1, incoming pod can only be scheduled to zone3 to become 2/2/2; + scheduling it onto zone1(zone2) would make the ActualSkew(3-1) on zone1(zone2) + violate MaxSkew(1). + - if MaxSkew is 2, incoming pod can be scheduled onto any zone. + When `whenUnsatisfiable=ScheduleAnyway`, it is used to give higher precedence + to topologies that satisfy it. + It's a required field. Default value is 1 and 0 is not allowed. + format: int32 + type: integer + minDomains: + description: |- + MinDomains indicates a minimum number of eligible domains. + When the number of eligible domains with matching topology keys is less than minDomains, + Pod Topology Spread treats "global minimum" as 0, and then the calculation of Skew is performed. + And when the number of eligible domains with matching topology keys equals or greater than minDomains, + this value has no effect on scheduling. + As a result, when the number of eligible domains is less than minDomains, + scheduler won't schedule more than maxSkew Pods to those domains. + If value is nil, the constraint behaves as if MinDomains is equal to 1. + Valid values are integers greater than 0. + When value is not nil, WhenUnsatisfiable must be DoNotSchedule. + + + For example, in a 3-zone cluster, MaxSkew is set to 2, MinDomains is set to 5 and pods with the same + labelSelector spread as 2/2/2: + | zone1 | zone2 | zone3 | + | P P | P P | P P | + The number of domains is less than 5(MinDomains), so "global minimum" is treated as 0. + In this situation, new pod with the same labelSelector cannot be scheduled, + because computed skew will be 3(3 - 0) if new Pod is scheduled to any of the three zones, + it will violate MaxSkew. + + + This is a beta field and requires the MinDomainsInPodTopologySpread feature gate to be enabled (enabled by default). + format: int32 + type: integer + nodeAffinityPolicy: + description: |- + NodeAffinityPolicy indicates how we will treat Pod's nodeAffinity/nodeSelector + when calculating pod topology spread skew. Options are: + - Honor: only nodes matching nodeAffinity/nodeSelector are included in the calculations. + - Ignore: nodeAffinity/nodeSelector are ignored. All nodes are included in the calculations. + + + If this value is nil, the behavior is equivalent to the Honor policy. + This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag. + type: string + nodeTaintsPolicy: + description: |- + NodeTaintsPolicy indicates how we will treat node taints when calculating + pod topology spread skew. Options are: + - Honor: nodes without taints, along with tainted nodes for which the incoming pod + has a toleration, are included. + - Ignore: node taints are ignored. All nodes are included. + + + If this value is nil, the behavior is equivalent to the Ignore policy. + This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag. + type: string + topologyKey: + description: |- + TopologyKey is the key of node labels. Nodes that have a label with this key + and identical values are considered to be in the same topology. + We consider each as a "bucket", and try to put balanced number + of pods into each bucket. + We define a domain as a particular instance of a topology. + Also, we define an eligible domain as a domain whose nodes meet the requirements of + nodeAffinityPolicy and nodeTaintsPolicy. + e.g. If TopologyKey is "kubernetes.io/hostname", each Node is a domain of that topology. + And, if TopologyKey is "topology.kubernetes.io/zone", each zone is a domain of that topology. + It's a required field. + type: string + whenUnsatisfiable: + description: |- + WhenUnsatisfiable indicates how to deal with a pod if it doesn't satisfy + the spread constraint. + - DoNotSchedule (default) tells the scheduler not to schedule it. + - ScheduleAnyway tells the scheduler to schedule the pod in any location, + but giving higher precedence to topologies that would help reduce the + skew. + A constraint is considered "Unsatisfiable" for an incoming pod + if and only if every possible node assignment for that pod would violate + "MaxSkew" on some topology. + For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same + labelSelector spread as 3/1/1: + | zone1 | zone2 | zone3 | + | P P P | P | P | + If WhenUnsatisfiable is set to DoNotSchedule, incoming pod can only be scheduled + to zone2(zone3) to become 3/2/1(3/1/2) as ActualSkew(2-1) on zone2(zone3) satisfies + MaxSkew(1). In other words, the cluster can still be imbalanced, but scheduler + won't make it *more* imbalanced. + It's a required field. + type: string + required: + - maxSkew + - topologyKey + - whenUnsatisfiable + type: object + type: array + type: object + serviceAccountName: + description: |- + Specifies the name of the ServiceAccount required by the running Component. + This ServiceAccount is used to grant necessary permissions for the Component's Pods to interact + with other Kubernetes resources, such as modifying Pod labels or sending events. + + + Defaults: + If not specified, KubeBlocks automatically assigns a default ServiceAccount named "kb-{cluster.name}", + bound to a default role defined during KubeBlocks installation. + + + Future Changes: + Future versions might change the default ServiceAccount creation strategy to one per Component, + potentially revising the naming to "kb-{cluster.name}-{component.name}". + + + Users can override the automatic ServiceAccount assignment by explicitly setting the name of + an existed ServiceAccount in this field. + type: string + serviceRefs: + description: |- + Defines a list of ServiceRef for a Component, enabling access to both external services and + Services provided by other Clusters. + + + Types of services: + + + - External services: Not managed by KubeBlocks or managed by a different KubeBlocks operator; + Require a ServiceDescriptor for connection details. + - Services provided by a Cluster: Managed by the same KubeBlocks operator; + identified using Cluster, Component and Service names. + + + ServiceRefs with identical `serviceRef.name` in the same Cluster are considered the same. + + + Example: + ```yaml + serviceRefs: + - name: "redis-sentinel" + serviceDescriptor: + name: "external-redis-sentinel" + - name: "postgres-cluster" + clusterServiceSelector: + cluster: "my-postgres-cluster" + service: + component: "postgresql" + ``` + The example above includes ServiceRefs to an external Redis Sentinel service and a PostgreSQL Cluster. + items: + properties: + cluster: + description: |- + Specifies the name of the KubeBlocks Cluster being referenced. + This is used when services from another KubeBlocks Cluster are consumed. + + + By default, the referenced KubeBlocks Cluster's `clusterDefinition.spec.connectionCredential` + will be utilized to bind to the current Component. This credential should include: + `endpoint`, `port`, `username`, and `password`. + + + Note: + + + - The `ServiceKind` and `ServiceVersion` specified in the service reference within the + ClusterDefinition are not validated when using this approach. + - If both `cluster` and `serviceDescriptor` are present, `cluster` will take precedence. + + + Deprecated since v0.9 since `clusterDefinition.spec.connectionCredential` is deprecated, + use `clusterServiceSelector` instead. + This field is maintained for backward compatibility and its use is discouraged. + Existing usage should be updated to the current preferred approach to avoid compatibility issues in future releases. + type: string + clusterServiceSelector: + description: |- + References a service provided by another KubeBlocks Cluster. + It specifies the ClusterService and the account credentials needed for access. + properties: + cluster: + description: The name of the Cluster being referenced. + type: string + credential: + description: |- + Specifies the SystemAccount to authenticate and establish a connection with the referenced Cluster. + The SystemAccount should be defined in `componentDefinition.spec.systemAccounts` + of the Component providing the service in the referenced Cluster. + properties: + component: + description: The name of the Component where the credential + resides in. + type: string + name: + description: The name of the credential (SystemAccount) + to reference. + type: string + required: + - component + - name + type: object + service: + description: Identifies a ClusterService from the list of + Services defined in `cluster.spec.services` of the referenced + Cluster. + properties: + component: + description: |- + The name of the Component where the Service resides in. + + + It is required when referencing a Component's Service. + type: string + port: + description: |- + The port name of the Service to be referenced. + + + If there is a non-zero node-port exist for the matched Service port, the node-port will be selected first. + + + If the referenced Service is of pod-service type (a Service per Pod), there will be multiple Service objects matched, + and the resolved value will be presented in the following format: service1.name:port1,service2.name:port2... + type: string + service: + description: |- + The name of the Service to be referenced. + + + Leave it empty to reference the default Service. Set it to "headless" to reference the default headless Service. + + + If the referenced Service is of pod-service type (a Service per Pod), there will be multiple Service objects matched, + and the resolved value will be presented in the following format: service1.name,service2.name... + type: string + required: + - service + type: object + required: + - cluster + type: object + name: + description: |- + Specifies the identifier of the service reference declaration. + It corresponds to the serviceRefDeclaration name defined in either: + + + - `componentDefinition.spec.serviceRefDeclarations[*].name` + - `clusterDefinition.spec.componentDefs[*].serviceRefDeclarations[*].name` (deprecated) + type: string + namespace: + description: |- + Specifies the namespace of the referenced Cluster or the namespace of the referenced ServiceDescriptor object. + If not provided, the referenced Cluster and ServiceDescriptor will be searched in the namespace of the current + Cluster by default. + type: string + serviceDescriptor: + description: |- + Specifies the name of the ServiceDescriptor object that describes a service provided by external sources. + + + When referencing a service provided by external sources, a ServiceDescriptor object is required to establish + the service binding. + The `serviceDescriptor.spec.serviceKind` and `serviceDescriptor.spec.serviceVersion` should match the serviceKind + and serviceVersion declared in the definition. + + + If both `cluster` and `serviceDescriptor` are specified, the `cluster` takes precedence. + type: string + required: + - name + type: object + type: array + serviceVersion: + description: |- + ServiceVersion specifies the version of the Service expected to be provisioned by this Component. + The version should follow the syntax and semantics of the "Semantic Versioning" specification (http://semver.org/). + maxLength: 32 + type: string + services: + description: |- + Overrides Services defined in referenced ComponentDefinition and exposes endpoints that can be accessed + by clients. + items: + description: |- + ComponentService defines a service that would be exposed as an inter-component service within a Cluster. + A Service defined in the ComponentService is expected to be accessed by other Components within the same Cluster. + + + When a Component needs to use a ComponentService provided by another Component within the same Cluster, + it can declare a variable in the `componentDefinition.spec.vars` section and bind it to the specific exposed address + of the ComponentService using the `serviceVarRef` field. + properties: + annotations: + additionalProperties: + type: string + description: |- + If ServiceType is LoadBalancer, cloud provider related parameters can be put here + More info: https://kubernetes.io/docs/concepts/services-networking/service/#loadbalancer. + type: object + disableAutoProvision: + description: |- + Indicates whether the automatic provisioning of the service should be disabled. + + + If set to true, the service will not be automatically created at the component provisioning. + Instead, you can enable the creation of this service by specifying it explicitly in the cluster API. + type: boolean + name: + description: |- + Name defines the name of the service. + otherwise, it indicates the name of the service. + Others can refer to this service by its name. (e.g., connection credential) + Cannot be updated. + maxLength: 25 + type: string + podService: + default: false + description: |- + Indicates whether to create a corresponding Service for each Pod of the selected Component. + When set to true, a set of Services will be automatically generated for each Pod, + and the `roleSelector` field will be ignored. + + + The names of the generated Services will follow the same suffix naming pattern: `$(serviceName)-$(podOrdinal)`. + The total number of generated Services will be equal to the number of replicas specified for the Component. + + + Example usage: + + + ```yaml + name: my-service + serviceName: my-service + podService: true + disableAutoProvision: true + spec: + type: NodePort + ports: + - name: http + port: 80 + targetPort: 8080 + ``` + + + In this example, if the Component has 3 replicas, three Services will be generated: + - my-service-0: Points to the first Pod (podOrdinal: 0) + - my-service-1: Points to the second Pod (podOrdinal: 1) + - my-service-2: Points to the third Pod (podOrdinal: 2) + + + Each generated Service will have the specified spec configuration and will target its respective Pod. + + + This feature is useful when you need to expose each Pod of a Component individually, allowing external access + to specific instances of the Component. + type: boolean + roleSelector: + description: "Extends the above `serviceSpec.selector` by allowing + you to specify defined role as selector for the service.\nWhen + `roleSelector` is set, it adds a label selector \"kubeblocks.io/role: + {roleSelector}\"\nto the `serviceSpec.selector`.\nExample + usage:\n\n\n\t roleSelector: \"leader\"\n\n\nIn this example, + setting `roleSelector` to \"leader\" will add a label selector\n\"kubeblocks.io/role: + leader\" to the `serviceSpec.selector`.\nThis means that the + service will select and route traffic to Pods with the label\n\"kubeblocks.io/role\" + set to \"leader\".\n\n\nNote that if `podService` sets to + true, RoleSelector will be ignored.\nThe `podService` flag + takes precedence over `roleSelector` and generates a service + for each Pod." + type: string + serviceName: + description: |- + ServiceName defines the name of the underlying service object. + If not specified, the default service name with different patterns will be used: + + + - CLUSTER_NAME: for cluster-level services + - CLUSTER_NAME-COMPONENT_NAME: for component-level services + + + Only one default service name is allowed. + Cannot be updated. + maxLength: 25 + pattern: ^[a-z]([a-z0-9\-]*[a-z0-9])?$ + type: string + spec: + description: |- + Spec defines the behavior of a service. + https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status + properties: + allocateLoadBalancerNodePorts: + description: |- + allocateLoadBalancerNodePorts defines if NodePorts will be automatically + allocated for services with type LoadBalancer. Default is "true". It + may be set to "false" if the cluster load-balancer does not rely on + NodePorts. If the caller requests specific NodePorts (by specifying a + value), those requests will be respected, regardless of this field. + This field may only be set for services with type LoadBalancer and will + be cleared if the type is changed to any other type. + type: boolean + clusterIP: + description: |- + clusterIP is the IP address of the service and is usually assigned + randomly. If an address is specified manually, is in-range (as per + system configuration), and is not in use, it will be allocated to the + service; otherwise creation of the service will fail. This field may not + be changed through updates unless the type field is also being changed + to ExternalName (which requires this field to be blank) or the type + field is being changed from ExternalName (in which case this field may + optionally be specified, as describe above). Valid values are "None", + empty string (""), or a valid IP address. Setting this to "None" makes a + "headless service" (no virtual IP), which is useful when direct endpoint + connections are preferred and proxying is not required. Only applies to + types ClusterIP, NodePort, and LoadBalancer. If this field is specified + when creating a Service of type ExternalName, creation will fail. This + field will be wiped when updating a Service to type ExternalName. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + type: string + clusterIPs: + description: |- + ClusterIPs is a list of IP addresses assigned to this service, and are + usually assigned randomly. If an address is specified manually, is + in-range (as per system configuration), and is not in use, it will be + allocated to the service; otherwise creation of the service will fail. + This field may not be changed through updates unless the type field is + also being changed to ExternalName (which requires this field to be + empty) or the type field is being changed from ExternalName (in which + case this field may optionally be specified, as describe above). Valid + values are "None", empty string (""), or a valid IP address. Setting + this to "None" makes a "headless service" (no virtual IP), which is + useful when direct endpoint connections are preferred and proxying is + not required. Only applies to types ClusterIP, NodePort, and + LoadBalancer. If this field is specified when creating a Service of type + ExternalName, creation will fail. This field will be wiped when updating + a Service to type ExternalName. If this field is not specified, it will + be initialized from the clusterIP field. If this field is specified, + clients must ensure that clusterIPs[0] and clusterIP have the same + value. + + + This field may hold a maximum of two entries (dual-stack IPs, in either order). + These IPs must correspond to the values of the ipFamilies field. Both + clusterIPs and ipFamilies are governed by the ipFamilyPolicy field. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalIPs: + description: |- + externalIPs is a list of IP addresses for which nodes in the cluster + will also accept traffic for this service. These IPs are not managed by + Kubernetes. The user is responsible for ensuring that traffic arrives + at a node with this IP. A common example is external load-balancers + that are not part of the Kubernetes system. + items: + type: string + type: array + externalName: + description: |- + externalName is the external reference that discovery mechanisms will + return as an alias for this service (e.g. a DNS CNAME record). No + proxying will be involved. Must be a lowercase RFC-1123 hostname + (https://tools.ietf.org/html/rfc1123) and requires `type` to be "ExternalName". + type: string + externalTrafficPolicy: + description: |- + externalTrafficPolicy describes how nodes distribute service traffic they + receive on one of the Service's "externally-facing" addresses (NodePorts, + ExternalIPs, and LoadBalancer IPs). If set to "Local", the proxy will configure + the service in a way that assumes that external load balancers will take care + of balancing the service traffic between nodes, and so each node will deliver + traffic only to the node-local endpoints of the service, without masquerading + the client source IP. (Traffic mistakenly sent to a node with no endpoints will + be dropped.) The default value, "Cluster", uses the standard behavior of + routing to all endpoints evenly (possibly modified by topology and other + features). Note that traffic sent to an External IP or LoadBalancer IP from + within the cluster will always get "Cluster" semantics, but clients sending to + a NodePort from within the cluster may need to take traffic policy into account + when picking a node. + type: string + healthCheckNodePort: + description: |- + healthCheckNodePort specifies the healthcheck nodePort for the service. + This only applies when type is set to LoadBalancer and + externalTrafficPolicy is set to Local. If a value is specified, is + in-range, and is not in use, it will be used. If not specified, a value + will be automatically allocated. External systems (e.g. load-balancers) + can use this port to determine if a given node holds endpoints for this + service or not. If this field is specified when creating a Service + which does not need it, creation will fail. This field will be wiped + when updating a Service to no longer need it (e.g. changing type). + This field cannot be updated once set. + format: int32 + type: integer + internalTrafficPolicy: + description: |- + InternalTrafficPolicy describes how nodes distribute service traffic they + receive on the ClusterIP. If set to "Local", the proxy will assume that pods + only want to talk to endpoints of the service on the same node as the pod, + dropping the traffic if there are no local endpoints. The default value, + "Cluster", uses the standard behavior of routing to all endpoints evenly + (possibly modified by topology and other features). + type: string + ipFamilies: + description: |- + IPFamilies is a list of IP families (e.g. IPv4, IPv6) assigned to this + service. This field is usually assigned automatically based on cluster + configuration and the ipFamilyPolicy field. If this field is specified + manually, the requested family is available in the cluster, + and ipFamilyPolicy allows it, it will be used; otherwise creation of + the service will fail. This field is conditionally mutable: it allows + for adding or removing a secondary IP family, but it does not allow + changing the primary IP family of the Service. Valid values are "IPv4" + and "IPv6". This field only applies to Services of types ClusterIP, + NodePort, and LoadBalancer, and does apply to "headless" services. + This field will be wiped when updating a Service to type ExternalName. + + + This field may hold a maximum of two entries (dual-stack families, in + either order). These families must correspond to the values of the + clusterIPs field, if specified. Both clusterIPs and ipFamilies are + governed by the ipFamilyPolicy field. + items: + description: |- + IPFamily represents the IP Family (IPv4 or IPv6). This type is used + to express the family of an IP expressed by a type (e.g. service.spec.ipFamilies). + type: string + type: array + x-kubernetes-list-type: atomic + ipFamilyPolicy: + description: |- + IPFamilyPolicy represents the dual-stack-ness requested or required by + this Service. If there is no value provided, then this field will be set + to SingleStack. Services can be "SingleStack" (a single IP family), + "PreferDualStack" (two IP families on dual-stack configured clusters or + a single IP family on single-stack clusters), or "RequireDualStack" + (two IP families on dual-stack configured clusters, otherwise fail). The + ipFamilies and clusterIPs fields depend on the value of this field. This + field will be wiped when updating a service to type ExternalName. + type: string + loadBalancerClass: + description: |- + loadBalancerClass is the class of the load balancer implementation this Service belongs to. + If specified, the value of this field must be a label-style identifier, with an optional prefix, + e.g. "internal-vip" or "example.com/internal-vip". Unprefixed names are reserved for end-users. + This field can only be set when the Service type is 'LoadBalancer'. If not set, the default load + balancer implementation is used, today this is typically done through the cloud provider integration, + but should apply for any default implementation. If set, it is assumed that a load balancer + implementation is watching for Services with a matching class. Any default load balancer + implementation (e.g. cloud providers) should ignore Services that set this field. + This field can only be set when creating or updating a Service to type 'LoadBalancer'. + Once set, it can not be changed. This field will be wiped when a service is updated to a non 'LoadBalancer' type. + type: string + loadBalancerIP: + description: |- + Only applies to Service Type: LoadBalancer. + This feature depends on whether the underlying cloud-provider supports specifying + the loadBalancerIP when a load balancer is created. + This field will be ignored if the cloud-provider does not support the feature. + Deprecated: This field was under-specified and its meaning varies across implementations. + Using it is non-portable and it may not support dual-stack. + Users are encouraged to use implementation-specific annotations when available. + type: string + loadBalancerSourceRanges: + description: |- + If specified and supported by the platform, this will restrict traffic through the cloud-provider + load-balancer will be restricted to the specified client IPs. This field will be ignored if the + cloud-provider does not support the feature." + More info: https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/ + items: + type: string + type: array + ports: + description: |- + The list of ports that are exposed by this service. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + items: + description: ServicePort contains information on service's + port. + properties: + appProtocol: + description: |- + The application protocol for this port. + This is used as a hint for implementations to offer richer behavior for protocols that they understand. + This field follows standard Kubernetes label syntax. + Valid values are either: + + + * Un-prefixed protocol names - reserved for IANA standard service names (as per + RFC-6335 and https://www.iana.org/assignments/service-names). + + + * Kubernetes-defined prefixed names: + * 'kubernetes.io/h2c' - HTTP/2 prior knowledge over cleartext as described in https://www.rfc-editor.org/rfc/rfc9113.html#name-starting-http-2-with-prior- + * 'kubernetes.io/ws' - WebSocket over cleartext as described in https://www.rfc-editor.org/rfc/rfc6455 + * 'kubernetes.io/wss' - WebSocket over TLS as described in https://www.rfc-editor.org/rfc/rfc6455 + + + * Other protocols should use implementation-defined prefixed names such as + mycompany.com/my-custom-protocol. + type: string + name: + description: |- + The name of this port within the service. This must be a DNS_LABEL. + All ports within a ServiceSpec must have unique names. When considering + the endpoints for a Service, this must match the 'name' field in the + EndpointPort. + Optional if only one ServicePort is defined on this service. + type: string + nodePort: + description: |- + The port on each node on which this service is exposed when type is + NodePort or LoadBalancer. Usually assigned by the system. If a value is + specified, in-range, and not in use it will be used, otherwise the + operation will fail. If not specified, a port will be allocated if this + Service requires one. If this field is specified when creating a + Service which does not need it, creation will fail. This field will be + wiped when updating a Service to no longer need it (e.g. changing type + from NodePort to ClusterIP). + More info: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport + format: int32 + type: integer + port: + description: The port that will be exposed by this + service. + format: int32 + type: integer + protocol: + default: TCP + description: |- + The IP protocol for this port. Supports "TCP", "UDP", and "SCTP". + Default is TCP. + type: string + targetPort: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the pods targeted by the service. + Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + If this is a string, it will be looked up as a named port in the + target Pod's container ports. If this is not specified, the value + of the 'port' field is used (an identity map). + This field is ignored for services with clusterIP=None, and should be + omitted or set equal to the 'port' field. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#defining-a-service + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-map-keys: + - port + - protocol + x-kubernetes-list-type: map + publishNotReadyAddresses: + description: |- + publishNotReadyAddresses indicates that any agent which deals with endpoints for this + Service should disregard any indications of ready/not-ready. + The primary use case for setting this field is for a StatefulSet's Headless Service to + propagate SRV DNS records for its Pods for the purpose of peer discovery. + The Kubernetes controllers that generate Endpoints and EndpointSlice resources for + Services interpret this to mean that all endpoints are considered "ready" even if the + Pods themselves are not. Agents which consume only Kubernetes generated endpoints + through the Endpoints or EndpointSlice resources can safely assume this behavior. + type: boolean + selector: + additionalProperties: + type: string + description: |- + Route service traffic to pods with label keys and values matching this + selector. If empty or not present, the service is assumed to have an + external process managing its endpoints, which Kubernetes will not + modify. Only applies to types ClusterIP, NodePort, and LoadBalancer. + Ignored if type is ExternalName. + More info: https://kubernetes.io/docs/concepts/services-networking/service/ + type: object + x-kubernetes-map-type: atomic + sessionAffinity: + description: |- + Supports "ClientIP" and "None". Used to maintain session affinity. + Enable client IP based session affinity. + Must be ClientIP or None. + Defaults to None. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + type: string + sessionAffinityConfig: + description: sessionAffinityConfig contains the configurations + of session affinity. + properties: + clientIP: + description: clientIP contains the configurations of + Client IP based session affinity. + properties: + timeoutSeconds: + description: |- + timeoutSeconds specifies the seconds of ClientIP type session sticky time. + The value must be >0 && <=86400(for 1 day) if ServiceAffinity == "ClientIP". + Default value is 10800(for 3 hours). + format: int32 + type: integer + type: object + type: object + type: + description: |- + type determines how the Service is exposed. Defaults to ClusterIP. Valid + options are ExternalName, ClusterIP, NodePort, and LoadBalancer. + "ClusterIP" allocates a cluster-internal IP address for load-balancing + to endpoints. Endpoints are determined by the selector or if that is not + specified, by manual construction of an Endpoints object or + EndpointSlice objects. If clusterIP is "None", no virtual IP is + allocated and the endpoints are published as a set of endpoints rather + than a virtual IP. + "NodePort" builds on ClusterIP and allocates a port on every node which + routes to the same endpoints as the clusterIP. + "LoadBalancer" builds on NodePort and creates an external load-balancer + (if supported in the current cloud) which routes to the same endpoints + as the clusterIP. + "ExternalName" aliases this service to the specified externalName. + Several other fields do not apply to ExternalName services. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types + type: string + type: object + required: + - name + type: object + type: array + stop: + description: |- + Stop the Component. + If set, all the computing resources will be released. + type: boolean + systemAccounts: + description: Overrides system accounts defined in referenced ComponentDefinition. + items: + properties: + name: + description: The name of the system account. + type: string + passwordConfig: + description: |- + Specifies the policy for generating the account's password. + + + This field is immutable once set. + properties: + length: + default: 16 + description: The length of the password. + format: int32 + maximum: 32 + minimum: 8 + type: integer + letterCase: + default: MixedCases + description: The case of the letters in the password. + enum: + - LowerCases + - UpperCases + - MixedCases + type: string + numDigits: + default: 4 + description: The number of digits in the password. + format: int32 + maximum: 8 + minimum: 0 + type: integer + numSymbols: + default: 0 + description: The number of symbols in the password. + format: int32 + maximum: 8 + minimum: 0 + type: integer + seed: + description: |- + Seed to generate the account's password. + Cannot be updated. + type: string + type: object + secretRef: + description: |- + Refers to the secret from which data will be copied to create the new account. + + + This field is immutable once set. + properties: + name: + description: The unique identifier of the secret. + type: string + namespace: + description: The namespace where the secret is located. + type: string + required: + - name + - namespace + type: object + required: + - name + type: object + type: array + tlsConfig: + description: "Specifies the TLS configuration for the Component, including:\n\n\n- + A boolean flag that indicates whether the Component should use Transport + Layer Security (TLS) for secure communication.\n- An optional field + that specifies the configuration for the TLS certificates issuer + when TLS is enabled.\n It allows defining the issuer name and the + reference to the secret containing the TLS certificates and key.\n\t + The secret should contain the CA certificate, TLS certificate, and + private key in the specified keys." + properties: + enable: + default: false + description: |- + A boolean flag that indicates whether the Component should use Transport Layer Security (TLS) + for secure communication. + When set to true, the Component will be configured to use TLS encryption for its network connections. + This ensures that the data transmitted between the Component and its clients or other Components is encrypted + and protected from unauthorized access. + If TLS is enabled, the Component may require additional configuration, + such as specifying TLS certificates and keys, to properly set up the secure communication channel. + type: boolean + issuer: + description: |- + Specifies the configuration for the TLS certificates issuer. + It allows defining the issuer name and the reference to the secret containing the TLS certificates and key. + The secret should contain the CA certificate, TLS certificate, and private key in the specified keys. + Required when TLS is enabled. + properties: + name: + allOf: + - enum: + - KubeBlocks + - UserProvided + - enum: + - KubeBlocks + - UserProvided + default: KubeBlocks + description: |- + The issuer for TLS certificates. + It only allows two enum values: `KubeBlocks` and `UserProvided`. + + + - `KubeBlocks` indicates that the self-signed TLS certificates generated by the KubeBlocks Operator will be used. + - `UserProvided` means that the user is responsible for providing their own CA, Cert, and Key. + In this case, the user-provided CA certificate, server certificate, and private key will be used + for TLS communication. + type: string + secretRef: + description: |- + SecretRef is the reference to the secret that contains user-provided certificates. + It is required when the issuer is set to `UserProvided`. + properties: + ca: + description: Key of CA cert in Secret + type: string + cert: + description: Key of Cert in Secret + type: string + key: + description: Key of TLS private key in Secret + type: string + name: + description: Name of the Secret that contains user-provided + certificates. + type: string + required: + - ca + - cert + - key + - name + type: object + required: + - name + type: object + type: object + volumeClaimTemplates: + description: |- + Specifies a list of PersistentVolumeClaim templates that define the storage requirements for the Component. + Each template specifies the desired characteristics of a persistent volume, such as storage class, + size, and access modes. + These templates are used to dynamically provision persistent volumes for the Component. + items: + properties: + name: + description: |- + Refers to the name of a volumeMount defined in either: + + + - `componentDefinition.spec.runtime.containers[*].volumeMounts` + - `clusterDefinition.spec.componentDefs[*].podSpec.containers[*].volumeMounts` (deprecated) + + + The value of `name` must match the `name` field of a volumeMount specified in the corresponding `volumeMounts` array. + type: string + spec: + description: |- + Defines the desired characteristics of a PersistentVolumeClaim that will be created for the volume + with the mount name specified in the `name` field. + + + When a Pod is created for this ClusterComponent, a new PVC will be created based on the specification + defined in the `spec` field. The PVC will be associated with the volume mount specified by the `name` field. + properties: + accessModes: + description: |- + Contains the desired access modes the volume should have. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1. + items: + type: string + type: array + x-kubernetes-preserve-unknown-fields: true + resources: + description: |- + Represents the minimum resources the volume should have. + If the RecoverVolumeExpansionFailure feature is enabled, users are allowed to specify resource requirements that + are lower than the previous value but must still be higher than the capacity recorded in the status field of the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources. + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + x-kubernetes-preserve-unknown-fields: true + storageClassName: + description: |- + The name of the StorageClass required by the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1. + type: string + volumeMode: + description: Defines what type of volume is required by + the claim, either Block or Filesystem. + type: string + type: object + required: + - name + type: object + type: array + volumes: + description: List of volumes to override. + items: + description: Volume represents a named volume in a pod that may + be accessed by any container in the pod. + properties: + awsElasticBlockStore: + description: |- + awsElasticBlockStore represents an AWS Disk resource that is attached to a + kubelet's host machine and then exposed to the pod. + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + properties: + fsType: + description: |- + fsType is the filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + partition: + description: |- + partition is the partition in the volume that you want to mount. + If omitted, the default is to mount by volume name. + Examples: For volume /dev/sda1, you specify the partition as "1". + Similarly, the volume partition for /dev/sda is "0" (or you can leave the property empty). + format: int32 + type: integer + readOnly: + description: |- + readOnly value true will force the readOnly setting in VolumeMounts. + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + type: boolean + volumeID: + description: |- + volumeID is unique ID of the persistent disk resource in AWS (Amazon EBS volume). + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + type: string + required: + - volumeID + type: object + azureDisk: + description: azureDisk represents an Azure Data Disk mount on + the host and bind mount to the pod. + properties: + cachingMode: + description: 'cachingMode is the Host Caching mode: None, + Read Only, Read Write.' + type: string + diskName: + description: diskName is the Name of the data disk in the + blob storage + type: string + diskURI: + description: diskURI is the URI of data disk in the blob + storage + type: string + fsType: + description: |- + fsType is Filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + kind: + description: 'kind expected values are Shared: multiple + blob disks per storage account Dedicated: single blob + disk per storage account Managed: azure managed data + disk (only in managed availability set). defaults to shared' + type: string + readOnly: + description: |- + readOnly Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + description: azureFile represents an Azure File Service mount + on the host and bind mount to the pod. + properties: + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretName: + description: secretName is the name of secret that contains + Azure Storage Account Name and Key + type: string + shareName: + description: shareName is the azure share Name + type: string + required: + - secretName + - shareName + type: object + cephfs: + description: cephFS represents a Ceph FS mount on the host that + shares a pod's lifetime + properties: + monitors: + description: |- + monitors is Required: Monitors is a collection of Ceph monitors + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + items: + type: string + type: array + path: + description: 'path is Optional: Used as the mounted root, + rather than the full Ceph tree, default is /' + type: string + readOnly: + description: |- + readOnly is Optional: Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + type: boolean + secretFile: + description: |- + secretFile is Optional: SecretFile is the path to key ring for User, default is /etc/ceph/user.secret + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + type: string + secretRef: + description: |- + secretRef is Optional: SecretRef is reference to the authentication secret for User, default is empty. + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + 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 + user: + description: |- + user is optional: User is the rados user name, default is admin + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + type: string + required: + - monitors + type: object + cinder: + description: |- + cinder represents a cinder volume attached and mounted on kubelets host machine. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + type: string + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + type: boolean + secretRef: + description: |- + secretRef is optional: points to a secret object containing parameters used to connect + to OpenStack. + 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 + volumeID: + description: |- + volumeID used to identify the volume in cinder. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + type: string + required: + - volumeID + type: object + configMap: + description: configMap represents a configMap that should populate + this volume + properties: + defaultMode: + description: |- + defaultMode is optional: mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + items: + description: |- + items if unspecified, each key-value pair in the Data field of the referenced + ConfigMap will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the ConfigMap, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + 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 + optional: + description: optional specify whether the ConfigMap or its + keys must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + csi: + description: csi (Container Storage Interface) represents ephemeral + storage that is handled by certain external CSI drivers (Beta + feature). + properties: + driver: + description: |- + driver is the name of the CSI driver that handles this volume. + Consult with your admin for the correct name as registered in the cluster. + type: string + fsType: + description: |- + fsType to mount. Ex. "ext4", "xfs", "ntfs". + If not provided, the empty value is passed to the associated CSI driver + which will determine the default filesystem to apply. + type: string + nodePublishSecretRef: + description: |- + nodePublishSecretRef is a reference to the secret object containing + sensitive information to pass to the CSI driver to complete the CSI + NodePublishVolume and NodeUnpublishVolume calls. + This field is optional, and may be empty if no secret is required. If the + secret object contains more than one secret, all secret references are passed. + 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 + readOnly: + description: |- + readOnly specifies a read-only configuration for the volume. + Defaults to false (read/write). + type: boolean + volumeAttributes: + additionalProperties: + type: string + description: |- + volumeAttributes stores driver-specific properties that are passed to the CSI + driver. Consult your driver's documentation for supported values. + type: object + required: + - driver + type: object + downwardAPI: + description: downwardAPI represents downward API about the pod + that should populate this volume + properties: + defaultMode: + description: |- + Optional: mode bits to use on created files by default. Must be a + Optional: mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + items: + description: Items is a list of downward API volume file + items: + description: DownwardAPIVolumeFile represents information + to create the file containing the pod field + properties: + fieldRef: + description: 'Required: Selects a field of the pod: + only annotations, labels, name and namespace are + supported.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the + specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + description: |- + Optional: mode bits used to set permissions on this file, must be an octal value + between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: 'Required: Path is the relative path + name of the file to be created. Must not be absolute + or contain the ''..'' path. Must be utf-8 encoded. + The first item of the relative path must not start + with ''..''' + type: string + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported. + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the + exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + type: object + emptyDir: + description: |- + emptyDir represents a temporary directory that shares a pod's lifetime. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir + properties: + medium: + description: |- + medium represents what type of storage medium should back this directory. + The default is "" which means to use the node's default medium. + Must be an empty string (default) or Memory. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + description: |- + sizeLimit is the total amount of local storage required for this EmptyDir volume. + The size limit is also applicable for memory medium. + The maximum usage on memory medium EmptyDir would be the minimum value between + the SizeLimit specified here and the sum of memory limits of all containers in a pod. + The default is nil which means that the limit is undefined. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + description: |- + ephemeral represents a volume that is handled by a cluster storage driver. + The volume's lifecycle is tied to the pod that defines it - it will be created before the pod starts, + and deleted when the pod is removed. + + + Use this if: + a) the volume is only needed while the pod runs, + b) features of normal volumes like restoring from snapshot or capacity + tracking are needed, + c) the storage driver is specified through a storage class, and + d) the storage driver supports dynamic volume provisioning through + a PersistentVolumeClaim (see EphemeralVolumeSource for more + information on the connection between this volume type + and PersistentVolumeClaim). + + + Use PersistentVolumeClaim or one of the vendor-specific + APIs for volumes that persist for longer than the lifecycle + of an individual pod. + + + Use CSI for light-weight local ephemeral volumes if the CSI driver is meant to + be used that way - see the documentation of the driver for + more information. + + + A pod can use both types of ephemeral volumes and + persistent volumes at the same time. + properties: + volumeClaimTemplate: + description: |- + Will be used to create a stand-alone PVC to provision the volume. + The pod in which this EphemeralVolumeSource is embedded will be the + owner of the PVC, i.e. the PVC will be deleted together with the + pod. The name of the PVC will be `-` where + `` is the name from the `PodSpec.Volumes` array + entry. Pod validation will reject the pod if the concatenated name + is not valid for a PVC (for example, too long). + + + An existing PVC with that name that is not owned by the pod + will *not* be used for the pod to avoid using an unrelated + volume by mistake. Starting the pod is then blocked until + the unrelated PVC is removed. If such a pre-created PVC is + meant to be used by the pod, the PVC has to updated with an + owner reference to the pod once the pod exists. Normally + this should not be necessary, but it may be useful when + manually reconstructing a broken cluster. + + + This field is read-only and no changes will be made by Kubernetes + to the PVC after it has been created. + + + Required, must not be nil. + properties: + metadata: + description: |- + May contain labels and annotations that will be copied into the PVC + when creating it. No other fields are allowed and will be rejected during + validation. + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + description: |- + The specification for the PersistentVolumeClaim. The entire content is + copied unchanged into the PVC that gets created from this + template. The same fields as in a PersistentVolumeClaim + are also valid here. + properties: + accessModes: + description: |- + accessModes contains the desired access modes the volume should have. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1 + items: + type: string + type: array + dataSource: + description: |- + dataSource field can be used to specify either: + * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) + * An existing PVC (PersistentVolumeClaim) + If the provisioner or an external controller can support the specified data source, + it will create a new volume based on the contents of the specified data source. + When the AnyVolumeDataSource feature gate is enabled, dataSource contents will be copied to dataSourceRef, + and dataSourceRef contents will be copied to dataSource when dataSourceRef.namespace is not specified. + If the namespace is specified, then dataSourceRef will not be copied to dataSource. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being + referenced + type: string + name: + description: Name is the name of resource being + referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + description: |- + dataSourceRef specifies the object from which to populate the volume with data, if a non-empty + volume is desired. This may be any object from a non-empty API group (non + core object) or a PersistentVolumeClaim object. + When this field is specified, volume binding will only succeed if the type of + the specified object matches some installed volume populator or dynamic + provisioner. + This field will replace the functionality of the dataSource field and as such + if both fields are non-empty, they must have the same value. For backwards + compatibility, when namespace isn't specified in dataSourceRef, + both fields (dataSource and dataSourceRef) will be set to the same + value automatically if one of them is empty and the other is non-empty. + When namespace is specified in dataSourceRef, + dataSource isn't set to the same value and must be empty. + There are three important differences between dataSource and dataSourceRef: + * While dataSource only allows two specific types of objects, dataSourceRef + allows any non-core object, as well as PersistentVolumeClaim objects. + * While dataSource ignores disallowed values (dropping them), dataSourceRef + preserves all values, and generates an error if a disallowed value is + specified. + * While dataSource only allows local objects, dataSourceRef allows objects + in any namespaces. + (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled. + (Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being + referenced + type: string + name: + description: Name is the name of resource being + referenced + type: string + namespace: + description: |- + Namespace is the namespace of resource being referenced + Note that when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details. + (Alpha) This field requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + type: string + required: + - kind + - name + type: object + resources: + description: |- + resources represents the minimum resources the volume should have. + If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements + that are lower than previous value but must still be higher than capacity recorded in the + status field of the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + selector: + description: selector is a label query over volumes + to consider for binding. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + description: |- + storageClassName is the name of the StorageClass required by the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1 + type: string + volumeAttributesClassName: + description: |- + volumeAttributesClassName may be used to set the VolumeAttributesClass used by this claim. + If specified, the CSI driver will create or update the volume with the attributes defined + in the corresponding VolumeAttributesClass. This has a different purpose than storageClassName, + it can be changed after the claim is created. An empty string value means that no VolumeAttributesClass + will be applied to the claim but it's not allowed to reset this field to empty string once it is set. + If unspecified and the PersistentVolumeClaim is unbound, the default VolumeAttributesClass + will be set by the persistentvolume controller if it exists. + If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be + set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource + exists. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#volumeattributesclass + (Alpha) Using this field requires the VolumeAttributesClass feature gate to be enabled. + type: string + volumeMode: + description: |- + volumeMode defines what type of volume is required by the claim. + Value of Filesystem is implied when not included in claim spec. + type: string + volumeName: + description: volumeName is the binding reference + to the PersistentVolume backing this claim. + type: string + type: object + required: + - spec + type: object + type: object + fc: + description: fc represents a Fibre Channel resource that is + attached to a kubelet's host machine and then exposed to the + pod. + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + lun: + description: 'lun is Optional: FC target lun number' + format: int32 + type: integer + readOnly: + description: |- + readOnly is Optional: Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + targetWWNs: + description: 'targetWWNs is Optional: FC target worldwide + names (WWNs)' + items: + type: string + type: array + wwids: + description: |- + wwids Optional: FC volume world wide identifiers (wwids) + Either wwids or combination of targetWWNs and lun must be set, but not both simultaneously. + items: + type: string + type: array + type: object + flexVolume: + description: |- + flexVolume represents a generic volume resource that is + provisioned/attached using an exec based plugin. + properties: + driver: + description: driver is the name of the driver to use for + this volume. + type: string + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". The default filesystem depends on FlexVolume script. + type: string + options: + additionalProperties: + type: string + description: 'options is Optional: this field holds extra + command options if any.' + type: object + readOnly: + description: |- + readOnly is Optional: defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: |- + secretRef is Optional: secretRef is reference to the secret object containing + sensitive information to pass to the plugin scripts. This may be + empty if no secret object is specified. If the secret object + contains more than one secret, all secrets are passed to the plugin + scripts. + 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 + required: + - driver + type: object + flocker: + description: flocker represents a Flocker volume attached to + a kubelet's host machine. This depends on the Flocker control + service being running + properties: + datasetName: + description: |- + datasetName is Name of the dataset stored as metadata -> name on the dataset for Flocker + should be considered as deprecated + type: string + datasetUUID: + description: datasetUUID is the UUID of the dataset. This + is unique identifier of a Flocker dataset + type: string + type: object + gcePersistentDisk: + description: |- + gcePersistentDisk represents a GCE Disk resource that is attached to a + kubelet's host machine and then exposed to the pod. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + properties: + fsType: + description: |- + fsType is filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + partition: + description: |- + partition is the partition in the volume that you want to mount. + If omitted, the default is to mount by volume name. + Examples: For volume /dev/sda1, you specify the partition as "1". + Similarly, the volume partition for /dev/sda is "0" (or you can leave the property empty). + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + format: int32 + type: integer + pdName: + description: |- + pdName is unique name of the PD resource in GCE. Used to identify the disk in GCE. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + type: string + readOnly: + description: |- + readOnly here will force the ReadOnly setting in VolumeMounts. + Defaults to false. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + type: boolean + required: + - pdName + type: object + gitRepo: + description: |- + gitRepo represents a git repository at a particular revision. + DEPRECATED: GitRepo is deprecated. To provision a container with a git repo, mount an + EmptyDir into an InitContainer that clones the repo using git, then mount the EmptyDir + into the Pod's container. + properties: + directory: + description: |- + directory is the target directory name. + Must not contain or start with '..'. If '.' is supplied, the volume directory will be the + git repository. Otherwise, if specified, the volume will contain the git repository in + the subdirectory with the given name. + type: string + repository: + description: repository is the URL + type: string + revision: + description: revision is the commit hash for the specified + revision. + type: string + required: + - repository + type: object + glusterfs: + description: |- + glusterfs represents a Glusterfs mount on the host that shares a pod's lifetime. + More info: https://examples.k8s.io/volumes/glusterfs/README.md + properties: + endpoints: + description: |- + endpoints is the endpoint name that details Glusterfs topology. + More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod + type: string + path: + description: |- + path is the Glusterfs volume path. + More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod + type: string + readOnly: + description: |- + readOnly here will force the Glusterfs volume to be mounted with read-only permissions. + Defaults to false. + More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod + type: boolean + required: + - endpoints + - path + type: object + hostPath: + description: |- + hostPath represents a pre-existing file or directory on the host + machine that is directly exposed to the container. This is generally + used for system agents or other privileged things that are allowed + to see the host machine. Most containers will NOT need this. + More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + --- + TODO(jonesdl) We need to restrict who can use host directory mounts and who can/can not + mount host directories as read/write. + properties: + path: + description: |- + path of the directory on the host. + If the path is a symlink, it will follow the link to the real path. + More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + type: string + type: + description: |- + type for HostPath Volume + Defaults to "" + More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + type: string + required: + - path + type: object + iscsi: + description: |- + iscsi represents an ISCSI Disk resource that is attached to a + kubelet's host machine and then exposed to the pod. + More info: https://examples.k8s.io/volumes/iscsi/README.md + properties: + chapAuthDiscovery: + description: chapAuthDiscovery defines whether support iSCSI + Discovery CHAP authentication + type: boolean + chapAuthSession: + description: chapAuthSession defines whether support iSCSI + Session CHAP authentication + type: boolean + fsType: + description: |- + fsType is the filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#iscsi + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + initiatorName: + description: |- + initiatorName is the custom iSCSI Initiator Name. + If initiatorName is specified with iscsiInterface simultaneously, new iSCSI interface + : will be created for the connection. + type: string + iqn: + description: iqn is the target iSCSI Qualified Name. + type: string + iscsiInterface: + description: |- + iscsiInterface is the interface Name that uses an iSCSI transport. + Defaults to 'default' (tcp). + type: string + lun: + description: lun represents iSCSI Target Lun number. + format: int32 + type: integer + portals: + description: |- + portals is the iSCSI Target Portal List. The portal is either an IP or ip_addr:port if the port + is other than default (typically TCP ports 860 and 3260). + items: + type: string + type: array + readOnly: + description: |- + readOnly here will force the ReadOnly setting in VolumeMounts. + Defaults to false. + type: boolean + secretRef: + description: secretRef is the CHAP Secret for iSCSI target + and initiator authentication + 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 + targetPortal: + description: |- + targetPortal is iSCSI Target Portal. The Portal is either an IP or ip_addr:port if the port + is other than default (typically TCP ports 860 and 3260). + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + description: |- + name of the volume. + Must be a DNS_LABEL and unique within the pod. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + nfs: + description: |- + nfs represents an NFS mount on the host that shares a pod's lifetime + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + properties: + path: + description: |- + path that is exported by the NFS server. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + type: string + readOnly: + description: |- + readOnly here will force the NFS export to be mounted with read-only permissions. + Defaults to false. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + type: boolean + server: + description: |- + server is the hostname or IP address of the NFS server. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + description: |- + persistentVolumeClaimVolumeSource represents a reference to a + PersistentVolumeClaim in the same namespace. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims + properties: + claimName: + description: |- + claimName is the name of a PersistentVolumeClaim in the same namespace as the pod using this volume. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims + type: string + readOnly: + description: |- + readOnly Will force the ReadOnly setting in VolumeMounts. + Default false. + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + description: photonPersistentDisk represents a PhotonController + persistent disk attached and mounted on kubelets host machine + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + pdID: + description: pdID is the ID that identifies Photon Controller + persistent disk + type: string + required: + - pdID + type: object + portworxVolume: + description: portworxVolume represents a portworx volume attached + and mounted on kubelets host machine + properties: + fsType: + description: |- + fSType represents the filesystem type to mount + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs". Implicitly inferred to be "ext4" if unspecified. + type: string + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + volumeID: + description: volumeID uniquely identifies a Portworx volume + type: string + required: + - volumeID + type: object + projected: + description: projected items for all in one resources secrets, + configmaps, and downward API + properties: + defaultMode: + description: |- + defaultMode are the mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + sources: + description: sources is the list of volume projections + items: + description: Projection that may be projected along with + other supported volume types + properties: + clusterTrustBundle: + description: |- + ClusterTrustBundle allows a pod to access the `.spec.trustBundle` field + of ClusterTrustBundle objects in an auto-updating file. + + + Alpha, gated by the ClusterTrustBundleProjection feature gate. + + + ClusterTrustBundle objects can either be selected by name, or by the + combination of signer name and a label selector. + + + Kubelet performs aggressive normalization of the PEM contents written + into the pod filesystem. Esoteric PEM features such as inter-block + comments and block headers are stripped. Certificates are deduplicated. + The ordering of certificates within the file is arbitrary, and Kubelet + may change the order over time. + properties: + labelSelector: + description: |- + Select all ClusterTrustBundles that match this label selector. Only has + effect if signerName is set. Mutually-exclusive with name. If unset, + interpreted as "match nothing". If set but empty, interpreted as "match + everything". + properties: + matchExpressions: + description: matchExpressions is a list of + label selector requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + name: + description: |- + Select a single ClusterTrustBundle by object name. Mutually-exclusive + with signerName and labelSelector. + type: string + optional: + description: |- + If true, don't block pod startup if the referenced ClusterTrustBundle(s) + aren't available. If using name, then the named ClusterTrustBundle is + allowed not to exist. If using signerName, then the combination of + signerName and labelSelector is allowed to match zero + ClusterTrustBundles. + type: boolean + path: + description: Relative path from the volume root + to write the bundle. + type: string + signerName: + description: |- + Select all ClusterTrustBundles that match this signer name. + Mutually-exclusive with name. The contents of all selected + ClusterTrustBundles will be unified and deduplicated. + type: string + required: + - path + type: object + configMap: + description: configMap information about the configMap + data to project + properties: + items: + description: |- + items if unspecified, each key-value pair in the Data field of the referenced + ConfigMap will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the ConfigMap, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within + a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + 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 + optional: + description: optional specify whether the ConfigMap + or its keys must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + downwardAPI: + description: downwardAPI information about the downwardAPI + data to project + properties: + items: + description: Items is a list of DownwardAPIVolume + file + items: + description: DownwardAPIVolumeFile represents + information to create the file containing + the pod field + properties: + fieldRef: + description: 'Required: Selects a field + of the pod: only annotations, labels, + name and namespace are supported.' + properties: + apiVersion: + description: Version of the schema the + FieldPath is written in terms of, + defaults to "v1". + type: string + fieldPath: + description: Path of the field to select + in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + description: |- + Optional: mode bits used to set permissions on this file, must be an octal value + between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: 'Required: Path is the relative + path name of the file to be created. Must + not be absolute or contain the ''..'' + path. Must be utf-8 encoded. The first + item of the relative path must not start + with ''..''' + type: string + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported. + properties: + containerName: + description: 'Container name: required + for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format + of the exposed resources, defaults + to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to + select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + type: object + secret: + description: secret information about the secret data + to project + properties: + items: + description: |- + items if unspecified, each key-value pair in the Data field of the referenced + Secret will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the Secret, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within + a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + 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 + optional: + description: optional field specify whether the + Secret or its key must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + serviceAccountToken: + description: serviceAccountToken is information about + the serviceAccountToken data to project + properties: + audience: + description: |- + audience is the intended audience of the token. A recipient of a token + must identify itself with an identifier specified in the audience of the + token, and otherwise should reject the token. The audience defaults to the + identifier of the apiserver. + type: string + expirationSeconds: + description: |- + expirationSeconds is the requested duration of validity of the service + account token. As the token approaches expiration, the kubelet volume + plugin will proactively rotate the service account token. The kubelet will + start trying to rotate the token if the token is older than 80 percent of + its time to live or if the token is older than 24 hours.Defaults to 1 hour + and must be at least 10 minutes. + format: int64 + type: integer + path: + description: |- + path is the path relative to the mount point of the file to project the + token into. + type: string + required: + - path + type: object + type: object + type: array + type: object + quobyte: + description: quobyte represents a Quobyte mount on the host + that shares a pod's lifetime + properties: + group: + description: |- + group to map volume access to + Default is no group + type: string + readOnly: + description: |- + readOnly here will force the Quobyte volume to be mounted with read-only permissions. + Defaults to false. + type: boolean + registry: + description: |- + registry represents a single or multiple Quobyte Registry services + specified as a string as host:port pair (multiple entries are separated with commas) + which acts as the central registry for volumes + type: string + tenant: + description: |- + tenant owning the given Quobyte volume in the Backend + Used with dynamically provisioned Quobyte volumes, value is set by the plugin + type: string + user: + description: |- + user to map volume access to + Defaults to serivceaccount user + type: string + volume: + description: volume is a string that references an already + created Quobyte volume by name. + type: string + required: + - registry + - volume + type: object + rbd: + description: |- + rbd represents a Rados Block Device mount on the host that shares a pod's lifetime. + More info: https://examples.k8s.io/volumes/rbd/README.md + properties: + fsType: + description: |- + fsType is the filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#rbd + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + image: + description: |- + image is the rados image name. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + keyring: + description: |- + keyring is the path to key ring for RBDUser. + Default is /etc/ceph/keyring. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + monitors: + description: |- + monitors is a collection of Ceph monitors. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + items: + type: string + type: array + pool: + description: |- + pool is the rados pool name. + Default is rbd. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + readOnly: + description: |- + readOnly here will force the ReadOnly setting in VolumeMounts. + Defaults to false. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: boolean + secretRef: + description: |- + secretRef is name of the authentication secret for RBDUser. If provided + overrides keyring. + Default is nil. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + 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 + user: + description: |- + user is the rados user name. + Default is admin. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + required: + - image + - monitors + type: object + scaleIO: + description: scaleIO represents a ScaleIO persistent volume + attached and mounted on Kubernetes nodes. + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". + Default is "xfs". + type: string + gateway: + description: gateway is the host address of the ScaleIO + API Gateway. + type: string + protectionDomain: + description: protectionDomain is the name of the ScaleIO + Protection Domain for the configured storage. + type: string + readOnly: + description: |- + readOnly Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: |- + secretRef references to the secret for ScaleIO user and other + sensitive information. If this is not provided, Login operation will fail. + 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 + sslEnabled: + description: sslEnabled Flag enable/disable SSL communication + with Gateway, default false + type: boolean + storageMode: + description: |- + storageMode indicates whether the storage for a volume should be ThickProvisioned or ThinProvisioned. + Default is ThinProvisioned. + type: string + storagePool: + description: storagePool is the ScaleIO Storage Pool associated + with the protection domain. + type: string + system: + description: system is the name of the storage system as + configured in ScaleIO. + type: string + volumeName: + description: |- + volumeName is the name of a volume already created in the ScaleIO system + that is associated with this volume source. + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + description: |- + secret represents a secret that should populate this volume. + More info: https://kubernetes.io/docs/concepts/storage/volumes#secret + properties: + defaultMode: + description: |- + defaultMode is Optional: mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values + for mode bits. Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + items: + description: |- + items If unspecified, each key-value pair in the Data field of the referenced + Secret will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the Secret, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + optional: + description: optional field specify whether the Secret or + its keys must be defined + type: boolean + secretName: + description: |- + secretName is the name of the secret in the pod's namespace to use. + More info: https://kubernetes.io/docs/concepts/storage/volumes#secret + type: string + type: object + storageos: + description: storageOS represents a StorageOS volume attached + and mounted on Kubernetes nodes. + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: |- + secretRef specifies the secret to use for obtaining the StorageOS API + credentials. If not specified, default values will be attempted. + 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 + volumeName: + description: |- + volumeName is the human-readable name of the StorageOS volume. Volume + names are only unique within a namespace. + type: string + volumeNamespace: + description: |- + volumeNamespace specifies the scope of the volume within StorageOS. If no + namespace is specified then the Pod's namespace will be used. This allows the + Kubernetes name scoping to be mirrored within StorageOS for tighter integration. + Set VolumeName to any name to override the default behaviour. + Set to "default" if you are not using namespaces within StorageOS. + Namespaces that do not pre-exist within StorageOS will be created. + type: string + type: object + vsphereVolume: + description: vsphereVolume represents a vSphere volume attached + and mounted on kubelets host machine + properties: + fsType: + description: |- + fsType is filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + storagePolicyID: + description: storagePolicyID is the storage Policy Based + Management (SPBM) profile ID associated with the StoragePolicyName. + type: string + storagePolicyName: + description: storagePolicyName is the storage Policy Based + Management (SPBM) profile name. + type: string + volumePath: + description: volumePath is the path that identifies vSphere + volume vmdk + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + required: + - compDef + - replicas type: object status: - description: ComponentStatus defines the observed state of Component + description: ComponentStatus represents the observed state of a Component + within the Cluster. + properties: + conditions: + description: |- + Represents a list of detailed status of the Component object. + Each condition in the list provides real-time information about certain aspect of the Component object. + + + This field is crucial for administrators and developers to monitor and respond to changes within the Component. + It provides a history of state transitions and a snapshot of the current state that can be used for + automated logic or direct inspection. + items: + description: "Condition contains details for one aspect of the current + state of this API Resource.\n---\nThis struct is intended for + direct use as an array at the field path .status.conditions. For + example,\n\n\n\ttype FooStatus struct{\n\t // Represents the + observations of a foo's current state.\n\t // Known .status.conditions.type + are: \"Available\", \"Progressing\", and \"Degraded\"\n\t // + +patchMergeKey=type\n\t // +patchStrategy=merge\n\t // +listType=map\n\t + \ // +listMapKey=type\n\t Conditions []metav1.Condition `json:\"conditions,omitempty\" + patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t + \ // other fields\n\t}" + 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 + message: + additionalProperties: + type: string + description: |- + A map that stores detailed message about the Component. + Each entry in the map provides insights into specific elements of the Component, such as Pods or workloads. + + + Keys in this map are formatted as `ObjectKind/Name`, where `ObjectKind` could be a type like Pod, + and `Name` is the specific name of the object. + type: object + observedGeneration: + description: Specifies the most recent generation observed for this + Component object. + format: int64 + type: integer + phase: + description: |- + Indicates the current phase of the Component, with each phase indicating specific conditions: + + + - Creating: The initial phase for new Components, transitioning from 'empty'(""). + - Running: All Pods in a Running state. + - Updating: The Component is currently being updated, with no failed Pods present. + - Abnormal: Some Pods have failed, indicating a potentially unstable state. + However, the cluster remains available as long as a quorum of members is functioning. + - Failed: A significant number of Pods or critical Pods have failed + The cluster may be non-functional or may offer only limited services (e.g, read-only). + - Stopping: All Pods are being terminated, with current replica count at zero. + - Stopped: All associated Pods have been successfully deleted. + - Deleting: The Component is being deleted. + enum: + - Creating + - Running + - Updating + - Stopping + - Stopped + - Deleting + - Failed + - Abnormal + type: string type: object type: object served: true diff --git a/config/crd/bases/apps.kubeblocks.io_servicedescriptors.yaml b/config/crd/bases/apps.kubeblocks.io_servicedescriptors.yaml index 3b84dcb3e59..99d33d9eaff 100644 --- a/config/crd/bases/apps.kubeblocks.io_servicedescriptors.yaml +++ b/config/crd/bases/apps.kubeblocks.io_servicedescriptors.yaml @@ -11,6 +11,7 @@ spec: names: categories: - kubeblocks + - all kind: ServiceDescriptor listKind: ServiceDescriptorList plural: servicedescriptors diff --git a/controllers/apps/cluster_controller_test.go b/controllers/apps/cluster_controller_test.go index 0b1df57a5cf..9a317944cab 100644 --- a/controllers/apps/cluster_controller_test.go +++ b/controllers/apps/cluster_controller_test.go @@ -61,7 +61,7 @@ var _ = Describe("Cluster Controller", func() { var ( clusterDefObj *appsv1.ClusterDefinition - compDefObj *appsv1alpha1.ComponentDefinition + compDefObj *appsv1.ComponentDefinition compVersionObj *appsv1.ComponentVersion clusterObj *appsv1alpha1.Cluster clusterKey types.NamespacedName @@ -182,9 +182,9 @@ var _ = Describe("Cluster Controller", func() { By("Wait objects available") Eventually(testapps.CheckObj(&testCtx, client.ObjectKeyFromObject(compDefObj), - func(g Gomega, compDef *appsv1alpha1.ComponentDefinition) { + func(g Gomega, compDef *appsv1.ComponentDefinition) { g.Expect(compDef.Status.ObservedGeneration).Should(Equal(compDef.Generation)) - g.Expect(compDef.Status.Phase).Should(Equal(appsv1alpha1.AvailablePhase)) + g.Expect(compDef.Status.Phase).Should(Equal(appsv1.AvailablePhase)) })).Should(Succeed()) Eventually(testapps.CheckObj(&testCtx, client.ObjectKeyFromObject(compVersionObj), func(g Gomega, compVersion *appsv1.ComponentVersion) { @@ -271,7 +271,7 @@ var _ = Describe("Cluster Controller", func() { Namespace: clusterObj.Namespace, Name: constant.GenerateClusterComponentName(clusterObj.Name, compName), } - Eventually(testapps.CheckObjExists(&testCtx, compKey, &appsv1alpha1.Component{}, true)).Should(Succeed()) + Eventually(testapps.CheckObjExists(&testCtx, compKey, &appsv1.Component{}, true)).Should(Succeed()) } createClusterObjWithTopology := func(topology, compName string, processor func(*testapps.MockClusterFactory)) { @@ -288,7 +288,7 @@ var _ = Describe("Cluster Controller", func() { Namespace: clusterObj.Namespace, Name: constant.GenerateClusterComponentName(clusterObj.Name, compName), } - Eventually(testapps.CheckObjExists(&testCtx, compKey, &appsv1alpha1.Component{}, true)).Should(Succeed()) + Eventually(testapps.CheckObjExists(&testCtx, compKey, &appsv1.Component{}, true)).Should(Succeed()) } createClusterObjWithSharding := func(compTplName, compDefName string, processor func(*testapps.MockClusterFactory)) { @@ -334,7 +334,7 @@ var _ = Describe("Cluster Controller", func() { Namespace: clusterObj.Namespace, Name: constant.GenerateClusterComponentName(clusterObj.Name, compName), } - compObj := &appsv1alpha1.Component{} + compObj := &appsv1.Component{} Eventually(testapps.CheckObjExists(&testCtx, compKey, compObj, true)).Should(Succeed()) Eventually(testapps.CheckObj(&testCtx, clusterKey, func(g Gomega, cluster *appsv1alpha1.Cluster) { @@ -355,7 +355,7 @@ var _ = Describe("Cluster Controller", func() { Namespace: clusterObj.Namespace, Name: constant.GenerateClusterComponentName(clusterObj.Name, compName), } - Eventually(testapps.CheckObj(&testCtx, compKey, func(g Gomega, comp *appsv1alpha1.Component) { + Eventually(testapps.CheckObj(&testCtx, compKey, func(g Gomega, comp *appsv1.Component) { g.Expect(comp.Generation).Should(BeEquivalentTo(1)) for k, v := range constant.GetComponentWellKnownLabels(clusterObj.Name, compName) { g.Expect(comp.Labels).Should(HaveKeyWithValue(k, v)) @@ -391,7 +391,7 @@ var _ = Describe("Cluster Controller", func() { Namespace: clusterObj.Namespace, Name: constant.GenerateClusterComponentName(clusterObj.Name, compName), } - Eventually(testapps.CheckObj(&testCtx, compKey, func(g Gomega, comp *appsv1alpha1.Component) { + Eventually(testapps.CheckObj(&testCtx, compKey, func(g Gomega, comp *appsv1.Component) { g.Expect(comp.Spec.CompDef).Should(Equal(expectedCompDef)) g.Expect(comp.Spec.ServiceVersion).Should(Equal(expectedServiceVersion)) })).Should(Succeed()) @@ -442,8 +442,8 @@ var _ = Describe("Cluster Controller", func() { Namespace: clusterObj.Namespace, Name: constant.GenerateClusterComponentName(clusterObj.Name, otherCompName), } - Eventually(testapps.CheckObjExists(&testCtx, compKey, &appsv1alpha1.Component{}, false)).Should(Succeed()) - Eventually(testapps.CheckObjExists(&testCtx, multiCompKey, &appsv1alpha1.Component{}, true)).Should(Succeed()) + Eventually(testapps.CheckObjExists(&testCtx, compKey, &appsv1.Component{}, false)).Should(Succeed()) + Eventually(testapps.CheckObjExists(&testCtx, multiCompKey, &appsv1.Component{}, true)).Should(Succeed()) Eventually(testapps.CheckObjExists(&testCtx, clusterKey, &appsv1alpha1.Cluster{}, true)).Should(Succeed()) } @@ -562,9 +562,7 @@ var _ = Describe("Cluster Controller", func() { Namespace: clusterObj.Namespace, Name: component.FullName(clusterObj.Name, compName), } - Eventually(testapps.CheckObj(&testCtx, compKey, func(g Gomega, comp *appsv1alpha1.Component) { - g.Expect(comp.Spec.Affinity).Should(BeNil()) - g.Expect(comp.Spec.Tolerations).Should(HaveLen(0)) + Eventually(testapps.CheckObj(&testCtx, compKey, func(g Gomega, comp *appsv1.Component) { g.Expect(comp.Spec.SchedulingPolicy).ShouldNot(BeNil()) g.Expect(comp.Spec.SchedulingPolicy.Affinity).Should(BeEquivalentTo(schedulingPolicy.Affinity)) g.Expect(comp.Spec.SchedulingPolicy.Tolerations).Should(HaveLen(2)) @@ -635,9 +633,7 @@ var _ = Describe("Cluster Controller", func() { Namespace: clusterObj.Namespace, Name: component.FullName(clusterObj.Name, compName), } - Eventually(testapps.CheckObj(&testCtx, compKey, func(g Gomega, comp *appsv1alpha1.Component) { - g.Expect(comp.Spec.Affinity).Should(BeNil()) - g.Expect(comp.Spec.Tolerations).Should(HaveLen(0)) + Eventually(testapps.CheckObj(&testCtx, compKey, func(g Gomega, comp *appsv1.Component) { g.Expect(comp.Spec.SchedulingPolicy).ShouldNot(BeNil()) g.Expect(comp.Spec.SchedulingPolicy.Affinity).Should(BeEquivalentTo(schedulingPolicy.Affinity)) g.Expect(comp.Spec.SchedulingPolicy.Tolerations).Should(HaveLen(2)) @@ -855,11 +851,11 @@ var _ = Describe("Cluster Controller", func() { Namespace: clusterKey.Namespace, Name: clusterKey.Name + "-" + compName, } - Eventually(testapps.CheckObjExists(&testCtx, compKey, &appsv1alpha1.Component{}, true)).Should(Succeed()) + Eventually(testapps.CheckObjExists(&testCtx, compKey, &appsv1.Component{}, true)).Should(Succeed()) By("set finalizer for component to prevent it from deletion") finalizer := "test/finalizer" - Expect(testapps.GetAndChangeObj(&testCtx, compKey, func(comp *appsv1alpha1.Component) { + Expect(testapps.GetAndChangeObj(&testCtx, compKey, func(comp *appsv1.Component) { comp.Finalizers = append(comp.Finalizers, finalizer) })()).ShouldNot(HaveOccurred()) @@ -870,12 +866,12 @@ var _ = Describe("Cluster Controller", func() { Consistently(testapps.CheckObjExists(&testCtx, clusterKey, &appsv1alpha1.Cluster{}, true)).Should(Succeed()) By("remove finalizer of component to get it deleted") - Expect(testapps.GetAndChangeObj(&testCtx, compKey, func(comp *appsv1alpha1.Component) { + Expect(testapps.GetAndChangeObj(&testCtx, compKey, func(comp *appsv1.Component) { comp.Finalizers = nil })()).ShouldNot(HaveOccurred()) By("wait for the cluster and component to terminate") - Eventually(testapps.CheckObjExists(&testCtx, compKey, &appsv1alpha1.Component{}, false)).Should(Succeed()) + Eventually(testapps.CheckObjExists(&testCtx, compKey, &appsv1.Component{}, false)).Should(Succeed()) Eventually(testapps.CheckObjExists(&testCtx, clusterKey, &appsv1alpha1.Cluster{}, false)).Should(Succeed()) } @@ -1348,7 +1344,7 @@ var _ = Describe("Cluster Controller", func() { g.Expect(cluster.Spec.ComponentSpecs[0].ComponentDef).Should(Equal(compDefObj.Name)) g.Expect(cluster.Spec.ComponentSpecs[0].ServiceVersion).Should(Equal(latestServiceVersion)) })).Should(Succeed()) - Eventually(testapps.CheckObj(&testCtx, compKey, func(g Gomega, comp *appsv1alpha1.Component) { + Eventually(testapps.CheckObj(&testCtx, compKey, func(g Gomega, comp *appsv1.Component) { g.Expect(comp.Spec.CompDef).Should(Equal(compDefObj.Name)) g.Expect(comp.Spec.ServiceVersion).Should(Equal(latestServiceVersion)) })).Should(Succeed()) @@ -1366,9 +1362,9 @@ var _ = Describe("Cluster Controller", func() { AddEnv(compDefObj.Spec.Runtime.Containers[0].Name, corev1.EnvVar{Name: "key", Value: "value"}). Create(&testCtx). GetObject() - Eventually(testapps.CheckObj(&testCtx, client.ObjectKeyFromObject(newCompDefObj), func(g Gomega, compDef *appsv1alpha1.ComponentDefinition) { + Eventually(testapps.CheckObj(&testCtx, client.ObjectKeyFromObject(newCompDefObj), func(g Gomega, compDef *appsv1.ComponentDefinition) { g.Expect(compDef.Status.ObservedGeneration).Should(Equal(compDef.Generation)) - g.Expect(compDef.Status.Phase).Should(Equal(appsv1alpha1.AvailablePhase)) + g.Expect(compDef.Status.Phase).Should(Equal(appsv1.AvailablePhase)) })).Should(Succeed()) By("check cluster and component objects stay in original version before upgrading") @@ -1380,7 +1376,7 @@ var _ = Describe("Cluster Controller", func() { g.Expect(cluster.Spec.ComponentSpecs[0].ComponentDef).Should(Equal(compDefObj.Name)) g.Expect(cluster.Spec.ComponentSpecs[0].ServiceVersion).Should(Equal(defaultServiceVersion)) })).Should(Succeed()) - Consistently(testapps.CheckObj(&testCtx, compKey, func(g Gomega, comp *appsv1alpha1.Component) { + Consistently(testapps.CheckObj(&testCtx, compKey, func(g Gomega, comp *appsv1.Component) { g.Expect(comp.Spec.CompDef).Should(Equal(compDefObj.Name)) g.Expect(comp.Spec.ServiceVersion).Should(Equal(defaultServiceVersion)) })).Should(Succeed()) @@ -1395,7 +1391,7 @@ var _ = Describe("Cluster Controller", func() { g.Expect(cluster.Spec.ComponentSpecs[0].ComponentDef).Should(Equal(newCompDefObj.Name)) g.Expect(cluster.Spec.ComponentSpecs[0].ServiceVersion).Should(Equal(defaultServiceVersion)) })).Should(Succeed()) - Eventually(testapps.CheckObj(&testCtx, compKey, func(g Gomega, comp *appsv1alpha1.Component) { + Eventually(testapps.CheckObj(&testCtx, compKey, func(g Gomega, comp *appsv1.Component) { g.Expect(comp.Spec.CompDef).Should(Equal(newCompDefObj.Name)) g.Expect(comp.Spec.ServiceVersion).Should(Equal(defaultServiceVersion)) })).Should(Succeed()) diff --git a/controllers/apps/cluster_plan_builder.go b/controllers/apps/cluster_plan_builder.go index 629fde35c70..4c75e260c6a 100644 --- a/controllers/apps/cluster_plan_builder.go +++ b/controllers/apps/cluster_plan_builder.go @@ -57,7 +57,7 @@ type clusterTransformContext struct { Cluster *appsv1alpha1.Cluster OrigCluster *appsv1alpha1.Cluster ClusterDef *appsv1.ClusterDefinition - ComponentDefs map[string]*appsv1alpha1.ComponentDefinition + ComponentDefs map[string]*appsv1.ComponentDefinition // ComponentSpecs includes all cluster component specs generated from ComponentSpecs and ShardingSpecs ComponentSpecs []*appsv1alpha1.ClusterComponentSpec // ShardingComponentSpecs includes all sharding component specs generated from ShardingSpecs diff --git a/controllers/apps/clusterdefinition_controller.go b/controllers/apps/clusterdefinition_controller.go index 40eac709ec6..500589949c7 100644 --- a/controllers/apps/clusterdefinition_controller.go +++ b/controllers/apps/clusterdefinition_controller.go @@ -227,20 +227,20 @@ func (r *ClusterDefinitionReconciler) validateTopologyOrders(topology appsv1.Clu } func (r *ClusterDefinitionReconciler) loadTopologyCompDefs(ctx context.Context, - topology appsv1.ClusterTopology) (map[string][]*appsv1alpha1.ComponentDefinition, error) { - compDefList := &appsv1alpha1.ComponentDefinitionList{} + topology appsv1.ClusterTopology) (map[string][]*appsv1.ComponentDefinition, error) { + compDefList := &appsv1.ComponentDefinitionList{} if err := r.Client.List(ctx, compDefList); err != nil { return nil, err } - compDefs := map[string]*appsv1alpha1.ComponentDefinition{} + compDefs := map[string]*appsv1.ComponentDefinition{} for i, item := range compDefList.Items { compDefs[item.Name] = &compDefList.Items[i] } - result := make(map[string][]*appsv1alpha1.ComponentDefinition) + result := make(map[string][]*appsv1.ComponentDefinition) for _, comp := range topology.Components { - defs := make([]*appsv1alpha1.ComponentDefinition, 0) + defs := make([]*appsv1.ComponentDefinition, 0) for compDefName := range compDefs { if strings.HasPrefix(compDefName, comp.CompDef) { defs = append(defs, compDefs[compDefName]) @@ -251,7 +251,7 @@ func (r *ClusterDefinitionReconciler) loadTopologyCompDefs(ctx context.Context, return result, nil } -func (r *ClusterDefinitionReconciler) validateTopologyComponent(compDefs map[string][]*appsv1alpha1.ComponentDefinition, +func (r *ClusterDefinitionReconciler) validateTopologyComponent(compDefs map[string][]*appsv1.ComponentDefinition, comp appsv1.ClusterTopologyComponent) error { defs, ok := compDefs[comp.Name] if !ok || len(defs) == 0 { diff --git a/controllers/apps/clusterdefinition_controller_test.go b/controllers/apps/clusterdefinition_controller_test.go index ada1811244e..e9e09dc1fc3 100644 --- a/controllers/apps/clusterdefinition_controller_test.go +++ b/controllers/apps/clusterdefinition_controller_test.go @@ -28,7 +28,6 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" intctrlutil "github.com/apecloud/kubeblocks/pkg/generics" testapps "github.com/apecloud/kubeblocks/pkg/testutil/apps" ) @@ -116,9 +115,9 @@ var _ = Describe("ClusterDefinition Controller", func() { AddServiceRef("service-2", "service-2", "v2"). Create(&testCtx). GetObject() - Eventually(testapps.CheckObj(&testCtx, client.ObjectKeyFromObject(compDefObj), func(g Gomega, compDef *appsv1alpha1.ComponentDefinition) { + Eventually(testapps.CheckObj(&testCtx, client.ObjectKeyFromObject(compDefObj), func(g Gomega, compDef *appsv1.ComponentDefinition) { g.Expect(compDef.Status.ObservedGeneration).Should(Equal(compDef.Generation)) - g.Expect(compDef.Status.Phase).Should(Equal(appsv1alpha1.AvailablePhase)) + g.Expect(compDef.Status.Phase).Should(Equal(appsv1.AvailablePhase)) })).Should(Succeed()) By("Create a ClusterDefinition obj") diff --git a/controllers/apps/component_controller_test.go b/controllers/apps/component_controller_test.go index 66256a35d90..359e7a8f3bd 100644 --- a/controllers/apps/component_controller_test.go +++ b/controllers/apps/component_controller_test.go @@ -136,11 +136,11 @@ var _ = Describe("Component Controller", func() { ) var ( - compDefObj *appsv1alpha1.ComponentDefinition + compDefObj *kbappsv1.ComponentDefinition compVerObj *kbappsv1.ComponentVersion clusterObj *appsv1alpha1.Cluster clusterKey types.NamespacedName - compObj *appsv1alpha1.Component + compObj *kbappsv1.Component compKey types.NamespacedName allSettings map[string]interface{} ) @@ -257,11 +257,11 @@ var _ = Describe("Component Controller", func() { Namespace: clusterObj.Namespace, Name: component.FullName(clusterObj.Name, compName), } - compObj = &appsv1alpha1.Component{} + compObj = &kbappsv1.Component{} Eventually(testapps.CheckObjExists(&testCtx, compKey, compObj, true)).Should(Succeed()) if phase == nil { Eventually(testapps.GetComponentObservedGeneration(&testCtx, compKey)).Should(BeEquivalentTo(1)) - Eventually(testapps.GetComponentPhase(&testCtx, compKey)).Should(Equal(appsv1alpha1.CreatingClusterCompPhase)) + Eventually(testapps.GetComponentPhase(&testCtx, compKey)).Should(Equal(kbappsv1.CreatingClusterCompPhase)) } } @@ -304,7 +304,7 @@ var _ = Describe("Component Controller", func() { // compObj = factory.Create(&testCtx).GetObject() // compKey = client.ObjectKeyFromObject(compObj) // - // Eventually(testapps.CheckObj(&testCtx, compKey, func(g Gomega, comp *appsv1alpha1.Component) { + // Eventually(testapps.CheckObj(&testCtx, compKey, func(g Gomega, comp *kbappsv1.Component) { // g.Expect(comp.Status.ObservedGeneration).To(BeEquivalentTo(comp.Generation)) // g.Expect(comp.Status.Phase).To(Equal(appsv1alpha1.CreatingClusterCompPhase)) // })).Should(Succeed()) @@ -363,12 +363,12 @@ var _ = Describe("Component Controller", func() { changeComponentReplicas(clusterKey, target) By("checking the number of replicas in component as expected") - Eventually(testapps.CheckObj(&testCtx, compKey, func(g Gomega, comp *appsv1alpha1.Component) { + Eventually(testapps.CheckObj(&testCtx, compKey, func(g Gomega, comp *kbappsv1.Component) { g.Expect(comp.Spec.Replicas).Should(Equal(target)) })).Should(Succeed()) By("checking the component status can't be reconciled well") - Eventually(testapps.CheckObj(&testCtx, compKey, func(g Gomega, comp *appsv1alpha1.Component) { + Eventually(testapps.CheckObj(&testCtx, compKey, func(g Gomega, comp *kbappsv1.Component) { g.Expect(comp.Generation > comp.Status.ObservedGeneration).Should(BeTrue()) })).Should(Succeed()) @@ -387,8 +387,8 @@ var _ = Describe("Component Controller", func() { By("set min replicas limit to 0") compDefKey := client.ObjectKeyFromObject(compDefObj) - Eventually(testapps.GetAndChangeObj(&testCtx, compDefKey, func(compDef *appsv1alpha1.ComponentDefinition) { - compDef.Spec.ReplicasLimit = &appsv1alpha1.ReplicasLimit{ + Eventually(testapps.GetAndChangeObj(&testCtx, compDefKey, func(compDef *kbappsv1.ComponentDefinition) { + compDef.Spec.ReplicasLimit = &kbappsv1.ReplicasLimit{ MinReplicas: 0, MaxReplicas: 5, } @@ -402,7 +402,7 @@ var _ = Describe("Component Controller", func() { changeComponentReplicas(clusterKey, target) By("checking the number of replicas in component as expected") - Eventually(testapps.CheckObj(&testCtx, compKey, func(g Gomega, comp *appsv1alpha1.Component) { + Eventually(testapps.CheckObj(&testCtx, compKey, func(g Gomega, comp *kbappsv1.Component) { g.Expect(comp.Spec.Replicas).Should(Equal(target)) g.Expect(comp.Generation).Should(Equal(comp.Status.ObservedGeneration)) })).Should(Succeed()) @@ -683,7 +683,7 @@ var _ = Describe("Component Controller", func() { By(fmt.Sprintf("set HorizontalScalePolicy as %s", bptName)) for _, compDefName := range compDefNames { Expect(testapps.GetAndChangeObj(&testCtx, types.NamespacedName{Name: compDefName}, - func(compDef *appsv1alpha1.ComponentDefinition) { + func(compDef *kbappsv1.ComponentDefinition) { if compDef.Annotations == nil { compDef.Annotations = map[string]string{} } @@ -711,7 +711,7 @@ var _ = Describe("Component Controller", func() { } bpt := func(comp appsv1alpha1.ClusterComponentSpec) *string { - compDef := &appsv1alpha1.ComponentDefinition{} + compDef := &kbappsv1.ComponentDefinition{} Expect(k8sClient.Get(testCtx.Ctx, types.NamespacedName{Name: comp.ComponentDef}, compDef)).Should(Succeed()) if len(compDef.Annotations) > 0 { template, ok := compDef.Annotations[constant.HorizontalScaleBackupPolicyTemplateKey] @@ -749,7 +749,7 @@ var _ = Describe("Component Controller", func() { horizontalScale(int(updatedReplicas), testk8s.DefaultStorageClassName, bpt, compDefName) } - testVolumeExpansion := func(compDef *appsv1alpha1.ComponentDefinition, compName string, storageClass *storagev1.StorageClass) { + testVolumeExpansion := func(compDef *kbappsv1.ComponentDefinition, compName string, storageClass *storagev1.StorageClass) { var ( replicas = 3 volumeSize = "1Gi" @@ -999,7 +999,7 @@ var _ = Describe("Component Controller", func() { createClusterObj(compName, compDefName, nil) By("check component finalizers and labels") - Eventually(testapps.CheckObj(&testCtx, compKey, func(g Gomega, comp *appsv1alpha1.Component) { + Eventually(testapps.CheckObj(&testCtx, compKey, func(g Gomega, comp *kbappsv1.Component) { // g.Expect(comp.Finalizers).Should(ContainElements(constant.DBComponentFinalizerName)) g.Expect(comp.Finalizers).Should(ContainElements(constant.DBClusterFinalizerName)) g.Expect(comp.Labels).Should(HaveKeyWithValue(constant.AppManagedByLabelKey, constant.AppName)) @@ -1075,7 +1075,7 @@ var _ = Describe("Component Controller", func() { mockCompRunning(compName) By("wait accounts to be provisioned") - Eventually(testapps.CheckObj(&testCtx, compKey, func(g Gomega, comp *appsv1alpha1.Component) { + Eventually(testapps.CheckObj(&testCtx, compKey, func(g Gomega, comp *kbappsv1.Component) { g.Expect(len(comp.Status.Conditions) > 0).Should(BeTrue()) var cond *metav1.Condition for i, c := range comp.Status.Conditions { @@ -1142,56 +1142,56 @@ var _ = Describe("Component Controller", func() { testCompVars := func(compName, compDefName string) { compDefKey := client.ObjectKeyFromObject(compDefObj) - Eventually(testapps.GetAndChangeObj(&testCtx, compDefKey, func(compDef *appsv1alpha1.ComponentDefinition) { - compDef.Spec.Vars = []appsv1alpha1.EnvVar{ + Eventually(testapps.GetAndChangeObj(&testCtx, compDefKey, func(compDef *kbappsv1.ComponentDefinition) { + compDef.Spec.Vars = []kbappsv1.EnvVar{ { Name: "SERVICE_HOST", - ValueFrom: &appsv1alpha1.VarSource{ - ServiceVarRef: &appsv1alpha1.ServiceVarSelector{ - ClusterObjectReference: appsv1alpha1.ClusterObjectReference{ + ValueFrom: &kbappsv1.VarSource{ + ServiceVarRef: &kbappsv1.ServiceVarSelector{ + ClusterObjectReference: kbappsv1.ClusterObjectReference{ Name: compDefObj.Spec.Services[0].Name, }, - ServiceVars: appsv1alpha1.ServiceVars{ - Host: &appsv1alpha1.VarRequired, + ServiceVars: kbappsv1.ServiceVars{ + Host: &kbappsv1.VarRequired, }, }, }, }, { Name: "SERVICE_PORT", - ValueFrom: &appsv1alpha1.VarSource{ - ServiceVarRef: &appsv1alpha1.ServiceVarSelector{ - ClusterObjectReference: appsv1alpha1.ClusterObjectReference{ + ValueFrom: &kbappsv1.VarSource{ + ServiceVarRef: &kbappsv1.ServiceVarSelector{ + ClusterObjectReference: kbappsv1.ClusterObjectReference{ Name: compDefObj.Spec.Services[0].Name, }, - ServiceVars: appsv1alpha1.ServiceVars{ - Port: &appsv1alpha1.NamedVar{}, + ServiceVars: kbappsv1.ServiceVars{ + Port: &kbappsv1.NamedVar{}, }, }, }, }, { Name: "USERNAME", - ValueFrom: &appsv1alpha1.VarSource{ - CredentialVarRef: &appsv1alpha1.CredentialVarSelector{ - ClusterObjectReference: appsv1alpha1.ClusterObjectReference{ + ValueFrom: &kbappsv1.VarSource{ + CredentialVarRef: &kbappsv1.CredentialVarSelector{ + ClusterObjectReference: kbappsv1.ClusterObjectReference{ Name: compDefObj.Spec.SystemAccounts[0].Name, }, - CredentialVars: appsv1alpha1.CredentialVars{ - Username: &appsv1alpha1.VarRequired, + CredentialVars: kbappsv1.CredentialVars{ + Username: &kbappsv1.VarRequired, }, }, }, }, { Name: "PASSWORD", - ValueFrom: &appsv1alpha1.VarSource{ - CredentialVarRef: &appsv1alpha1.CredentialVarSelector{ - ClusterObjectReference: appsv1alpha1.ClusterObjectReference{ + ValueFrom: &kbappsv1.VarSource{ + CredentialVarRef: &kbappsv1.CredentialVarSelector{ + ClusterObjectReference: kbappsv1.ClusterObjectReference{ Name: compDefObj.Spec.SystemAccounts[0].Name, }, - CredentialVars: appsv1alpha1.CredentialVars{ - Password: &appsv1alpha1.VarRequired, + CredentialVars: kbappsv1.CredentialVars{ + Password: &kbappsv1.VarRequired, }, }, }, @@ -1362,7 +1362,7 @@ var _ = Describe("Component Controller", func() { } testCompReplicasLimit := func(compName, compDefName string) { - replicasLimit := &appsv1alpha1.ReplicasLimit{ + replicasLimit := &kbappsv1.ReplicasLimit{ MinReplicas: 4, MaxReplicas: 16, } @@ -1380,7 +1380,7 @@ var _ = Describe("Component Controller", func() { By("set replicas limit") compDefKey := client.ObjectKeyFromObject(compDefObj) - Eventually(testapps.GetAndChangeObj(&testCtx, compDefKey, func(compDef *appsv1alpha1.ComponentDefinition) { + Eventually(testapps.GetAndChangeObj(&testCtx, compDefKey, func(compDef *kbappsv1.ComponentDefinition) { compDef.Spec.ReplicasLimit = replicasLimit })).Should(Succeed()) @@ -1389,10 +1389,10 @@ var _ = Describe("Component Controller", func() { createClusterObjWithPhase(compName, compDefName, func(f *testapps.MockClusterFactory) { f.SetReplicas(replicas) }, "") - Eventually(testapps.CheckObj(&testCtx, compKey, func(g Gomega, comp *appsv1alpha1.Component) { + Eventually(testapps.CheckObj(&testCtx, compKey, func(g Gomega, comp *kbappsv1.Component) { g.Expect(comp.Spec.Replicas).Should(BeEquivalentTo(replicas)) g.Expect(comp.Status.Conditions).Should(HaveLen(1)) - g.Expect(comp.Status.Conditions[0].Type).Should(BeEquivalentTo(appsv1alpha1.ConditionTypeProvisioningStarted)) + g.Expect(comp.Status.Conditions[0].Type).Should(BeEquivalentTo(kbappsv1.ConditionTypeProvisioningStarted)) g.Expect(comp.Status.Conditions[0].Status).Should(BeEquivalentTo(metav1.ConditionFalse)) g.Expect(comp.Status.Conditions[0].Message).Should(ContainSubstring(replicasOutOfLimitError(replicas, *replicasLimit).Error())) })).Should(Succeed()) @@ -1578,7 +1578,7 @@ var _ = Describe("Component Controller", func() { testCompRBAC := func(compName, compDefName, saName string) { By("update comp definition to enable volume protection") - Expect(testapps.GetAndChangeObj(&testCtx, client.ObjectKeyFromObject(compDefObj), func(compDef *appsv1alpha1.ComponentDefinition) { + Expect(testapps.GetAndChangeObj(&testCtx, client.ObjectKeyFromObject(compDefObj), func(compDef *kbappsv1.ComponentDefinition) { for i, vol := range compDef.Spec.Volumes { if vol.HighWatermark <= 0 || vol.HighWatermark >= 100 { compDef.Spec.Volumes[i].HighWatermark = 85 @@ -1762,7 +1762,7 @@ var _ = Describe("Component Controller", func() { Should(Equal(appsv1alpha1.RunningClusterCompPhase)) } - testRestoreClusterFromBackup := func(compName string, compDef *appsv1alpha1.ComponentDefinition) { + testRestoreClusterFromBackup := func(compName string, compDef *kbappsv1.ComponentDefinition) { By("mock backuptool object") backupPolicyName := "test-backup-policy" backupName := "test-backup" @@ -1882,21 +1882,21 @@ var _ = Describe("Component Controller", func() { viper.Set(constant.KBToolsImage, newToolsImage) By("update component annotation to trigger component status reconcile") - Expect(testapps.GetAndChangeObj(&testCtx, compKey, func(comp *appsv1alpha1.Component) { + Expect(testapps.GetAndChangeObj(&testCtx, compKey, func(comp *kbappsv1.Component) { comp.Annotations = map[string]string{"time": time.Now().Format(time.RFC3339)} })()).Should(Succeed()) checkWorkloadGenerationAndToolsImage(Consistently, initWorkloadGeneration, 1, 0) By("update spec to trigger component spec reconcile, but workload not changed") - Expect(testapps.GetAndChangeObj(&testCtx, compKey, func(comp *appsv1alpha1.Component) { - comp.Spec.ServiceRefs = []appsv1alpha1.ServiceRef{ + Expect(testapps.GetAndChangeObj(&testCtx, compKey, func(comp *kbappsv1.Component) { + comp.Spec.ServiceRefs = []kbappsv1.ServiceRef{ {Name: randomStr()}, // set a non-existed reference. } })()).Should(Succeed()) checkWorkloadGenerationAndToolsImage(Consistently, initWorkloadGeneration, 1, 0) By("update replicas to trigger component spec and workload reconcile") - Expect(testapps.GetAndChangeObj(&testCtx, compKey, func(comp *appsv1alpha1.Component) { + Expect(testapps.GetAndChangeObj(&testCtx, compKey, func(comp *kbappsv1.Component) { comp.Spec.Replicas += 1 })()).Should(Succeed()) checkWorkloadGenerationAndToolsImage(Eventually, initWorkloadGeneration+2, 0, 1) @@ -1928,7 +1928,7 @@ var _ = Describe("Component Controller", func() { }) By("check component inherit clusters labels and annotations") - Eventually(testapps.CheckObj(&testCtx, compKey, func(g Gomega, comp *appsv1alpha1.Component) { + Eventually(testapps.CheckObj(&testCtx, compKey, func(g Gomega, comp *kbappsv1.Component) { g.Expect(comp.Labels).Should(HaveKeyWithValue(customLabelKey, customLabelValue)) g.Expect(comp.Labels).ShouldNot(HaveKeyWithValue(customLabelKeyBeFiltered, customLabelValueBeFiltered)) g.Expect(comp.Annotations).Should(HaveKeyWithValue(customAnnotationKey, customAnnotationValue)) @@ -1961,7 +1961,7 @@ var _ = Describe("Component Controller", func() { createClusterObjX("", defaultCompName, compDefName, zeroReplicas, &phase) By("checking the component status can't be reconciled well") - Eventually(testapps.CheckObj(&testCtx, compKey, func(g Gomega, comp *appsv1alpha1.Component) { + Eventually(testapps.CheckObj(&testCtx, compKey, func(g Gomega, comp *kbappsv1.Component) { g.Expect(comp.Generation > comp.Status.ObservedGeneration).Should(BeTrue()) })).Should(Succeed()) }) @@ -2184,7 +2184,7 @@ var _ = Describe("Component Controller", func() { } checkCompRunningAs := func(phase appsv1alpha1.ClusterComponentPhase) { - Eventually(testapps.CheckObj(&testCtx, compKey, func(g Gomega, comp *appsv1alpha1.Component) { + Eventually(testapps.CheckObj(&testCtx, compKey, func(g Gomega, comp *kbappsv1.Component) { g.Expect(comp.Status.ObservedGeneration).To(BeEquivalentTo(comp.Generation)) if comp.Spec.Stop != nil { g.Expect(*comp.Spec.Stop).Should(BeFalse()) @@ -2207,11 +2207,11 @@ var _ = Describe("Component Controller", func() { } checkCompStopped := func() { - Eventually(testapps.CheckObj(&testCtx, compKey, func(g Gomega, comp *appsv1alpha1.Component) { + Eventually(testapps.CheckObj(&testCtx, compKey, func(g Gomega, comp *kbappsv1.Component) { g.Expect(comp.Status.ObservedGeneration).To(BeEquivalentTo(comp.Generation)) g.Expect(comp.Spec.Stop).ShouldNot(BeNil()) g.Expect(*comp.Spec.Stop).Should(BeTrue()) - g.Expect(comp.Status.Phase).Should(Equal(appsv1alpha1.StoppedClusterCompPhase)) + g.Expect(comp.Status.Phase).Should(Equal(kbappsv1.StoppedClusterCompPhase)) })).Should(Succeed()) itsKey := compKey @@ -2264,10 +2264,10 @@ var _ = Describe("Component Controller", func() { changeCompReplicas(clusterKey, 3, &clusterObj.Spec.ComponentSpecs[0]) By("check comp & its") - Eventually(testapps.CheckObj(&testCtx, compKey, func(g Gomega, comp *appsv1alpha1.Component) { + Eventually(testapps.CheckObj(&testCtx, compKey, func(g Gomega, comp *kbappsv1.Component) { g.Expect(comp.Spec.Replicas).Should(Equal(3)) g.Expect(comp.Status.ObservedGeneration < comp.Generation).Should(BeTrue()) - g.Expect(comp.Status.Phase).Should(Equal(appsv1alpha1.StoppedClusterCompPhase)) + g.Expect(comp.Status.Phase).Should(Equal(kbappsv1.StoppedClusterCompPhase)) })) itsKey := compKey Consistently(testapps.CheckObj(&testCtx, itsKey, func(g Gomega, its *workloads.InstanceSet) { @@ -2278,10 +2278,10 @@ var _ = Describe("Component Controller", func() { startComp() By("check comp & its") - Eventually(testapps.CheckObj(&testCtx, compKey, func(g Gomega, comp *appsv1alpha1.Component) { + Eventually(testapps.CheckObj(&testCtx, compKey, func(g Gomega, comp *kbappsv1.Component) { g.Expect(comp.Spec.Replicas).Should(Equal(3)) g.Expect(comp.Status.ObservedGeneration).Should(Equal(comp.Generation)) - g.Expect(comp.Status.Phase).Should(Equal(appsv1alpha1.UpdatingClusterCompPhase)) + g.Expect(comp.Status.Phase).Should(Equal(kbappsv1.UpdatingClusterCompPhase)) })) Eventually(testapps.CheckObj(&testCtx, itsKey, func(g Gomega, its *workloads.InstanceSet) { @@ -2332,7 +2332,7 @@ var _ = Describe("Component Controller", func() { By("trigger component reconcile") now := time.Now().Format(time.RFC3339) - Expect(testapps.GetAndChangeObj(&testCtx, compKey, func(comp *appsv1alpha1.Component) { + Expect(testapps.GetAndChangeObj(&testCtx, compKey, func(comp *kbappsv1.Component) { comp.Annotations["now"] = now })()).Should(Succeed()) diff --git a/controllers/apps/component_plan_builder.go b/controllers/apps/component_plan_builder.go index dd9a66f919b..1b6ac6224a5 100644 --- a/controllers/apps/component_plan_builder.go +++ b/controllers/apps/component_plan_builder.go @@ -30,6 +30,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" "github.com/apecloud/kubeblocks/pkg/constant" "github.com/apecloud/kubeblocks/pkg/controller/component" @@ -46,9 +47,9 @@ type componentTransformContext struct { record.EventRecorder logr.Logger Cluster *appsv1alpha1.Cluster - CompDef *appsv1alpha1.ComponentDefinition - Component *appsv1alpha1.Component - ComponentOrig *appsv1alpha1.Component + CompDef *appsv1.ComponentDefinition + Component *appsv1.Component + ComponentOrig *appsv1.Component SynthesizeComponent *component.SynthesizedComponent RunningWorkload client.Object ProtoWorkload client.Object diff --git a/controllers/apps/componentdefinition_controller.go b/controllers/apps/componentdefinition_controller.go index 88b1f9caaac..38256bf0873 100644 --- a/controllers/apps/componentdefinition_controller.go +++ b/controllers/apps/componentdefinition_controller.go @@ -37,7 +37,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/log" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsconfig "github.com/apecloud/kubeblocks/controllers/apps/configuration" "github.com/apecloud/kubeblocks/pkg/constant" intctrlutil "github.com/apecloud/kubeblocks/pkg/controllerutil" @@ -73,7 +73,7 @@ func (r *ComponentDefinitionReconciler) Reconcile(ctx context.Context, req ctrl. rctx.Log.V(1).Info("reconcile", "component", req.NamespacedName) - cmpd := &appsv1alpha1.ComponentDefinition{} + cmpd := &appsv1.ComponentDefinition{} if err := r.Client.Get(rctx.Ctx, rctx.Req.NamespacedName, cmpd); err != nil { return intctrlutil.CheckedRequeueWithError(err, rctx.Log, "") } @@ -84,19 +84,19 @@ func (r *ComponentDefinitionReconciler) Reconcile(ctx context.Context, req ctrl. // SetupWithManager sets up the controller with the Manager. func (r *ComponentDefinitionReconciler) SetupWithManager(mgr ctrl.Manager) error { return intctrlutil.NewNamespacedControllerManagedBy(mgr). - For(&appsv1alpha1.ComponentDefinition{}). + For(&appsv1.ComponentDefinition{}). Complete(r) } func (r *ComponentDefinitionReconciler) reconcile(rctx intctrlutil.RequestCtx, - cmpd *appsv1alpha1.ComponentDefinition) (ctrl.Result, error) { + cmpd *appsv1.ComponentDefinition) (ctrl.Result, error) { res, err := intctrlutil.HandleCRDeletion(rctx, r, cmpd, componentDefinitionFinalizerName, r.deletionHandler(rctx, cmpd)) if res != nil { return *res, err } if cmpd.Status.ObservedGeneration == cmpd.Generation && - slices.Contains([]appsv1alpha1.Phase{appsv1alpha1.AvailablePhase}, cmpd.Status.Phase) { + slices.Contains([]appsv1.Phase{appsv1.AvailablePhase}, cmpd.Status.Phase) { return intctrlutil.Reconciled() } @@ -121,14 +121,14 @@ func (r *ComponentDefinitionReconciler) reconcile(rctx intctrlutil.RequestCtx, } func (r *ComponentDefinitionReconciler) deletionHandler(rctx intctrlutil.RequestCtx, - cmpd *appsv1alpha1.ComponentDefinition) func() (*ctrl.Result, error) { + cmpd *appsv1.ComponentDefinition) func() (*ctrl.Result, error) { return func() (*ctrl.Result, error) { recordEvent := func() { r.Recorder.Event(cmpd, corev1.EventTypeWarning, constant.ReasonRefCRUnavailable, "cannot be deleted because of existing referencing Component.") } if res, err := intctrlutil.ValidateReferenceCR(rctx, r.Client, cmpd, constant.ComponentDefinitionLabelKey, - recordEvent, &appsv1alpha1.ComponentList{}); res != nil || err != nil { + recordEvent, &appsv1.ComponentList{}); res != nil || err != nil { return res, err } return nil, nil @@ -136,17 +136,17 @@ func (r *ComponentDefinitionReconciler) deletionHandler(rctx intctrlutil.Request } func (r *ComponentDefinitionReconciler) available(cli client.Client, rctx intctrlutil.RequestCtx, - cmpd *appsv1alpha1.ComponentDefinition) error { - return r.status(cli, rctx, cmpd, appsv1alpha1.AvailablePhase, "") + cmpd *appsv1.ComponentDefinition) error { + return r.status(cli, rctx, cmpd, appsv1.AvailablePhase, "") } func (r *ComponentDefinitionReconciler) unavailable(cli client.Client, rctx intctrlutil.RequestCtx, - cmpd *appsv1alpha1.ComponentDefinition, err error) error { - return r.status(cli, rctx, cmpd, appsv1alpha1.UnavailablePhase, err.Error()) + cmpd *appsv1.ComponentDefinition, err error) error { + return r.status(cli, rctx, cmpd, appsv1.UnavailablePhase, err.Error()) } func (r *ComponentDefinitionReconciler) status(cli client.Client, rctx intctrlutil.RequestCtx, - cmpd *appsv1alpha1.ComponentDefinition, phase appsv1alpha1.Phase, message string) error { + cmpd *appsv1.ComponentDefinition, phase appsv1.Phase, message string) error { patch := client.MergeFrom(cmpd.DeepCopy()) cmpd.Status.ObservedGeneration = cmpd.Generation cmpd.Status.Phase = phase @@ -155,7 +155,7 @@ func (r *ComponentDefinitionReconciler) status(cli client.Client, rctx intctrlut } func (r *ComponentDefinitionReconciler) immutableHash(cli client.Client, rctx intctrlutil.RequestCtx, - cmpd *appsv1alpha1.ComponentDefinition) error { + cmpd *appsv1.ComponentDefinition) error { if r.skipImmutableCheck(cmpd) { return nil } @@ -176,8 +176,8 @@ func (r *ComponentDefinitionReconciler) immutableHash(cli client.Client, rctx in } func (r *ComponentDefinitionReconciler) validate(cli client.Client, rctx intctrlutil.RequestCtx, - cmpd *appsv1alpha1.ComponentDefinition) error { - for _, validator := range []func(client.Client, intctrlutil.RequestCtx, *appsv1alpha1.ComponentDefinition) error{ + cmpd *appsv1.ComponentDefinition) error { + for _, validator := range []func(client.Client, intctrlutil.RequestCtx, *appsv1.ComponentDefinition) error{ r.validateServiceVersion, r.validateRuntime, r.validateVars, @@ -200,22 +200,22 @@ func (r *ComponentDefinitionReconciler) validate(cli client.Client, rctx intctrl } func (r *ComponentDefinitionReconciler) validateServiceVersion(cli client.Client, rctx intctrlutil.RequestCtx, - cmpd *appsv1alpha1.ComponentDefinition) error { + cmpd *appsv1.ComponentDefinition) error { return validateServiceVersion(cmpd.Spec.ServiceVersion) } func (r *ComponentDefinitionReconciler) validateRuntime(cli client.Client, rctx intctrlutil.RequestCtx, - cmpd *appsv1alpha1.ComponentDefinition) error { + cmpd *appsv1.ComponentDefinition) error { return nil } func (r *ComponentDefinitionReconciler) validateVars(cli client.Client, rctx intctrlutil.RequestCtx, - cmpd *appsv1alpha1.ComponentDefinition) error { + cmpd *appsv1.ComponentDefinition) error { return nil } func (r *ComponentDefinitionReconciler) validateVolumes(cli client.Client, rctx intctrlutil.RequestCtx, - cmpd *appsv1alpha1.ComponentDefinition) error { + cmpd *appsv1.ComponentDefinition) error { if !checkUniqueItemWithValue(cmpd.Spec.Volumes, "Name", nil) { return fmt.Errorf("duplicate volume names are not allowed") } @@ -236,7 +236,7 @@ func (r *ComponentDefinitionReconciler) validateVolumes(cli client.Client, rctx } func (r *ComponentDefinitionReconciler) validateHostNetwork(cli client.Client, rctx intctrlutil.RequestCtx, - cmpd *appsv1alpha1.ComponentDefinition) error { + cmpd *appsv1.ComponentDefinition) error { if cmpd.Spec.HostNetwork == nil { return nil } @@ -270,7 +270,7 @@ func (r *ComponentDefinitionReconciler) validateHostNetwork(cli client.Client, r } func (r *ComponentDefinitionReconciler) validateServices(cli client.Client, rctx intctrlutil.RequestCtx, - cmpd *appsv1alpha1.ComponentDefinition) error { + cmpd *appsv1.ComponentDefinition) error { if !checkUniqueItemWithValue(cmpd.Spec.Services, "Name", nil) { return fmt.Errorf("duplicate names of component service are not allowed") } @@ -298,28 +298,28 @@ func (r *ComponentDefinitionReconciler) validateServices(cli client.Client, rctx } func (r *ComponentDefinitionReconciler) validateConfigs(cli client.Client, rctx intctrlutil.RequestCtx, - compDef *appsv1alpha1.ComponentDefinition) error { + compDef *appsv1.ComponentDefinition) error { return appsconfig.ReconcileConfigSpecsForReferencedCR(cli, rctx, compDef) } func (r *ComponentDefinitionReconciler) validatePolicyRules(cli client.Client, rctx intctrlutil.RequestCtx, - cmpd *appsv1alpha1.ComponentDefinition) error { + cmpd *appsv1.ComponentDefinition) error { // TODO: how to check the acquired rules can be granted? return nil } func (r *ComponentDefinitionReconciler) validateLabels(cli client.Client, rctx intctrlutil.RequestCtx, - cmpd *appsv1alpha1.ComponentDefinition) error { + cmpd *appsv1.ComponentDefinition) error { return nil } func (r *ComponentDefinitionReconciler) validateReplicasLimit(cli client.Client, rctx intctrlutil.RequestCtx, - cmpd *appsv1alpha1.ComponentDefinition) error { + cmpd *appsv1.ComponentDefinition) error { return nil } func (r *ComponentDefinitionReconciler) validateSystemAccounts(cli client.Client, rctx intctrlutil.RequestCtx, - cmpd *appsv1alpha1.ComponentDefinition) error { + cmpd *appsv1.ComponentDefinition) error { for _, v := range cmpd.Spec.SystemAccounts { if v.SecretRef == nil && !v.InitAccount && (cmpd.Spec.LifecycleActions == nil || cmpd.Spec.LifecycleActions.AccountProvision == nil) { return fmt.Errorf(`the AccountProvision action is needed to provision system account %s`, v.Name) @@ -337,18 +337,19 @@ func (r *ComponentDefinitionReconciler) validateSystemAccounts(cli client.Client } func (r *ComponentDefinitionReconciler) validateReplicaRoles(cli client.Client, reqCtx intctrlutil.RequestCtx, - cmpd *appsv1alpha1.ComponentDefinition) error { + cmpd *appsv1.ComponentDefinition) error { if !checkUniqueItemWithValue(cmpd.Spec.Roles, "Name", nil) { return fmt.Errorf("duplicate replica roles are not allowed") } return nil } -func (r *ComponentDefinitionReconciler) validateLifecycleActions(cli client.Client, reqCtx intctrlutil.RequestCtx, cmpd *appsv1alpha1.ComponentDefinition) error { +func (r *ComponentDefinitionReconciler) validateLifecycleActions(cli client.Client, reqCtx intctrlutil.RequestCtx, + cmpd *appsv1.ComponentDefinition) error { return nil } -func (r *ComponentDefinitionReconciler) immutableCheck(cmpd *appsv1alpha1.ComponentDefinition) error { +func (r *ComponentDefinitionReconciler) immutableCheck(cmpd *appsv1.ComponentDefinition) error { if r.skipImmutableCheck(cmpd) { return nil } @@ -366,7 +367,7 @@ func (r *ComponentDefinitionReconciler) immutableCheck(cmpd *appsv1alpha1.Compon return nil } -func (r *ComponentDefinitionReconciler) skipImmutableCheck(cmpd *appsv1alpha1.ComponentDefinition) bool { +func (r *ComponentDefinitionReconciler) skipImmutableCheck(cmpd *appsv1.ComponentDefinition) bool { if cmpd.Annotations == nil { return false } @@ -374,7 +375,7 @@ func (r *ComponentDefinitionReconciler) skipImmutableCheck(cmpd *appsv1alpha1.Co return ok && strings.ToLower(skip) == "true" } -func (r *ComponentDefinitionReconciler) cmpdHash(cmpd *appsv1alpha1.ComponentDefinition) (string, error) { +func (r *ComponentDefinitionReconciler) cmpdHash(cmpd *appsv1.ComponentDefinition) (string, error) { objCopy := cmpd.DeepCopy() // reset all mutable fields @@ -394,31 +395,31 @@ func (r *ComponentDefinitionReconciler) cmpdHash(cmpd *appsv1alpha1.ComponentDef return rand.SafeEncodeString(fmt.Sprintf("%d", hash.Sum32())), nil } -func getNCheckCompDefinition(ctx context.Context, cli client.Reader, name string) (*appsv1alpha1.ComponentDefinition, error) { +func getNCheckCompDefinition(ctx context.Context, cli client.Reader, name string) (*appsv1.ComponentDefinition, error) { compKey := types.NamespacedName{ Name: name, } - compDef := &appsv1alpha1.ComponentDefinition{} + compDef := &appsv1.ComponentDefinition{} if err := cli.Get(ctx, compKey, compDef); err != nil { return nil, err } if compDef.Generation != compDef.Status.ObservedGeneration { return nil, fmt.Errorf("the referenced ComponentDefinition is not up to date: %s", compDef.Name) } - if compDef.Status.Phase != appsv1alpha1.AvailablePhase { + if compDef.Status.Phase != appsv1.AvailablePhase { return nil, fmt.Errorf("the referenced ComponentDefinition is unavailable: %s", compDef.Name) } return compDef, nil } // listCompDefinitionsWithPrefix returns all component definitions whose names have prefix @namePrefix. -func listCompDefinitionsWithPrefix(ctx context.Context, cli client.Reader, namePrefix string) ([]*appsv1alpha1.ComponentDefinition, error) { - compDefList := &appsv1alpha1.ComponentDefinitionList{} +func listCompDefinitionsWithPrefix(ctx context.Context, cli client.Reader, namePrefix string) ([]*appsv1.ComponentDefinition, error) { + compDefList := &appsv1.ComponentDefinitionList{} if err := cli.List(ctx, compDefList); err != nil { return nil, err } - compDefsFullyMatched := make([]*appsv1alpha1.ComponentDefinition, 0) - compDefsPrefixMatched := make([]*appsv1alpha1.ComponentDefinition, 0) + compDefsFullyMatched := make([]*appsv1.ComponentDefinition, 0) + compDefsPrefixMatched := make([]*appsv1.ComponentDefinition, 0) for i, item := range compDefList.Items { if item.Name == namePrefix { compDefsFullyMatched = append(compDefsFullyMatched, &compDefList.Items[i]) diff --git a/controllers/apps/componentdefinition_controller_test.go b/controllers/apps/componentdefinition_controller_test.go index 97916a3000b..185fa801477 100644 --- a/controllers/apps/componentdefinition_controller_test.go +++ b/controllers/apps/componentdefinition_controller_test.go @@ -30,6 +30,7 @@ import ( corev1 "k8s.io/api/core/v1" "sigs.k8s.io/controller-runtime/pkg/client" + kbappsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" "github.com/apecloud/kubeblocks/pkg/constant" intctrlutil "github.com/apecloud/kubeblocks/pkg/generics" @@ -45,7 +46,7 @@ var _ = Describe("ComponentDefinition Controller", func() { ) var ( - defaultActionHandler = &appsv1alpha1.Action{} + defaultActionHandler = &kbappsv1.Action{} ) cleanEnv := func() { @@ -66,10 +67,10 @@ var _ = Describe("ComponentDefinition Controller", func() { testapps.ClearResourcesWithRemoveFinalizerOption(&testCtx, intctrlutil.ConfigMapSignature, true, inNS, ml) } - checkObjectStatus := func(obj *appsv1alpha1.ComponentDefinition, expectedPhase appsv1alpha1.Phase) { + checkObjectStatus := func(obj *kbappsv1.ComponentDefinition, expectedPhase kbappsv1.Phase) { By(fmt.Sprintf("checking the object as %s", strings.ToLower(string(expectedPhase)))) Eventually(testapps.CheckObj(&testCtx, client.ObjectKeyFromObject(obj), - func(g Gomega, cmpd *appsv1alpha1.ComponentDefinition) { + func(g Gomega, cmpd *kbappsv1.ComponentDefinition) { g.Expect(cmpd.Status.ObservedGeneration).Should(Equal(cmpd.GetGeneration())) g.Expect(cmpd.Status.Phase).Should(Equal(expectedPhase)) })).Should(Succeed()) @@ -93,10 +94,10 @@ var _ = Describe("ComponentDefinition Controller", func() { By("checking the object reconciled") Eventually(testapps.CheckObj(&testCtx, client.ObjectKeyFromObject(componentDefObj), - func(g Gomega, cmpd *appsv1alpha1.ComponentDefinition) { + func(g Gomega, cmpd *kbappsv1.ComponentDefinition) { g.Expect(cmpd.Finalizers).ShouldNot(BeEmpty()) g.Expect(cmpd.Status.ObservedGeneration).Should(Equal(cmpd.GetGeneration())) - g.Expect(cmpd.Status.Phase).Should(Equal(appsv1alpha1.AvailablePhase)) + g.Expect(cmpd.Status.Phase).Should(Equal(kbappsv1.AvailablePhase)) })).Should(Succeed()) }) }) @@ -109,7 +110,7 @@ var _ = Describe("ComponentDefinition Controller", func() { AddVolume("default", true, 85). Create(&testCtx).GetObject() - checkObjectStatus(componentDefObj, appsv1alpha1.UnavailablePhase) + checkObjectStatus(componentDefObj, kbappsv1.UnavailablePhase) }) It("enable volume protection w/ actions set", func() { @@ -121,7 +122,7 @@ var _ = Describe("ComponentDefinition Controller", func() { SetLifecycleAction("Readwrite", defaultActionHandler). Create(&testCtx).GetObject() - checkObjectStatus(componentDefObj, appsv1alpha1.AvailablePhase) + checkObjectStatus(componentDefObj, kbappsv1.AvailablePhase) }) }) @@ -133,7 +134,7 @@ var _ = Describe("ComponentDefinition Controller", func() { AddHostNetworkContainerPort(testapps.DefaultMySQLContainerName, []string{"mysql"}). Create(&testCtx).GetObject() - checkObjectStatus(componentDefObj, appsv1alpha1.AvailablePhase) + checkObjectStatus(componentDefObj, kbappsv1.AvailablePhase) }) It("duplicate containers", func() { @@ -144,7 +145,7 @@ var _ = Describe("ComponentDefinition Controller", func() { AddHostNetworkContainerPort(testapps.DefaultMySQLContainerName, []string{"mysql"}). Create(&testCtx).GetObject() - checkObjectStatus(componentDefObj, appsv1alpha1.UnavailablePhase) + checkObjectStatus(componentDefObj, kbappsv1.UnavailablePhase) }) It("undefined container", func() { @@ -154,7 +155,7 @@ var _ = Describe("ComponentDefinition Controller", func() { AddHostNetworkContainerPort("non-exist-container", []string{"mysql"}). Create(&testCtx).GetObject() - checkObjectStatus(componentDefObj, appsv1alpha1.UnavailablePhase) + checkObjectStatus(componentDefObj, kbappsv1.UnavailablePhase) }) It("undefined container port", func() { @@ -164,7 +165,7 @@ var _ = Describe("ComponentDefinition Controller", func() { AddHostNetworkContainerPort(testapps.DefaultMySQLContainerName, []string{"non-exist-port"}). Create(&testCtx).GetObject() - checkObjectStatus(componentDefObj, appsv1alpha1.UnavailablePhase) + checkObjectStatus(componentDefObj, kbappsv1.UnavailablePhase) }) }) @@ -179,7 +180,7 @@ var _ = Describe("ComponentDefinition Controller", func() { AddRole("follower", true, false). Create(&testCtx).GetObject() - checkObjectStatus(componentDefObj, appsv1alpha1.AvailablePhase) + checkObjectStatus(componentDefObj, kbappsv1.AvailablePhase) }) It("duplicate names", func() { @@ -192,7 +193,7 @@ var _ = Describe("ComponentDefinition Controller", func() { AddRole("follower", true, false). Create(&testCtx).GetObject() - checkObjectStatus(componentDefObj, appsv1alpha1.UnavailablePhase) + checkObjectStatus(componentDefObj, kbappsv1.UnavailablePhase) }) It("duplicate service names", func() { @@ -205,7 +206,7 @@ var _ = Describe("ComponentDefinition Controller", func() { AddRole("follower", true, false). Create(&testCtx).GetObject() - checkObjectStatus(componentDefObj, appsv1alpha1.UnavailablePhase) + checkObjectStatus(componentDefObj, kbappsv1.UnavailablePhase) }) It("multiple default service names", func() { @@ -218,7 +219,7 @@ var _ = Describe("ComponentDefinition Controller", func() { AddRole("follower", true, false). Create(&testCtx).GetObject() - checkObjectStatus(componentDefObj, appsv1alpha1.UnavailablePhase) + checkObjectStatus(componentDefObj, kbappsv1.UnavailablePhase) }) It("w/o port", func() { @@ -230,7 +231,7 @@ var _ = Describe("ComponentDefinition Controller", func() { AddRole("follower", true, false). Create(&testCtx).GetObject() - checkObjectStatus(componentDefObj, appsv1alpha1.UnavailablePhase) + checkObjectStatus(componentDefObj, kbappsv1.UnavailablePhase) }) It("undefined role selector", func() { @@ -244,7 +245,7 @@ var _ = Describe("ComponentDefinition Controller", func() { AddRole("follower", true, false). Create(&testCtx).GetObject() - checkObjectStatus(componentDefObj, appsv1alpha1.UnavailablePhase) + checkObjectStatus(componentDefObj, kbappsv1.UnavailablePhase) }) }) @@ -256,7 +257,7 @@ var _ = Describe("ComponentDefinition Controller", func() { AddSystemAccount(adminAccount, false, "create user"). Create(&testCtx).GetObject() - checkObjectStatus(componentDefObj, appsv1alpha1.UnavailablePhase) + checkObjectStatus(componentDefObj, kbappsv1.UnavailablePhase) }) It("w/ actions set", func() { @@ -267,7 +268,7 @@ var _ = Describe("ComponentDefinition Controller", func() { SetLifecycleAction("AccountProvision", defaultActionHandler). Create(&testCtx).GetObject() - checkObjectStatus(componentDefObj, appsv1alpha1.AvailablePhase) + checkObjectStatus(componentDefObj, kbappsv1.AvailablePhase) }) It("duplicate accounts", func() { @@ -279,7 +280,7 @@ var _ = Describe("ComponentDefinition Controller", func() { SetLifecycleAction("AccountProvision", defaultActionHandler). Create(&testCtx).GetObject() - checkObjectStatus(componentDefObj, appsv1alpha1.UnavailablePhase) + checkObjectStatus(componentDefObj, kbappsv1.UnavailablePhase) }) It("multiple init accounts", func() { @@ -292,7 +293,7 @@ var _ = Describe("ComponentDefinition Controller", func() { SetLifecycleAction("AccountProvision", defaultActionHandler). Create(&testCtx).GetObject() - checkObjectStatus(componentDefObj, appsv1alpha1.AvailablePhase) + checkObjectStatus(componentDefObj, kbappsv1.AvailablePhase) }) It("multiple accounts should be ok", func() { @@ -305,7 +306,7 @@ var _ = Describe("ComponentDefinition Controller", func() { SetLifecycleAction("AccountProvision", defaultActionHandler). Create(&testCtx).GetObject() - checkObjectStatus(componentDefObj, appsv1alpha1.AvailablePhase) + checkObjectStatus(componentDefObj, kbappsv1.AvailablePhase) }) }) @@ -319,7 +320,7 @@ var _ = Describe("ComponentDefinition Controller", func() { AddRole("learner", false, false). Create(&testCtx).GetObject() - checkObjectStatus(componentDefObj, appsv1alpha1.AvailablePhase) + checkObjectStatus(componentDefObj, kbappsv1.AvailablePhase) }) It("duplicate roles", func() { @@ -332,12 +333,12 @@ var _ = Describe("ComponentDefinition Controller", func() { AddRole("learner", true, false). Create(&testCtx).GetObject() - checkObjectStatus(componentDefObj, appsv1alpha1.UnavailablePhase) + checkObjectStatus(componentDefObj, kbappsv1.UnavailablePhase) }) }) Context("immutable", func() { - newCmpdFn := func(processor func(*testapps.MockComponentDefinitionFactory)) *appsv1alpha1.ComponentDefinition { + newCmpdFn := func(processor func(*testapps.MockComponentDefinitionFactory)) *kbappsv1.ComponentDefinition { By("create a ComponentDefinition obj") builder := testapps.NewComponentDefinitionFactory(componentDefName). SetDescription("v0.0.1"). @@ -352,15 +353,15 @@ var _ = Describe("ComponentDefinition Controller", func() { processor(builder) } obj := builder.Create(&testCtx).GetObject() - checkObjectStatus(obj, appsv1alpha1.AvailablePhase) + checkObjectStatus(obj, kbappsv1.AvailablePhase) return obj } - newCmpd := func() *appsv1alpha1.ComponentDefinition { + newCmpd := func() *kbappsv1.ComponentDefinition { return newCmpdFn(nil) } - newCmpdSkipImmutableCheck := func() *appsv1alpha1.ComponentDefinition { + newCmpdSkipImmutableCheck := func() *kbappsv1.ComponentDefinition { return newCmpdFn(func(f *testapps.MockComponentDefinitionFactory) { f.AddAnnotations(constant.SkipImmutableCheckAnnotationKey, "true") }) @@ -370,15 +371,15 @@ var _ = Describe("ComponentDefinition Controller", func() { componentDefObj := newCmpd() By("update mutable fields") - Expect(testapps.GetAndChangeObj(&testCtx, client.ObjectKeyFromObject(componentDefObj), func(cmpd *appsv1alpha1.ComponentDefinition) { + Expect(testapps.GetAndChangeObj(&testCtx, client.ObjectKeyFromObject(componentDefObj), func(cmpd *kbappsv1.ComponentDefinition) { cmpd.Spec.Description = "v0.0.2" parallel := appsv1.ParallelPodManagement cmpd.Spec.PodManagementPolicy = ¶llel })()).Should(Succeed()) - By(fmt.Sprintf("checking the updated object as %s", strings.ToLower(string(appsv1alpha1.AvailablePhase)))) + By(fmt.Sprintf("checking the updated object as %s", strings.ToLower(string(kbappsv1.AvailablePhase)))) Eventually(testapps.CheckObj(&testCtx, client.ObjectKeyFromObject(componentDefObj), - func(g Gomega, cmpd *appsv1alpha1.ComponentDefinition) { + func(g Gomega, cmpd *kbappsv1.ComponentDefinition) { g.Expect(cmpd.Status.ObservedGeneration).Should(Equal(cmpd.GetGeneration())) g.Expect(cmpd.Status.Phase).Should(Equal(appsv1alpha1.AvailablePhase)) g.Expect(cmpd.Spec.Description).Should(Equal("v0.0.2")) @@ -391,18 +392,18 @@ var _ = Describe("ComponentDefinition Controller", func() { componentDefObj := newCmpdSkipImmutableCheck() By("update mutable & immutable fields") - Expect(testapps.GetAndChangeObj(&testCtx, client.ObjectKeyFromObject(componentDefObj), func(cmpd *appsv1alpha1.ComponentDefinition) { + Expect(testapps.GetAndChangeObj(&testCtx, client.ObjectKeyFromObject(componentDefObj), func(cmpd *kbappsv1.ComponentDefinition) { cmpd.Spec.Description = "v0.0.2" cmpd.Spec.Runtime.Containers[0].Image = "image:v0.0.2" - parallel := appsv1alpha1.ParallelStrategy + parallel := kbappsv1.ParallelStrategy cmpd.Spec.UpdateStrategy = ¶llel })()).Should(Succeed()) By(fmt.Sprintf("checking the updated object as %s", strings.ToLower(string(appsv1alpha1.AvailablePhase)))) Eventually(testapps.CheckObj(&testCtx, client.ObjectKeyFromObject(componentDefObj), - func(g Gomega, cmpd *appsv1alpha1.ComponentDefinition) { + func(g Gomega, cmpd *kbappsv1.ComponentDefinition) { g.Expect(cmpd.Status.ObservedGeneration).Should(Equal(cmpd.GetGeneration())) - g.Expect(cmpd.Status.Phase).Should(Equal(appsv1alpha1.AvailablePhase)) + g.Expect(cmpd.Status.Phase).Should(Equal(kbappsv1.AvailablePhase)) g.Expect(cmpd.Spec.Description).Should(Equal("v0.0.2")) c := corev1.Container{ Name: "container", @@ -411,7 +412,7 @@ var _ = Describe("ComponentDefinition Controller", func() { } g.Expect(cmpd.Spec.Runtime.Containers[0]).Should(BeEquivalentTo(c)) g.Expect(cmpd.Spec.UpdateStrategy).ShouldNot(BeNil()) - g.Expect(*cmpd.Spec.UpdateStrategy).Should(Equal(appsv1alpha1.ParallelStrategy)) + g.Expect(*cmpd.Spec.UpdateStrategy).Should(Equal(kbappsv1.ParallelStrategy)) })).Should(Succeed()) }) @@ -419,18 +420,18 @@ var _ = Describe("ComponentDefinition Controller", func() { componentDefObj := newCmpd() By("update mutable & immutable fields") - Expect(testapps.GetAndChangeObj(&testCtx, client.ObjectKeyFromObject(componentDefObj), func(cmpd *appsv1alpha1.ComponentDefinition) { + Expect(testapps.GetAndChangeObj(&testCtx, client.ObjectKeyFromObject(componentDefObj), func(cmpd *kbappsv1.ComponentDefinition) { cmpd.Spec.Description = "v0.0.2" cmpd.Spec.Runtime.Containers[0].Image = "image:v0.0.2" - parallel := appsv1alpha1.ParallelStrategy + parallel := kbappsv1.ParallelStrategy cmpd.Spec.UpdateStrategy = ¶llel })()).Should(Succeed()) By(fmt.Sprintf("checking the updated object as %s", strings.ToLower(string(appsv1alpha1.UnavailablePhase)))) Eventually(testapps.CheckObj(&testCtx, client.ObjectKeyFromObject(componentDefObj), - func(g Gomega, cmpd *appsv1alpha1.ComponentDefinition) { + func(g Gomega, cmpd *kbappsv1.ComponentDefinition) { g.Expect(cmpd.Status.ObservedGeneration).Should(Equal(cmpd.GetGeneration())) - g.Expect(cmpd.Status.Phase).Should(Equal(appsv1alpha1.UnavailablePhase)) + g.Expect(cmpd.Status.Phase).Should(Equal(kbappsv1.UnavailablePhase)) g.Expect(cmpd.Spec.Description).Should(Equal("v0.0.2")) c := corev1.Container{ Name: "container", @@ -439,20 +440,20 @@ var _ = Describe("ComponentDefinition Controller", func() { } g.Expect(cmpd.Spec.Runtime.Containers[0]).Should(BeEquivalentTo(c)) g.Expect(cmpd.Spec.UpdateStrategy).ShouldNot(BeNil()) - g.Expect(*cmpd.Spec.UpdateStrategy).Should(Equal(appsv1alpha1.ParallelStrategy)) + g.Expect(*cmpd.Spec.UpdateStrategy).Should(Equal(kbappsv1.ParallelStrategy)) })).Should(Succeed()) By("revert the change to immutable fields back") - Expect(testapps.GetAndChangeObj(&testCtx, client.ObjectKeyFromObject(componentDefObj), func(cmpd *appsv1alpha1.ComponentDefinition) { + Expect(testapps.GetAndChangeObj(&testCtx, client.ObjectKeyFromObject(componentDefObj), func(cmpd *kbappsv1.ComponentDefinition) { cmpd.Spec.Runtime.Containers[0].Image = "image:v0.0.1" cmpd.Spec.UpdateStrategy = nil })()).Should(Succeed()) By(fmt.Sprintf("checking the updated object as %s", strings.ToLower(string(appsv1alpha1.AvailablePhase)))) Eventually(testapps.CheckObj(&testCtx, client.ObjectKeyFromObject(componentDefObj), - func(g Gomega, cmpd *appsv1alpha1.ComponentDefinition) { + func(g Gomega, cmpd *kbappsv1.ComponentDefinition) { g.Expect(cmpd.Status.ObservedGeneration).Should(Equal(cmpd.GetGeneration())) - g.Expect(cmpd.Status.Phase).Should(Equal(appsv1alpha1.AvailablePhase)) + g.Expect(cmpd.Status.Phase).Should(Equal(kbappsv1.AvailablePhase)) g.Expect(cmpd.Spec.Description).Should(Equal("v0.0.2")) c := corev1.Container{ Name: "container", @@ -461,7 +462,7 @@ var _ = Describe("ComponentDefinition Controller", func() { } g.Expect(cmpd.Spec.Runtime.Containers[0]).Should(BeEquivalentTo(c)) g.Expect(cmpd.Spec.UpdateStrategy).ShouldNot(BeNil()) - g.Expect(*cmpd.Spec.UpdateStrategy).Should(Equal(appsv1alpha1.SerialStrategy)) + g.Expect(*cmpd.Spec.UpdateStrategy).Should(Equal(kbappsv1.SerialStrategy)) })).Should(Succeed()) }) }) diff --git a/controllers/apps/componentversion_controller.go b/controllers/apps/componentversion_controller.go index 2621e1637e6..c21d6a86bb7 100644 --- a/controllers/apps/componentversion_controller.go +++ b/controllers/apps/componentversion_controller.go @@ -93,12 +93,12 @@ func (r *ComponentVersionReconciler) Reconcile(ctx context.Context, req ctrl.Req func (r *ComponentVersionReconciler) SetupWithManager(mgr ctrl.Manager) error { return ctrl.NewControllerManagedBy(mgr). For(&appsv1.ComponentVersion{}). - Watches(&appsv1alpha1.ComponentDefinition{}, handler.EnqueueRequestsFromMapFunc(r.compatibleCompVersion)). + Watches(&appsv1.ComponentDefinition{}, handler.EnqueueRequestsFromMapFunc(r.compatibleCompVersion)). Complete(r) } func (r *ComponentVersionReconciler) compatibleCompVersion(ctx context.Context, obj client.Object) []reconcile.Request { - compDef, ok := obj.(*appsv1alpha1.ComponentDefinition) + compDef, ok := obj.(*appsv1.ComponentDefinition) if !ok { return nil } @@ -119,7 +119,7 @@ func (r *ComponentVersionReconciler) compatibleCompVersion(ctx context.Context, return requests } -func (r *ComponentVersionReconciler) isCompatibleWith(compDef appsv1alpha1.ComponentDefinition, compVer appsv1.ComponentVersion) bool { +func (r *ComponentVersionReconciler) isCompatibleWith(compDef appsv1.ComponentDefinition, compVer appsv1.ComponentVersion) bool { for _, rule := range compVer.Spec.CompatibilityRules { for _, name := range rule.CompDefs { if strings.HasPrefix(compDef.Name, name) { @@ -138,7 +138,7 @@ func (r *ComponentVersionReconciler) reconcile(rctx intctrlutil.RequestCtx, } // if compVersion.Status.ObservedGeneration == compVersion.Generation && - // slices.Contains([]appsv1alpha1.Phase{appsv1alpha1.AvailablePhase}, compVersion.Status.Phase) { + // slices.Contains([]appsv1.Phase{appsv1.AvailablePhase}, compVersion.Status.Phase) { // return intctrlutil.Reconciled() // } @@ -171,8 +171,8 @@ func (r *ComponentVersionReconciler) reconcile(rctx intctrlutil.RequestCtx, } func (r *ComponentVersionReconciler) buildReleaseToCompDefinitionMapping(cli client.Client, rctx intctrlutil.RequestCtx, - compVersion *appsv1.ComponentVersion) (map[string]map[string]*appsv1alpha1.ComponentDefinition, error) { - compDefs := make(map[string][]*appsv1alpha1.ComponentDefinition) + compVersion *appsv1.ComponentVersion) (map[string]map[string]*appsv1.ComponentDefinition, error) { + compDefs := make(map[string][]*appsv1.ComponentDefinition) for _, rule := range compVersion.Spec.CompatibilityRules { for _, compDef := range rule.CompDefs { if _, ok := compDefs[compDef]; ok { @@ -185,11 +185,11 @@ func (r *ComponentVersionReconciler) buildReleaseToCompDefinitionMapping(cli cli } } } - releaseToCompDefinitions := make(map[string]map[string]*appsv1alpha1.ComponentDefinition) + releaseToCompDefinitions := make(map[string]map[string]*appsv1.ComponentDefinition) for _, rule := range compVersion.Spec.CompatibilityRules { for _, release := range rule.Releases { if _, ok := releaseToCompDefinitions[release]; !ok { - releaseToCompDefinitions[release] = map[string]*appsv1alpha1.ComponentDefinition{} + releaseToCompDefinitions[release] = map[string]*appsv1.ComponentDefinition{} } for _, compDefName := range rule.CompDefs { for i, compDef := range compDefs[compDefName] { @@ -252,7 +252,7 @@ func (r *ComponentVersionReconciler) supportedServiceVersions(compVersion *appsv } func (r *ComponentVersionReconciler) updateSupportedCompDefLabels(cli client.Client, rctx intctrlutil.RequestCtx, - compVersion *appsv1.ComponentVersion, releaseToCompDefinitions map[string]map[string]*appsv1alpha1.ComponentDefinition) error { + compVersion *appsv1.ComponentVersion, releaseToCompDefinitions map[string]map[string]*appsv1.ComponentDefinition) error { if compVersion.Annotations == nil { compVersion.Annotations = make(map[string]string) } @@ -284,7 +284,7 @@ func (r *ComponentVersionReconciler) updateSupportedCompDefLabels(cli client.Cli } func (r *ComponentVersionReconciler) validate(compVersion *appsv1.ComponentVersion, - releaseToCompDefinitions map[string]map[string]*appsv1alpha1.ComponentDefinition) error { + releaseToCompDefinitions map[string]map[string]*appsv1.ComponentDefinition) error { for _, release := range compVersion.Spec.Releases { if err := r.validateRelease(release, releaseToCompDefinitions); err != nil { return err @@ -294,9 +294,9 @@ func (r *ComponentVersionReconciler) validate(compVersion *appsv1.ComponentVersi } func (r *ComponentVersionReconciler) validateRelease(release appsv1.ComponentVersionRelease, - releaseToCompDefinitions map[string]map[string]*appsv1alpha1.ComponentDefinition) error { + releaseToCompDefinitions map[string]map[string]*appsv1.ComponentDefinition) error { cmpds, ok := releaseToCompDefinitions[release.Name] - notNil := func(cmpd *appsv1alpha1.ComponentDefinition) bool { + notNil := func(cmpd *appsv1.ComponentDefinition) bool { return cmpd != nil } if !ok || generics.CountFunc(maps.Values(cmpds), notNil) == 0 { @@ -315,8 +315,8 @@ func (r *ComponentVersionReconciler) validateServiceVersion(release appsv1.Compo return validateServiceVersion(release.ServiceVersion) } -func (r *ComponentVersionReconciler) validateImages(release appsv1.ComponentVersionRelease, cmpds map[string]*appsv1alpha1.ComponentDefinition) error { - validateContainer := func(cmpd appsv1alpha1.ComponentDefinition, name string) error { +func (r *ComponentVersionReconciler) validateImages(release appsv1.ComponentVersionRelease, cmpds map[string]*appsv1.ComponentDefinition) error { + validateContainer := func(cmpd appsv1.ComponentDefinition, name string) error { cmp := func(c corev1.Container) bool { return c.Name == name } @@ -342,16 +342,16 @@ func (r *ComponentVersionReconciler) validateImages(release appsv1.ComponentVers } // resolveCompDefinitionNServiceVersion resolves and returns the specific component definition object and the service version supported. -func resolveCompDefinitionNServiceVersion(ctx context.Context, cli client.Reader, compDefName, serviceVersion string) (*appsv1alpha1.ComponentDefinition, string, error) { +func resolveCompDefinitionNServiceVersion(ctx context.Context, cli client.Reader, compDefName, serviceVersion string) (*appsv1.ComponentDefinition, string, error) { var ( - compDef *appsv1alpha1.ComponentDefinition + compDef *appsv1.ComponentDefinition ) compDefs, err := listCompDefinitionsWithPrefix(ctx, cli, compDefName) if err != nil { return compDef, serviceVersion, err } - // mapping from to <[]*appsv1alpha1.ComponentDefinition> + // mapping from to <[]*appsv1.ComponentDefinition> serviceVersionToCompDefs, err := serviceVersionToCompDefinitions(ctx, cli, compDefs, serviceVersion) if err != nil { return compDef, serviceVersion, err @@ -381,17 +381,17 @@ func resolveCompDefinitionNServiceVersion(ctx context.Context, cli client.Reader } func serviceVersionToCompDefinitions(ctx context.Context, cli client.Reader, - compDefs []*appsv1alpha1.ComponentDefinition, serviceVersion string) (map[string]map[string]*appsv1alpha1.ComponentDefinition, error) { - result := make(map[string]map[string]*appsv1alpha1.ComponentDefinition) + compDefs []*appsv1.ComponentDefinition, serviceVersion string) (map[string]map[string]*appsv1.ComponentDefinition, error) { + result := make(map[string]map[string]*appsv1.ComponentDefinition) - insert := func(version string, compDef *appsv1alpha1.ComponentDefinition) { + insert := func(version string, compDef *appsv1.ComponentDefinition) { if _, ok := result[version]; !ok { - result[version] = make(map[string]*appsv1alpha1.ComponentDefinition) + result[version] = make(map[string]*appsv1.ComponentDefinition) } result[version][compDef.Name] = compDef } - checkedInsert := func(version string, compDef *appsv1alpha1.ComponentDefinition) error { + checkedInsert := func(version string, compDef *appsv1.ComponentDefinition) error { match, err := component.CompareServiceVersion(serviceVersion, version) if err == nil && match { insert(version, compDef) @@ -424,7 +424,7 @@ func serviceVersionToCompDefinitions(ctx context.Context, cli client.Reader, } // compatibleServiceVersions4Definition returns all service versions that are compatible with specified component definition. -func compatibleServiceVersions4Definition(compDef *appsv1alpha1.ComponentDefinition, compVersion *appsv1.ComponentVersion) sets.Set[string] { +func compatibleServiceVersions4Definition(compDef *appsv1.ComponentDefinition, compVersion *appsv1.ComponentVersion) sets.Set[string] { prefixMatch := func(prefix string) bool { return strings.HasPrefix(compDef.Name, prefix) } diff --git a/controllers/apps/componentversion_controller_test.go b/controllers/apps/componentversion_controller_test.go index 2619436d43b..3b861ca61a8 100644 --- a/controllers/apps/componentversion_controller_test.go +++ b/controllers/apps/componentversion_controller_test.go @@ -31,7 +31,6 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" "github.com/apecloud/kubeblocks/pkg/controller/component" "github.com/apecloud/kubeblocks/pkg/generics" testapps "github.com/apecloud/kubeblocks/pkg/testutil/apps" @@ -39,7 +38,7 @@ import ( var _ = Describe("ComponentVersion Controller", func() { var ( - // compDefinitionObjs []*appsv1alpha1.ComponentDefinition + // compDefinitionObjs []*appsv1.ComponentDefinition compVersionObj *appsv1.ComponentVersion compDefNames = []string{testapps.CompDefName("v1.0"), testapps.CompDefName("v1.1"), testapps.CompDefName("v2.0"), testapps.CompDefName("v3.0")} @@ -72,9 +71,9 @@ var _ = Describe("ComponentVersion Controller", func() { cleanEnv() }) - createCompDefinitionObjs := func() []*appsv1alpha1.ComponentDefinition { + createCompDefinitionObjs := func() []*appsv1.ComponentDefinition { By("create default ComponentDefinition objs") - objs := make([]*appsv1alpha1.ComponentDefinition, 0) + objs := make([]*appsv1.ComponentDefinition, 0) for _, name := range compDefNames { f := testapps.NewComponentDefinitionFactory(name). SetServiceVersion(testapps.ServiceVersion("v0")) // use v0 as init service version @@ -86,7 +85,7 @@ var _ = Describe("ComponentVersion Controller", func() { } for _, obj := range objs { Eventually(testapps.CheckObj(&testCtx, client.ObjectKeyFromObject(obj), - func(g Gomega, compDef *appsv1alpha1.ComponentDefinition) { + func(g Gomega, compDef *appsv1.ComponentDefinition) { g.Expect(compDef.Status.ObservedGeneration).Should(Equal(compDef.Generation)) })).Should(Succeed()) } @@ -174,7 +173,7 @@ var _ = Describe("ComponentVersion Controller", func() { return obj } - updateNCheckCompDefinitionImages := func(compDef *appsv1alpha1.ComponentDefinition, serviceVersion string, r0, r1 string) { + updateNCheckCompDefinitionImages := func(compDef *appsv1.ComponentDefinition, serviceVersion string, r0, r1 string) { Expect(compDef.Spec.Runtime.Containers[0].Image).Should(Equal(testapps.AppImage(compDef.Spec.Runtime.Containers[0].Name, testapps.ReleaseID("")))) Expect(compDef.Spec.Runtime.Containers[1].Image).Should(Equal(testapps.AppImage(compDef.Spec.Runtime.Containers[1].Name, testapps.ReleaseID("")))) Expect(component.UpdateCompDefinitionImages4ServiceVersion(testCtx.Ctx, testCtx.Cli, compDef, serviceVersion)).Should(Succeed()) @@ -210,8 +209,8 @@ var _ = Describe("ComponentVersion Controller", func() { It("release has no supported component definitions", func() { By("delete v3.0 component definition, let release r5 has no available component definitions") compDefKey := types.NamespacedName{Name: testapps.CompDefName("v3.0")} - testapps.DeleteObject(&testCtx, compDefKey, &appsv1alpha1.ComponentDefinition{}) - Eventually(testapps.CheckObjExists(&testCtx, compDefKey, &appsv1alpha1.ComponentDefinition{}, false)).Should(Succeed()) + testapps.DeleteObject(&testCtx, compDefKey, &appsv1.ComponentDefinition{}) + Eventually(testapps.CheckObjExists(&testCtx, compDefKey, &appsv1.ComponentDefinition{}, false)).Should(Succeed()) By("checking the object unavailable") Eventually(testapps.CheckObj(&testCtx, client.ObjectKeyFromObject(compVersionObj), @@ -264,8 +263,8 @@ var _ = Describe("ComponentVersion Controller", func() { continue } compDefKey := types.NamespacedName{Name: name} - testapps.DeleteObject(&testCtx, compDefKey, &appsv1alpha1.ComponentDefinition{}) - Eventually(testapps.CheckObjExists(&testCtx, compDefKey, &appsv1alpha1.ComponentDefinition{}, false)).Should(Succeed()) + testapps.DeleteObject(&testCtx, compDefKey, &appsv1.ComponentDefinition{}) + Eventually(testapps.CheckObjExists(&testCtx, compDefKey, &appsv1.ComponentDefinition{}, false)).Should(Succeed()) } By("checking the object available") @@ -513,7 +512,7 @@ var _ = Describe("ComponentVersion Controller", func() { Create(&testCtx). GetObject() Eventually(testapps.CheckObj(&testCtx, client.ObjectKeyFromObject(compDefObj), - func(g Gomega, compDef *appsv1alpha1.ComponentDefinition) { + func(g Gomega, compDef *appsv1.ComponentDefinition) { g.Expect(compDef.Status.ObservedGeneration).Should(Equal(compDef.Generation)) })).Should(Succeed()) @@ -555,7 +554,7 @@ var _ = Describe("ComponentVersion Controller", func() { compDefs := createCompDefinitionObjs() for _, compDef := range compDefs { compDefKey := client.ObjectKeyFromObject(compDef) - Eventually(testapps.GetAndChangeObj(&testCtx, compDefKey, func(compDef *appsv1alpha1.ComponentDefinition) { + Eventually(testapps.GetAndChangeObj(&testCtx, compDefKey, func(compDef *appsv1.ComponentDefinition) { compDef.Spec.ServiceVersion = "" })).Should(Succeed()) } diff --git a/controllers/apps/configuration/config_util.go b/controllers/apps/configuration/config_util.go index 3ead690645f..a5aac06e7c1 100644 --- a/controllers/apps/configuration/config_util.go +++ b/controllers/apps/configuration/config_util.go @@ -31,7 +31,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1beta1 "github.com/apecloud/kubeblocks/apis/apps/v1beta1" cfgcm "github.com/apecloud/kubeblocks/pkg/configuration/config_manager" "github.com/apecloud/kubeblocks/pkg/configuration/core" @@ -116,7 +116,7 @@ func ReconcileConfigSpecsForReferencedCR[T generics.Object, PT generics.PObject[ } func DeleteConfigMapFinalizer(cli client.Client, ctx intctrlutil.RequestCtx, obj client.Object) error { - handler := func(configSpecs []appsv1alpha1.ComponentConfigSpec) (bool, error) { + handler := func(configSpecs []appsv1.ComponentConfigSpec) (bool, error) { return true, batchDeleteConfigMapFinalizer(cli, ctx, configSpecs, obj) } _, err := handleConfigTemplate(obj, handler) @@ -152,7 +152,7 @@ func validateConfigMapOwners(cli client.Client, ctx intctrlutil.RequestCtx, labe return true, nil } -func batchDeleteConfigMapFinalizer(cli client.Client, ctx intctrlutil.RequestCtx, configSpecs []appsv1alpha1.ComponentConfigSpec, cr client.Object) error { +func batchDeleteConfigMapFinalizer(cli client.Client, ctx intctrlutil.RequestCtx, configSpecs []appsv1.ComponentConfigSpec, cr client.Object) error { validator := func(obj client.Object) bool { return obj.GetName() == cr.GetName() && obj.GetNamespace() == cr.GetNamespace() } @@ -160,7 +160,7 @@ func batchDeleteConfigMapFinalizer(cli client.Client, ctx intctrlutil.RequestCtx labels := client.MatchingLabels{ core.GenerateTPLUniqLabelKeyWithConfig(configSpec.Name): configSpec.TemplateRef, } - if ok, err := validateConfigMapOwners(cli, ctx, labels, validator, &appsv1alpha1.ClusterDefinitionList{}, &appsv1alpha1.ComponentDefinitionList{}); err != nil { + if ok, err := validateConfigMapOwners(cli, ctx, labels, validator, &appsv1.ClusterDefinitionList{}, &appsv1.ComponentDefinitionList{}); err != nil { return err } else if !ok { continue @@ -173,13 +173,13 @@ func batchDeleteConfigMapFinalizer(cli client.Client, ctx intctrlutil.RequestCtx } func updateConfigMapFinalizer(client client.Client, ctx intctrlutil.RequestCtx, obj client.Object) (bool, error) { - handler := func(configSpecs []appsv1alpha1.ComponentConfigSpec) (bool, error) { + handler := func(configSpecs []appsv1.ComponentConfigSpec) (bool, error) { return true, batchUpdateConfigMapFinalizer(client, ctx, configSpecs) } return handleConfigTemplate(obj, handler) } -func batchUpdateConfigMapFinalizer(cli client.Client, ctx intctrlutil.RequestCtx, configSpecs []appsv1alpha1.ComponentConfigSpec) error { +func batchUpdateConfigMapFinalizer(cli client.Client, ctx intctrlutil.RequestCtx, configSpecs []appsv1.ComponentConfigSpec) error { for _, configSpec := range configSpecs { if err := updateConfigMapFinalizerImpl(cli, ctx, configSpec); err != nil { return err @@ -188,7 +188,7 @@ func batchUpdateConfigMapFinalizer(cli client.Client, ctx intctrlutil.RequestCtx return nil } -func updateConfigMapFinalizerImpl(cli client.Client, ctx intctrlutil.RequestCtx, configSpec appsv1alpha1.ComponentConfigSpec) error { +func updateConfigMapFinalizerImpl(cli client.Client, ctx intctrlutil.RequestCtx, configSpec appsv1.ComponentConfigSpec) error { // step1: add finalizer // step2: add labels: CMConfigurationTypeLabelKey // step3: update immutable @@ -215,7 +215,7 @@ func updateConfigMapFinalizerImpl(cli client.Client, ctx intctrlutil.RequestCtx, return cli.Patch(ctx.Ctx, cmObj, patch) } -func deleteConfigMapFinalizer(cli client.Client, ctx intctrlutil.RequestCtx, configSpec appsv1alpha1.ComponentConfigSpec) error { +func deleteConfigMapFinalizer(cli client.Client, ctx intctrlutil.RequestCtx, configSpec appsv1.ComponentConfigSpec) error { cmObj, err := getConfigMapByTemplateName(cli, ctx, configSpec.TemplateRef, configSpec.Namespace) if err != nil && apierrors.IsNotFound(err) { return nil @@ -233,16 +233,16 @@ func deleteConfigMapFinalizer(cli client.Client, ctx intctrlutil.RequestCtx, con return cli.Patch(ctx.Ctx, cmObj, patch) } -type ConfigTemplateHandler func([]appsv1alpha1.ComponentConfigSpec) (bool, error) -type componentValidateHandler func(*appsv1alpha1.ComponentDefinition) error +type ConfigTemplateHandler func([]appsv1.ComponentConfigSpec) (bool, error) +type componentValidateHandler func(*appsv1.ComponentDefinition) error func handleConfigTemplate(object client.Object, handler ConfigTemplateHandler, handler2 ...componentValidateHandler) (bool, error) { var ( err error - configTemplates []appsv1alpha1.ComponentConfigSpec + configTemplates []appsv1.ComponentConfigSpec ) switch cr := object.(type) { - case *appsv1alpha1.ComponentDefinition: + case *appsv1.ComponentDefinition: configTemplates, err = getConfigTemplateFromComponentDef(cr, handler2...) default: return false, core.MakeError("not support CR type: %v", cr) @@ -258,14 +258,14 @@ func handleConfigTemplate(object client.Object, handler ConfigTemplateHandler, h } } -func getConfigTemplateFromComponentDef(componentDef *appsv1alpha1.ComponentDefinition, - validators ...componentValidateHandler) ([]appsv1alpha1.ComponentConfigSpec, error) { - configTemplates := make([]appsv1alpha1.ComponentConfigSpec, 0) +func getConfigTemplateFromComponentDef(componentDef *appsv1.ComponentDefinition, + validators ...componentValidateHandler) ([]appsv1.ComponentConfigSpec, error) { + configTemplates := make([]appsv1.ComponentConfigSpec, 0) // For compatibility with the previous lifecycle management of configurationSpec.TemplateRef, // it is necessary to convert ScriptSpecs to ConfigSpecs, // ensuring that the script-related configmap is not allowed to be deleted. for _, scriptSpec := range componentDef.Spec.Scripts { - configTemplates = append(configTemplates, appsv1alpha1.ComponentConfigSpec{ + configTemplates = append(configTemplates, appsv1.ComponentConfigSpec{ ComponentTemplateSpec: scriptSpec, }) } @@ -281,14 +281,14 @@ func getConfigTemplateFromComponentDef(componentDef *appsv1alpha1.ComponentDefin } func checkConfigTemplate(client client.Client, ctx intctrlutil.RequestCtx, obj client.Object) (bool, error) { - handler := func(configSpecs []appsv1alpha1.ComponentConfigSpec) (bool, error) { + handler := func(configSpecs []appsv1.ComponentConfigSpec) (bool, error) { return validateConfigTemplate(client, ctx, configSpecs) } return handleConfigTemplate(obj, handler) } func updateLabelsByConfigSpec[T generics.Object, PT generics.PObject[T]](cli client.Client, ctx intctrlutil.RequestCtx, obj PT) (bool, error) { - handler := func(configSpecs []appsv1alpha1.ComponentConfigSpec) (bool, error) { + handler := func(configSpecs []appsv1.ComponentConfigSpec) (bool, error) { patch := client.MergeFrom(PT(obj.DeepCopy())) configuration.BuildConfigConstraintLabels(obj, configSpecs) return true, cli.Patch(ctx.Ctx, obj, patch) @@ -296,14 +296,14 @@ func updateLabelsByConfigSpec[T generics.Object, PT generics.PObject[T]](cli cli return handleConfigTemplate(obj, handler) } -func validateConfigTemplate(cli client.Client, ctx intctrlutil.RequestCtx, configSpecs []appsv1alpha1.ComponentConfigSpec) (bool, error) { +func validateConfigTemplate(cli client.Client, ctx intctrlutil.RequestCtx, configSpecs []appsv1.ComponentConfigSpec) (bool, error) { // validate ConfigTemplate - foundAndCheckConfigSpec := func(configSpec appsv1alpha1.ComponentConfigSpec, logger logr.Logger) (*appsv1beta1.ConfigConstraint, error) { + foundAndCheckConfigSpec := func(configSpec appsv1.ComponentConfigSpec, logger logr.Logger) (*appsv1beta1.ConfigConstraint, error) { if _, err := getConfigMapByTemplateName(cli, ctx, configSpec.TemplateRef, configSpec.Namespace); err != nil { logger.Error(err, "failed to get config template cm object!") return nil, err } - if configSpec.VolumeName == "" && !configSpec.InjectEnvEnabled() { + if configSpec.VolumeName == "" && configuration.InjectEnvEnabled(configSpec) { return nil, core.MakeError("config template volume name and envFrom is empty!") } if configSpec.ConfigConstraintRef == "" { diff --git a/controllers/apps/configuration/config_util_test.go b/controllers/apps/configuration/config_util_test.go index 0cd46b262ce..56c8fd1c46e 100644 --- a/controllers/apps/configuration/config_util_test.go +++ b/controllers/apps/configuration/config_util_test.go @@ -27,7 +27,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/log" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1beta1 "github.com/apecloud/kubeblocks/apis/apps/v1beta1" cfgcore "github.com/apecloud/kubeblocks/pkg/configuration/core" intctrlutil "github.com/apecloud/kubeblocks/pkg/controllerutil" @@ -51,7 +51,7 @@ var _ = Describe("ConfigWrapper util test", func() { var ( configMapObj *corev1.ConfigMap configConstraintObj *appsv1beta1.ConfigConstraint - compDefObj *appsv1alpha1.ComponentDefinition + compDefObj *appsv1.ComponentDefinition ) cleanEnv := func() { @@ -162,9 +162,9 @@ var _ = Describe("ConfigWrapper util test", func() { Context("ComponentDefinition CR test without config Constraints", func() { It("Should success without error", func() { // remove ConfigConstraintRef - _, err := handleConfigTemplate(compDefObj, func(templates []appsv1alpha1.ComponentConfigSpec) (bool, error) { + _, err := handleConfigTemplate(compDefObj, func(templates []appsv1.ComponentConfigSpec) (bool, error) { return true, nil - }, func(compDef *appsv1alpha1.ComponentDefinition) error { + }, func(compDef *appsv1.ComponentDefinition) error { if len(compDef.Spec.Configs) == 0 { return nil } diff --git a/controllers/apps/configuration/configconstraint_controller.go b/controllers/apps/configuration/configconstraint_controller.go index 8d9fc988226..e3c6bc56831 100644 --- a/controllers/apps/configuration/configconstraint_controller.go +++ b/controllers/apps/configuration/configconstraint_controller.go @@ -30,6 +30,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/log" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" appsv1beta1 "github.com/apecloud/kubeblocks/apis/apps/v1beta1" cfgcore "github.com/apecloud/kubeblocks/pkg/configuration/core" @@ -85,7 +86,7 @@ func (r *ConfigConstraintReconciler) Reconcile(ctx context.Context, req ctrl.Req } if res, err := intctrlutil.ValidateReferenceCR(reqCtx, r.Client, configConstraint, cfgcore.GenerateConstraintsUniqLabelKeyWithConfig(configConstraint.GetName()), - recordEvent, &appsv1alpha1.ClusterDefinitionList{}, &appsv1alpha1.ComponentDefinitionList{}); res != nil || err != nil { + recordEvent, &appsv1alpha1.ClusterDefinitionList{}, &appsv1.ComponentDefinitionList{}); res != nil || err != nil { return res, err } return nil, nil diff --git a/controllers/apps/configuration/configuration_controller.go b/controllers/apps/configuration/configuration_controller.go index 5ad037c0aaf..6470d2faa35 100644 --- a/controllers/apps/configuration/configuration_controller.go +++ b/controllers/apps/configuration/configuration_controller.go @@ -35,6 +35,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/controller" "sigs.k8s.io/controller-runtime/pkg/log" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" "github.com/apecloud/kubeblocks/pkg/constant" "github.com/apecloud/kubeblocks/pkg/controller/component" @@ -236,7 +237,7 @@ func isFinishStatus(phase appsv1alpha1.ConfigurationPhase) bool { } func buildTemplateVars(ctx context.Context, cli client.Reader, - compDef *appsv1alpha1.ComponentDefinition, synthesizedComp *component.SynthesizedComponent) error { + compDef *appsv1.ComponentDefinition, synthesizedComp *component.SynthesizedComponent) error { if compDef != nil && len(compDef.Spec.Vars) > 0 { templateVars, _, err := component.ResolveTemplateNEnvVars(ctx, cli, synthesizedComp, compDef.Spec.Vars) if err != nil { diff --git a/controllers/apps/configuration/configuration_test.go b/controllers/apps/configuration/configuration_test.go index 64342353d9a..17ffd8d218d 100644 --- a/controllers/apps/configuration/configuration_test.go +++ b/controllers/apps/configuration/configuration_test.go @@ -30,6 +30,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/log" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" appsv1beta1 "github.com/apecloud/kubeblocks/apis/apps/v1beta1" "github.com/apecloud/kubeblocks/pkg/configuration/core" @@ -101,7 +102,7 @@ func mockConfigResource() (*corev1.ConfigMap, *appsv1beta1.ConfigConstraint) { return configmap, constraint } -func mockReconcileResource() (*corev1.ConfigMap, *appsv1beta1.ConfigConstraint, *appsv1alpha1.Cluster, *appsv1alpha1.Component, *component.SynthesizedComponent) { +func mockReconcileResource() (*corev1.ConfigMap, *appsv1beta1.ConfigConstraint, *appsv1alpha1.Cluster, *appsv1.Component, *component.SynthesizedComponent) { configmap, constraint := mockConfigResource() By("Create a component definition obj and mock to available") @@ -113,8 +114,8 @@ func mockReconcileResource() (*corev1.ConfigMap, *appsv1beta1.ConfigConstraint, core.GenerateConstraintsUniqLabelKeyWithConfig(constraint.Name), constraint.Name). Create(&testCtx). GetObject() - Expect(testapps.GetAndChangeObjStatus(&testCtx, client.ObjectKeyFromObject(compDefObj), func(obj *appsv1alpha1.ComponentDefinition) { - obj.Status.Phase = appsv1alpha1.AvailablePhase + Expect(testapps.GetAndChangeObjStatus(&testCtx, client.ObjectKeyFromObject(compDefObj), func(obj *appsv1.ComponentDefinition) { + obj.Status.Phase = appsv1.AvailablePhase })()).Should(Succeed()) By("Creating a cluster") @@ -159,7 +160,7 @@ func mockReconcileResource() (*corev1.ConfigMap, *appsv1beta1.ConfigConstraint, func initConfiguration(resourceCtx *configctrl.ResourceCtx, synthesizedComponent *component.SynthesizedComponent, clusterObj *appsv1alpha1.Cluster, - componentObj *appsv1alpha1.Component) error { + componentObj *appsv1.Component) error { return configctrl.NewCreatePipeline(configctrl.ReconcileCtx{ ResourceCtx: resourceCtx, Component: componentObj, diff --git a/controllers/apps/configuration/policy_util_test.go b/controllers/apps/configuration/policy_util_test.go index 4fbd815dd63..0efbfa09431 100644 --- a/controllers/apps/configuration/policy_util_test.go +++ b/controllers/apps/configuration/policy_util_test.go @@ -32,6 +32,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/log" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" appsv1beta1 "github.com/apecloud/kubeblocks/apis/apps/v1beta1" workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" @@ -162,7 +163,7 @@ func newMockReconfigureParams(testName string, cli client.Client, paramOps ...Pa }, SynthesizedComponent: &component.SynthesizedComponent{ MinReadySeconds: 5, - Roles: []appsv1alpha1.ReplicaRole{ + Roles: []appsv1.ReplicaRole{ { Name: "leader", Serviceable: true, diff --git a/controllers/apps/configuration/reconcile_task.go b/controllers/apps/configuration/reconcile_task.go index 77557471f5f..e1a025264be 100644 --- a/controllers/apps/configuration/reconcile_task.go +++ b/controllers/apps/configuration/reconcile_task.go @@ -24,9 +24,11 @@ import ( corev1 "k8s.io/api/core/v1" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" "github.com/apecloud/kubeblocks/pkg/configuration/core" cfgutil "github.com/apecloud/kubeblocks/pkg/configuration/util" + "github.com/apecloud/kubeblocks/pkg/controller/builder" "github.com/apecloud/kubeblocks/pkg/controller/component" configctrl "github.com/apecloud/kubeblocks/pkg/controller/configuration" intctrlutil "github.com/apecloud/kubeblocks/pkg/controllerutil" @@ -65,7 +67,7 @@ func NewTask(item appsv1alpha1.ConfigurationItemDetail, status *appsv1alpha1.Con return syncStatus(configMap, status) case appsv1alpha1.CPendingPhase, appsv1alpha1.CMergeFailedPhase: - return syncImpl(fetcher, item, status, synComponent, revision, configSpec) + return syncImpl(fetcher, item, status, synComponent, revision, builder.ToV1ConfigSpec(configSpec)) case appsv1alpha1.CCreatingPhase: return nil } @@ -79,7 +81,7 @@ func syncImpl(fetcher *Task, status *appsv1alpha1.ConfigurationItemDetailStatus, synthesizedComponent *component.SynthesizedComponent, revision string, - configSpec *appsv1alpha1.ComponentConfigSpec) (err error) { + configSpec *appsv1.ComponentConfigSpec) (err error) { err = configctrl.NewReconcilePipeline(configctrl.ReconcileCtx{ ResourceCtx: fetcher.ResourceCtx, Cluster: fetcher.ClusterObj, diff --git a/controllers/apps/operations/custom.go b/controllers/apps/operations/custom.go index eb5810e115e..1b4dbcd12cc 100644 --- a/controllers/apps/operations/custom.go +++ b/controllers/apps/operations/custom.go @@ -30,6 +30,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/client" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" "github.com/apecloud/kubeblocks/pkg/common" "github.com/apecloud/kubeblocks/pkg/constant" @@ -126,14 +127,14 @@ func (c CustomOpsHandler) SaveLastConfiguration(reqCtx intctrlutil.RequestCtx, c func (c CustomOpsHandler) listComponents(reqCtx intctrlutil.RequestCtx, cli client.Client, cluster *appsv1alpha1.Cluster, - componentName string) ([]appsv1alpha1.Component, error) { + componentName string) ([]appsv1.Component, error) { if cluster.Spec.GetComponentByName(componentName) != nil { comp, err := component.GetComponentByName(reqCtx.Ctx, cli, cluster.Namespace, constant.GenerateClusterComponentName(cluster.Name, componentName)) if err != nil { return nil, err } - return []appsv1alpha1.Component{*comp}, nil + return []appsv1.Component{*comp}, nil } return intctrlutil.ListShardingComponents(reqCtx.Ctx, cli, cluster, componentName) } diff --git a/controllers/apps/operations/custom_test.go b/controllers/apps/operations/custom_test.go index f43266c40d3..6ec6197fd39 100644 --- a/controllers/apps/operations/custom_test.go +++ b/controllers/apps/operations/custom_test.go @@ -22,11 +22,13 @@ package operations import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" + batchv1 "k8s.io/api/batch/v1" corev1 "k8s.io/api/core/v1" "sigs.k8s.io/controller-runtime/pkg/client" logf "sigs.k8s.io/controller-runtime/pkg/log" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" "github.com/apecloud/kubeblocks/pkg/constant" intctrlutil "github.com/apecloud/kubeblocks/pkg/controllerutil" @@ -40,7 +42,7 @@ var _ = Describe("CustomOps", func() { compDefName = "test-compdef-" + randomStr clusterName = "test-cluster-" + randomStr opsResource *OpsResource - compObj *appsv1alpha1.Component + compObj *appsv1.Component opsDef *appsv1alpha1.OpsDefinition reqCtx intctrlutil.RequestCtx cluster *appsv1alpha1.Cluster @@ -182,7 +184,7 @@ var _ = Describe("CustomOps", func() { By("mock component is Running") Expect(testapps.ChangeObjStatus(&testCtx, compObj, func() { - compObj.Status.Phase = appsv1alpha1.RunningClusterCompPhase + compObj.Status.Phase = appsv1.RunningClusterCompPhase })).Should(Succeed()) By("job should be created successfully") diff --git a/controllers/apps/operations/ops_comp_helper.go b/controllers/apps/operations/ops_comp_helper.go index 7ba80e0d2db..77a69f429c6 100644 --- a/controllers/apps/operations/ops_comp_helper.go +++ b/controllers/apps/operations/ops_comp_helper.go @@ -28,6 +28,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" "github.com/apecloud/kubeblocks/pkg/constant" "github.com/apecloud/kubeblocks/pkg/controller/component" @@ -161,7 +162,7 @@ func (c componentOpsHelper) reconcileActionWithComponentOps(reqCtx intctrlutil.R completedProgressCount int32 requeueTimeAfterFailed time.Duration err error - clusterDef *appsv1alpha1.ClusterDefinition + clusterDef *appsv1.ClusterDefinition ) if opsRes.Cluster.Spec.ClusterDefRef != "" { if clusterDef, err = getClusterDefByName(reqCtx.Ctx, cli, opsRes.Cluster.Spec.ClusterDefRef); err != nil { @@ -177,9 +178,9 @@ func (c componentOpsHelper) reconcileActionWithComponentOps(reqCtx intctrlutil.R var progressResources []progressResource setProgressResource := func(compSpec *appsv1alpha1.ClusterComponentSpec, compOps ComponentOpsInterface, fullComponentName string, isShardingComponent bool) error { - var componentDefinition *appsv1alpha1.ComponentDefinition + var componentDefinition *appsv1.ComponentDefinition if compSpec.ComponentDef != "" { - componentDefinition = &appsv1alpha1.ComponentDefinition{} + componentDefinition = &appsv1.ComponentDefinition{} if err = cli.Get(reqCtx.Ctx, client.ObjectKey{Name: compSpec.ComponentDef}, componentDefinition); err != nil { return err } @@ -258,7 +259,7 @@ func (c componentOpsHelper) reconcileActionWithComponentOps(reqCtx intctrlutil.R if err != nil { return opsRequestPhase, 0, err } - componentPhase = compObj.Status.Phase + componentPhase = appsv1alpha1.ClusterComponentPhase(compObj.Status.Phase) } // conditions whether ops is running: // 1. completedProgressCount is not equal to expectProgressCount when the ops do not need to wait component phase to a terminal phase. diff --git a/controllers/apps/operations/ops_util.go b/controllers/apps/operations/ops_util.go index 598032da878..82221a5e1d6 100644 --- a/controllers/apps/operations/ops_util.go +++ b/controllers/apps/operations/ops_util.go @@ -22,6 +22,7 @@ package operations import ( "context" "fmt" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" "time" "golang.org/x/exp/slices" @@ -58,8 +59,8 @@ type handleStatusProgressWithComponent func(reqCtx intctrlutil.RequestCtx, type handleReconfigureOpsStatus func(cmStatus *appsv1alpha1.ConfigurationItemStatus) error // getClusterDefByName gets the ClusterDefinition object by the name. -func getClusterDefByName(ctx context.Context, cli client.Client, clusterDefName string) (*appsv1alpha1.ClusterDefinition, error) { - clusterDef := &appsv1alpha1.ClusterDefinition{} +func getClusterDefByName(ctx context.Context, cli client.Client, clusterDefName string) (*appsv1.ClusterDefinition, error) { + clusterDef := &appsv1.ClusterDefinition{} if err := cli.Get(ctx, client.ObjectKey{Name: clusterDefName}, clusterDef); err != nil { return nil, err } diff --git a/controllers/apps/operations/reconfigure_test.go b/controllers/apps/operations/reconfigure_test.go index d08d52d0009..12b2fd403e2 100644 --- a/controllers/apps/operations/reconfigure_test.go +++ b/controllers/apps/operations/reconfigure_test.go @@ -30,6 +30,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/log" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" appsv1beta1 "github.com/apecloud/kubeblocks/apis/apps/v1beta1" opsutil "github.com/apecloud/kubeblocks/controllers/apps/operations/util" @@ -90,7 +91,7 @@ var _ = Describe("Reconfigure OpsRequest", func() { return cfgCM, cfgTpl } - assureConfigInstanceObj := func(clusterName, componentName, ns string, compDef *appsv1alpha1.ComponentDefinition) (*appsv1alpha1.Configuration, *corev1.ConfigMap) { + assureConfigInstanceObj := func(clusterName, componentName, ns string, compDef *appsv1.ComponentDefinition) (*appsv1alpha1.Configuration, *corev1.ConfigMap) { if len(compDef.Spec.Configs) == 0 { return nil, nil } @@ -158,8 +159,8 @@ var _ = Describe("Reconfigure OpsRequest", func() { By("update clusterdefinition tpl") patch := client.MergeFrom(compDef.DeepCopy()) - compDef.Spec.Configs = []appsv1alpha1.ComponentConfigSpec{{ - ComponentTemplateSpec: appsv1alpha1.ComponentTemplateSpec{ + compDef.Spec.Configs = []appsv1.ComponentConfigSpec{{ + ComponentTemplateSpec: appsv1.ComponentTemplateSpec{ Name: "mysql-test", TemplateRef: cmObj.Name, VolumeName: "mysql-config", diff --git a/controllers/apps/operations/suite_test.go b/controllers/apps/operations/suite_test.go index 2f0f58fa737..71cbc7c88c3 100644 --- a/controllers/apps/operations/suite_test.go +++ b/controllers/apps/operations/suite_test.go @@ -40,6 +40,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/log/zap" "sigs.k8s.io/controller-runtime/pkg/metrics/server" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" appsv1beta1 "github.com/apecloud/kubeblocks/apis/apps/v1beta1" dpv1alpha1 "github.com/apecloud/kubeblocks/apis/dataprotection/v1alpha1" @@ -146,7 +147,7 @@ var _ = AfterSuite(func() { Expect(err).NotTo(HaveOccurred()) }) -func initOperationsResources(compDefName, clusterName string) (*OpsResource, *appsv1alpha1.ComponentDefinition, *appsv1alpha1.Cluster) { +func initOperationsResources(compDefName, clusterName string) (*OpsResource, *appsv1.ComponentDefinition, *appsv1alpha1.Cluster) { compDef := testapps.NewComponentDefinitionFactory(compDefName). SetDefaultSpec(). Create(&testCtx). diff --git a/controllers/apps/operations/switchover_test.go b/controllers/apps/operations/switchover_test.go index 0bad677155b..a17d7dd9a23 100644 --- a/controllers/apps/operations/switchover_test.go +++ b/controllers/apps/operations/switchover_test.go @@ -30,6 +30,7 @@ import ( "k8s.io/apimachinery/pkg/types" "sigs.k8s.io/controller-runtime/pkg/client" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" "github.com/apecloud/kubeblocks/pkg/constant" intctrlutil "github.com/apecloud/kubeblocks/pkg/controllerutil" @@ -42,7 +43,7 @@ var _ = Describe("", func() { randomStr = testCtx.GetRandomStr() compDefName = "test-compdef-" + randomStr clusterName = "test-cluster-" + randomStr - compDefObj *appsv1alpha1.ComponentDefinition + compDefObj *appsv1.ComponentDefinition clusterObj *appsv1alpha1.Cluster ) diff --git a/controllers/apps/operations/switchover_util.go b/controllers/apps/operations/switchover_util.go index 22bacdec65f..4eee3c32958 100644 --- a/controllers/apps/operations/switchover_util.go +++ b/controllers/apps/operations/switchover_util.go @@ -32,6 +32,7 @@ import ( "k8s.io/apimachinery/pkg/types" "sigs.k8s.io/controller-runtime/pkg/client" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" "github.com/apecloud/kubeblocks/pkg/constant" "github.com/apecloud/kubeblocks/pkg/controller/component" @@ -187,7 +188,7 @@ func renderSwitchoverCmdJob(ctx context.Context, return nil, errors.New("serviceable and writable pod not found") } - renderJob := func(switchoverSpec *appsv1alpha1.Action, switchoverEnvs []corev1.EnvVar) (*batchv1.Job, error) { + renderJob := func(switchoverSpec *appsv1.Action, switchoverEnvs []corev1.EnvVar) (*batchv1.Job, error) { if switchoverSpec == nil { return nil, errors.New("switchover exec action not found") } diff --git a/controllers/apps/operations/type.go b/controllers/apps/operations/type.go index 899c840573a..edc1157f5f7 100644 --- a/controllers/apps/operations/type.go +++ b/controllers/apps/operations/type.go @@ -20,6 +20,7 @@ along with this program. If not, see . package operations import ( + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" "time" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -105,8 +106,8 @@ type progressResource struct { // checks if the component is a sharding component isShardingComponent bool clusterComponent *appsv1alpha1.ClusterComponentSpec - clusterDef *appsv1alpha1.ClusterDefinition - componentDef *appsv1alpha1.ComponentDefinition + clusterDef *appsv1.ClusterDefinition + componentDef *appsv1.ComponentDefinition // record which pods need to updated during this operation. // key is podName, value is instance template name. updatedPodSet map[string]string diff --git a/controllers/apps/operations/upgrade.go b/controllers/apps/operations/upgrade.go index ec3a5e51157..98c0b97fb85 100644 --- a/controllers/apps/operations/upgrade.go +++ b/controllers/apps/operations/upgrade.go @@ -27,6 +27,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/client" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" "github.com/apecloud/kubeblocks/pkg/controller/component" intctrlutil "github.com/apecloud/kubeblocks/pkg/controllerutil" @@ -99,7 +100,7 @@ func (u upgradeOpsHandler) ReconcileAction(reqCtx intctrlutil.RequestCtx, cli cl upgradeSpec := opsRes.OpsRequest.Spec.Upgrade var ( compOpsHelper componentOpsHelper - componentDefMap map[string]*appsv1alpha1.ComponentDefinition + componentDefMap map[string]*appsv1.ComponentDefinition err error ) if u.existClusterVersion(opsRes.OpsRequest) { @@ -168,8 +169,8 @@ func (u upgradeOpsHandler) SaveLastConfiguration(reqCtx intctrlutil.RequestCtx, // that is updated with the corresponding images of the ComponentDefinition and service version. func (u upgradeOpsHandler) getComponentDefMapWithUpdatedImages(reqCtx intctrlutil.RequestCtx, cli client.Client, - opsRes *OpsResource) (map[string]*appsv1alpha1.ComponentDefinition, error) { - compDefMap := map[string]*appsv1alpha1.ComponentDefinition{} + opsRes *OpsResource) (map[string]*appsv1.ComponentDefinition, error) { + compDefMap := map[string]*appsv1.ComponentDefinition{} for _, v := range opsRes.OpsRequest.Spec.Upgrade.Components { compSpec := getComponentSpecOrShardingTemplate(opsRes.Cluster, v.ComponentName) if compSpec == nil { diff --git a/controllers/apps/operations/upgrade_test.go b/controllers/apps/operations/upgrade_test.go index 53a57c30f0b..bd5c576d7e9 100644 --- a/controllers/apps/operations/upgrade_test.go +++ b/controllers/apps/operations/upgrade_test.go @@ -91,7 +91,7 @@ var _ = Describe("Upgrade OpsRequest", func() { })).Should(Succeed()) } - initOpsResWithComponentDef := func(createCompVersion bool) (*appsv1alpha1.ComponentDefinition, *appsv1alpha1.ComponentDefinition, *OpsResource) { + initOpsResWithComponentDef := func(createCompVersion bool) (*appsv1.ComponentDefinition, *appsv1.ComponentDefinition, *OpsResource) { compDef1 := testapps.NewComponentDefinitionFactory(testapps.CompDefName("cmpd-1")). SetServiceVersion(testapps.ServiceVersion(serviceVer0)). SetRuntime(&corev1.Container{ diff --git a/controllers/apps/opsrequest_controller_test.go b/controllers/apps/opsrequest_controller_test.go index 82f34c71718..c57a7c62adb 100644 --- a/controllers/apps/opsrequest_controller_test.go +++ b/controllers/apps/opsrequest_controller_test.go @@ -38,6 +38,7 @@ import ( "k8s.io/utils/pointer" "sigs.k8s.io/controller-runtime/pkg/client" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" dpv1alpha1 "github.com/apecloud/kubeblocks/apis/dataprotection/v1alpha1" workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" @@ -100,7 +101,7 @@ var _ = Describe("OpsRequest Controller", func() { }) var ( - compDefObj *appsv1alpha1.ComponentDefinition + compDefObj *appsv1.ComponentDefinition clusterObj *appsv1alpha1.Cluster clusterKey types.NamespacedName ) @@ -277,7 +278,7 @@ var _ = Describe("OpsRequest Controller", func() { Namespace: clusterKey.Namespace, Name: component.FullName(clusterKey.Name, mysqlCompName), } - Eventually(testapps.CheckObj(&testCtx, compKey, func(g Gomega, comp *appsv1alpha1.Component) { + Eventually(testapps.CheckObj(&testCtx, compKey, func(g Gomega, comp *appsv1.Component) { g.Expect(comp.Generation).Should(Equal(comp.Status.ObservedGeneration)) })).Should(Succeed()) @@ -314,7 +315,7 @@ var _ = Describe("OpsRequest Controller", func() { testk8s.MockEnableVolumeSnapshot(&testCtx, testk8s.DefaultStorageClassName) Expect(testapps.GetAndChangeObj(&testCtx, client.ObjectKeyFromObject(compDefObj), - func(compDef *appsv1alpha1.ComponentDefinition) { + func(compDef *appsv1.ComponentDefinition) { if compDef.Annotations == nil { compDef.Annotations = map[string]string{} } diff --git a/controllers/apps/transformer_cluster_api_normalization.go b/controllers/apps/transformer_cluster_api_normalization.go index c0557442ebe..882f6fa2848 100644 --- a/controllers/apps/transformer_cluster_api_normalization.go +++ b/controllers/apps/transformer_cluster_api_normalization.go @@ -205,7 +205,7 @@ func (t *ClusterAPINormalizationTransformer) buildCompAnnotationsInheritedFromCl func (t *ClusterAPINormalizationTransformer) resolveCompDefinitions(transCtx *clusterTransformContext) error { if transCtx.ComponentDefs == nil { - transCtx.ComponentDefs = make(map[string]*appsv1alpha1.ComponentDefinition) + transCtx.ComponentDefs = make(map[string]*appsv1.ComponentDefinition) } for i, compSpec := range transCtx.ComponentSpecs { compDef, serviceVersion, err := t.resolveCompDefinitionNServiceVersion(transCtx, compSpec) @@ -221,7 +221,7 @@ func (t *ClusterAPINormalizationTransformer) resolveCompDefinitions(transCtx *cl } func (t *ClusterAPINormalizationTransformer) resolveCompDefinitionNServiceVersion(transCtx *clusterTransformContext, - compSpec *appsv1alpha1.ClusterComponentSpec) (*appsv1alpha1.ComponentDefinition, string, error) { + compSpec *appsv1alpha1.ClusterComponentSpec) (*appsv1.ComponentDefinition, string, error) { if withClusterLegacyDefinition(transCtx.Cluster) || withClusterSimplifiedAPI(transCtx.Cluster) { return nil, "", fmt.Errorf("legacy cluster definition or simplified API are not supported") } @@ -229,13 +229,13 @@ func (t *ClusterAPINormalizationTransformer) resolveCompDefinitionNServiceVersio } func (t *ClusterAPINormalizationTransformer) resolveCompDefinitionNServiceVersionWithUpgrade(transCtx *clusterTransformContext, - compSpec *appsv1alpha1.ClusterComponentSpec) (*appsv1alpha1.ComponentDefinition, string, error) { + compSpec *appsv1alpha1.ClusterComponentSpec) (*appsv1.ComponentDefinition, string, error) { var ( ctx = transCtx.Context cli = transCtx.Client cluster = transCtx.Cluster ) - comp := &appsv1alpha1.Component{} + comp := &appsv1.Component{} err := cli.Get(ctx, types.NamespacedName{Namespace: cluster.Namespace, Name: component.FullName(cluster.Name, compSpec.Name)}, comp) if err != nil && !apierrors.IsNotFound(err) { return nil, "", err @@ -247,7 +247,7 @@ func (t *ClusterAPINormalizationTransformer) resolveCompDefinitionNServiceVersio return resolveCompDefinitionNServiceVersion(ctx, cli, comp.Spec.CompDef, comp.Spec.ServiceVersion) } -func (t *ClusterAPINormalizationTransformer) checkCompUpgrade(compSpec *appsv1alpha1.ClusterComponentSpec, comp *appsv1alpha1.Component) bool { +func (t *ClusterAPINormalizationTransformer) checkCompUpgrade(compSpec *appsv1alpha1.ClusterComponentSpec, comp *appsv1.Component) bool { return compSpec.ServiceVersion != comp.Spec.ServiceVersion || compSpec.ComponentDef != comp.Spec.CompDef } diff --git a/controllers/apps/transformer_cluster_component.go b/controllers/apps/transformer_cluster_component.go index bbdd5998075..b22b5caebc5 100644 --- a/controllers/apps/transformer_cluster_component.go +++ b/controllers/apps/transformer_cluster_component.go @@ -32,6 +32,7 @@ import ( "k8s.io/apimachinery/pkg/util/sets" "sigs.k8s.io/controller-runtime/pkg/client" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" "github.com/apecloud/kubeblocks/pkg/constant" "github.com/apecloud/kubeblocks/pkg/controller/component" @@ -156,7 +157,7 @@ func handleCompsInOrder(transCtx *clusterTransformContext, dag *graph.DAG, } func checkAllCompsUpToDate(transCtx *clusterTransformContext, cluster *appsv1alpha1.Cluster) (bool, error) { - compList := &appsv1alpha1.ComponentList{} + compList := &appsv1.ComponentList{} labels := constant.GetClusterWellKnownLabels(cluster.Name) if err := transCtx.Client.List(transCtx.Context, compList, client.InNamespace(cluster.Namespace), client.MatchingLabels(labels)); err != nil { return false, err @@ -177,12 +178,12 @@ func checkAllCompsUpToDate(transCtx *clusterTransformContext, cluster *appsv1alp } // getRunningCompObject gets the component object from cache snapshot -func getRunningCompObject(transCtx *clusterTransformContext, cluster *appsv1alpha1.Cluster, compName string) (*appsv1alpha1.Component, error) { +func getRunningCompObject(transCtx *clusterTransformContext, cluster *appsv1alpha1.Cluster, compName string) (*appsv1.Component, error) { compKey := types.NamespacedName{ Namespace: cluster.Namespace, Name: component.FullName(cluster.Name, compName), } - comp := &appsv1alpha1.Component{} + comp := &appsv1.Component{} if err := transCtx.Client.Get(transCtx.Context, compKey, comp); err != nil { return nil, err } @@ -192,7 +193,7 @@ func getRunningCompObject(transCtx *clusterTransformContext, cluster *appsv1alph // copyAndMergeComponent merges two component objects for updating: // 1. new a component object targetCompObj by copying from oldCompObj // 2. merge all fields can be updated from newCompObj into targetCompObj -func copyAndMergeComponent(oldCompObj, newCompObj *appsv1alpha1.Component) *appsv1alpha1.Component { +func copyAndMergeComponent(oldCompObj, newCompObj *appsv1.Component) *appsv1.Component { compObjCopy := oldCompObj.DeepCopy() compProto := newCompObj @@ -220,8 +221,7 @@ func copyAndMergeComponent(oldCompObj, newCompObj *appsv1alpha1.Component) *apps compObjCopy.Spec.ServiceAccountName = compProto.Spec.ServiceAccountName compObjCopy.Spec.ParallelPodManagementConcurrency = compProto.Spec.ParallelPodManagementConcurrency compObjCopy.Spec.PodUpdatePolicy = compProto.Spec.PodUpdatePolicy - compObjCopy.Spec.Affinity = compProto.Spec.Affinity - compObjCopy.Spec.Tolerations = compProto.Spec.Tolerations + compObjCopy.Spec.SchedulingPolicy = compProto.Spec.SchedulingPolicy compObjCopy.Spec.TLSConfig = compProto.Spec.TLSConfig compObjCopy.Spec.Instances = compProto.Spec.Instances compObjCopy.Spec.OfflineInstances = compProto.Spec.OfflineInstances @@ -306,10 +306,10 @@ func newParallelHandler(compSpecs map[string]*appsv1alpha1.ClusterComponentSpec, func newOrderedHandler(compSpecs map[string]*appsv1alpha1.ClusterComponentSpec, labels, annotations map[string]map[string]string, orders []string, op int) compConditionalHandler { - upworking := func(comp *appsv1alpha1.Component) bool { - target := appsv1alpha1.RunningClusterCompPhase + upworking := func(comp *appsv1.Component) bool { + target := appsv1.RunningClusterCompPhase if comp.Spec.Stop != nil && *comp.Spec.Stop { - target = appsv1alpha1.StoppedClusterCompPhase + target = appsv1.StoppedClusterCompPhase } return comp.Status.Phase == target } @@ -441,7 +441,7 @@ func (c *compNotExistPrecondition) match(transCtx *clusterTransformContext, dag type compPhasePrecondition struct { orders []string - phaseExpectation func(component2 *appsv1alpha1.Component) bool + phaseExpectation func(component2 *appsv1.Component) bool } func (c *compPhasePrecondition) match(transCtx *clusterTransformContext, dag *graph.DAG, compName string) (bool, error) { @@ -455,7 +455,7 @@ func (c *compPhasePrecondition) match(transCtx *clusterTransformContext, dag *gr return false } for _, predecessor := range predecessors(c.orders, compName) { - comp := &appsv1alpha1.Component{} + comp := &appsv1.Component{} compKey := types.NamespacedName{ Namespace: transCtx.Cluster.Namespace, Name: component.FullName(transCtx.Cluster.Name, predecessor), diff --git a/controllers/apps/transformer_cluster_component_status.go b/controllers/apps/transformer_cluster_component_status.go index fc073524f7e..440ab331f15 100644 --- a/controllers/apps/transformer_cluster_component_status.go +++ b/controllers/apps/transformer_cluster_component_status.go @@ -28,6 +28,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" "github.com/apecloud/kubeblocks/pkg/controller/component" "github.com/apecloud/kubeblocks/pkg/controller/graph" @@ -63,7 +64,7 @@ func (t *clusterComponentStatusTransformer) reconcileComponentsStatus(transCtx * Namespace: cluster.Namespace, Name: component.FullName(cluster.Name, compSpec.Name), } - comp := &appsv1alpha1.Component{} + comp := &appsv1.Component{} if err := transCtx.Client.Get(transCtx.Context, compKey, comp); err != nil { if apierrors.IsNotFound(err) { continue @@ -77,7 +78,7 @@ func (t *clusterComponentStatusTransformer) reconcileComponentsStatus(transCtx * // buildClusterCompStatus builds cluster component status from specified component object. func (t *clusterComponentStatusTransformer) buildClusterCompStatus(transCtx *clusterTransformContext, - comp *appsv1alpha1.Component, compName string) appsv1alpha1.ClusterComponentStatus { + comp *appsv1.Component, compName string) appsv1alpha1.ClusterComponentStatus { var ( cluster = transCtx.Cluster status = cluster.Status.Components[compName] @@ -99,9 +100,9 @@ func (t *clusterComponentStatusTransformer) buildClusterCompStatus(transCtx *clu } // updateClusterComponentStatus sets the cluster component phase and messages conditionally. -func (t *clusterComponentStatusTransformer) updateClusterComponentStatus(comp *appsv1alpha1.Component, +func (t *clusterComponentStatusTransformer) updateClusterComponentStatus(comp *appsv1.Component, status *appsv1alpha1.ClusterComponentStatus) { - if status.Phase != comp.Status.Phase { + if string(status.Phase) != string(comp.Status.Phase) { status.Phase = comp.Status.Phase if status.Message == nil { status.Message = comp.Status.Message @@ -122,11 +123,11 @@ func (t *clusterComponentStatusTransformer) updateClusterComponentStatus(comp *a } } -func (t *clusterComponentStatusTransformer) isClusterComponentPodsReady(phase appsv1alpha1.ClusterComponentPhase) bool { - podsReadyPhases := []appsv1alpha1.ClusterComponentPhase{ - appsv1alpha1.RunningClusterCompPhase, - appsv1alpha1.StoppingClusterCompPhase, - appsv1alpha1.StoppedClusterCompPhase, +func (t *clusterComponentStatusTransformer) isClusterComponentPodsReady(phase appsv1.ClusterComponentPhase) bool { + podsReadyPhases := []appsv1.ClusterComponentPhase{ + appsv1.RunningClusterCompPhase, + appsv1.StoppingClusterCompPhase, + appsv1.StoppedClusterCompPhase, } return slices.Contains(podsReadyPhases, phase) } diff --git a/controllers/apps/transformer_cluster_component_test.go b/controllers/apps/transformer_cluster_component_test.go index e36a179ef44..9c7638cdebb 100644 --- a/controllers/apps/transformer_cluster_component_test.go +++ b/controllers/apps/transformer_cluster_component_test.go @@ -219,7 +219,7 @@ var _ = Describe("cluster component transformer test", func() { return compSpecs } - mockCompObj := func(transCtx *clusterTransformContext, compName string, setters ...func(*appsv1alpha1.Component)) *appsv1alpha1.Component { + mockCompObj := func(transCtx *clusterTransformContext, compName string, setters ...func(*appsv1.Component)) *appsv1.Component { var compSpec *appsv1alpha1.ClusterComponentSpec for i, spec := range transCtx.ComponentSpecs { if spec.Name == compName { @@ -269,10 +269,10 @@ var _ = Describe("cluster component transformer test", func() { // check the components graphCli := transCtx.Client.(model.GraphClient) - objs := graphCli.FindAll(dag, &appsv1alpha1.Component{}) + objs := graphCli.FindAll(dag, &appsv1.Component{}) Expect(len(objs)).Should(Equal(4)) for _, obj := range objs { - comp := obj.(*appsv1alpha1.Component) + comp := obj.(*appsv1.Component) Expect(graphCli.IsAction(dag, comp, model.ActionCreatePtr())).Should(BeTrue()) } }) @@ -285,10 +285,10 @@ var _ = Describe("cluster component transformer test", func() { // check the first two components graphCli := transCtx.Client.(model.GraphClient) - objs := graphCli.FindAll(dag, &appsv1alpha1.Component{}) + objs := graphCli.FindAll(dag, &appsv1.Component{}) Expect(len(objs)).Should(Equal(2)) for _, obj := range objs { - comp := obj.(*appsv1alpha1.Component) + comp := obj.(*appsv1.Component) Expect(component.ShortName(transCtx.Cluster.Name, comp.Name)).Should(Or(Equal(comp1aName), Equal(comp1bName))) Expect(graphCli.IsAction(dag, comp, model.ActionCreatePtr())).Should(BeTrue()) } @@ -300,11 +300,11 @@ var _ = Describe("cluster component transformer test", func() { // mock first two components status as running and creating reader := &mockReader{ objs: []client.Object{ - mockCompObj(transCtx, comp1aName, func(comp *appsv1alpha1.Component) { - comp.Status.Phase = appsv1alpha1.RunningClusterCompPhase + mockCompObj(transCtx, comp1aName, func(comp *appsv1.Component) { + comp.Status.Phase = appsv1.RunningClusterCompPhase }), - mockCompObj(transCtx, comp1bName, func(comp *appsv1alpha1.Component) { - comp.Status.Phase = appsv1alpha1.CreatingClusterCompPhase + mockCompObj(transCtx, comp1bName, func(comp *appsv1.Component) { + comp.Status.Phase = appsv1.CreatingClusterCompPhase }), }, } @@ -316,7 +316,7 @@ var _ = Describe("cluster component transformer test", func() { // should have no components to update graphCli := transCtx.Client.(model.GraphClient) - objs := graphCli.FindAll(dag, &appsv1alpha1.Component{}) + objs := graphCli.FindAll(dag, &appsv1.Component{}) Expect(len(objs)).Should(Equal(0)) }) @@ -326,8 +326,8 @@ var _ = Describe("cluster component transformer test", func() { // mock one of first two components status as running reader := &mockReader{ objs: []client.Object{ - mockCompObj(transCtx, comp1aName, func(comp *appsv1alpha1.Component) { - comp.Status.Phase = appsv1alpha1.RunningClusterCompPhase + mockCompObj(transCtx, comp1aName, func(comp *appsv1.Component) { + comp.Status.Phase = appsv1.RunningClusterCompPhase }), }, } @@ -339,9 +339,9 @@ var _ = Describe("cluster component transformer test", func() { // should have one component to create graphCli := transCtx.Client.(model.GraphClient) - objs := graphCli.FindAll(dag, &appsv1alpha1.Component{}) + objs := graphCli.FindAll(dag, &appsv1.Component{}) Expect(len(objs)).Should(Equal(1)) - comp := objs[0].(*appsv1alpha1.Component) + comp := objs[0].(*appsv1.Component) Expect(component.ShortName(transCtx.Cluster.Name, comp.Name)).Should(Equal(comp1bName)) Expect(graphCli.IsAction(dag, comp, model.ActionCreatePtr())).Should(BeTrue()) }) @@ -352,11 +352,11 @@ var _ = Describe("cluster component transformer test", func() { // mock first two components status as running reader := &mockReader{ objs: []client.Object{ - mockCompObj(transCtx, comp1aName, func(comp *appsv1alpha1.Component) { - comp.Status.Phase = appsv1alpha1.RunningClusterCompPhase + mockCompObj(transCtx, comp1aName, func(comp *appsv1.Component) { + comp.Status.Phase = appsv1.RunningClusterCompPhase }), - mockCompObj(transCtx, comp1bName, func(comp *appsv1alpha1.Component) { - comp.Status.Phase = appsv1alpha1.RunningClusterCompPhase + mockCompObj(transCtx, comp1bName, func(comp *appsv1.Component) { + comp.Status.Phase = appsv1.RunningClusterCompPhase }), }, } @@ -367,10 +367,10 @@ var _ = Describe("cluster component transformer test", func() { // check the last two components graphCli := transCtx.Client.(model.GraphClient) - objs := graphCli.FindAll(dag, &appsv1alpha1.Component{}) + objs := graphCli.FindAll(dag, &appsv1.Component{}) Expect(len(objs)).Should(Equal(2)) for _, obj := range objs { - comp := obj.(*appsv1alpha1.Component) + comp := obj.(*appsv1.Component) Expect(component.ShortName(transCtx.Cluster.Name, comp.Name)).Should(Or(Equal(comp2aName), Equal(comp2bName))) Expect(graphCli.IsAction(dag, comp, model.ActionCreatePtr())).Should(BeTrue()) } @@ -382,12 +382,12 @@ var _ = Describe("cluster component transformer test", func() { // mock first two components reader := &mockReader{ objs: []client.Object{ - mockCompObj(transCtx, comp1aName, func(comp *appsv1alpha1.Component) { + mockCompObj(transCtx, comp1aName, func(comp *appsv1.Component) { comp.Spec.Replicas = 2 // to update - comp.Status.Phase = appsv1alpha1.RunningClusterCompPhase + comp.Status.Phase = appsv1.RunningClusterCompPhase }), - mockCompObj(transCtx, comp1bName, func(comp *appsv1alpha1.Component) { - comp.Status.Phase = appsv1alpha1.RunningClusterCompPhase + mockCompObj(transCtx, comp1bName, func(comp *appsv1.Component) { + comp.Status.Phase = appsv1.RunningClusterCompPhase }), }, } @@ -399,9 +399,9 @@ var _ = Describe("cluster component transformer test", func() { // check the first component graphCli := transCtx.Client.(model.GraphClient) - objs := graphCli.FindAll(dag, &appsv1alpha1.Component{}) + objs := graphCli.FindAll(dag, &appsv1.Component{}) Expect(len(objs)).Should(Equal(1)) - comp := objs[0].(*appsv1alpha1.Component) + comp := objs[0].(*appsv1.Component) Expect(component.ShortName(transCtx.Cluster.Name, comp.Name)).Should(Equal(comp1aName)) Expect(graphCli.IsAction(dag, comp, model.ActionUpdatePtr())).Should(BeTrue()) }) @@ -412,18 +412,18 @@ var _ = Describe("cluster component transformer test", func() { // mock components reader := &mockReader{ objs: []client.Object{ - mockCompObj(transCtx, comp1aName, func(comp *appsv1alpha1.Component) { - comp.Status.Phase = appsv1alpha1.CreatingClusterCompPhase // not ready + mockCompObj(transCtx, comp1aName, func(comp *appsv1.Component) { + comp.Status.Phase = appsv1.CreatingClusterCompPhase // not ready }), - mockCompObj(transCtx, comp1bName, func(comp *appsv1alpha1.Component) { - comp.Status.Phase = appsv1alpha1.RunningClusterCompPhase + mockCompObj(transCtx, comp1bName, func(comp *appsv1.Component) { + comp.Status.Phase = appsv1.RunningClusterCompPhase }), - mockCompObj(transCtx, comp2aName, func(comp *appsv1alpha1.Component) { + mockCompObj(transCtx, comp2aName, func(comp *appsv1.Component) { comp.Spec.Replicas = 2 // to update - comp.Status.Phase = appsv1alpha1.RunningClusterCompPhase + comp.Status.Phase = appsv1.RunningClusterCompPhase }), - mockCompObj(transCtx, comp2bName, func(comp *appsv1alpha1.Component) { - comp.Status.Phase = appsv1alpha1.RunningClusterCompPhase + mockCompObj(transCtx, comp2bName, func(comp *appsv1.Component) { + comp.Status.Phase = appsv1.RunningClusterCompPhase }), }, } @@ -436,7 +436,7 @@ var _ = Describe("cluster component transformer test", func() { // should have no components to update graphCli := transCtx.Client.(model.GraphClient) - objs := graphCli.FindAll(dag, &appsv1alpha1.Component{}) + objs := graphCli.FindAll(dag, &appsv1.Component{}) Expect(len(objs)).Should(Equal(0)) }) @@ -446,19 +446,19 @@ var _ = Describe("cluster component transformer test", func() { // mock components reader := &mockReader{ objs: []client.Object{ - mockCompObj(transCtx, comp1aName, func(comp *appsv1alpha1.Component) { + mockCompObj(transCtx, comp1aName, func(comp *appsv1.Component) { comp.Spec.Replicas = 2 // to update - comp.Status.Phase = appsv1alpha1.RunningClusterCompPhase + comp.Status.Phase = appsv1.RunningClusterCompPhase }), - mockCompObj(transCtx, comp1bName, func(comp *appsv1alpha1.Component) { - comp.Status.Phase = appsv1alpha1.RunningClusterCompPhase + mockCompObj(transCtx, comp1bName, func(comp *appsv1.Component) { + comp.Status.Phase = appsv1.RunningClusterCompPhase }), - mockCompObj(transCtx, comp2aName, func(comp *appsv1alpha1.Component) { + mockCompObj(transCtx, comp2aName, func(comp *appsv1.Component) { comp.Spec.Replicas = 2 // to update - comp.Status.Phase = appsv1alpha1.RunningClusterCompPhase + comp.Status.Phase = appsv1.RunningClusterCompPhase }), - mockCompObj(transCtx, comp2bName, func(comp *appsv1alpha1.Component) { - comp.Status.Phase = appsv1alpha1.RunningClusterCompPhase + mockCompObj(transCtx, comp2bName, func(comp *appsv1.Component) { + comp.Status.Phase = appsv1.RunningClusterCompPhase }), }, } @@ -471,9 +471,9 @@ var _ = Describe("cluster component transformer test", func() { // should have one component to update graphCli := transCtx.Client.(model.GraphClient) - objs := graphCli.FindAll(dag, &appsv1alpha1.Component{}) + objs := graphCli.FindAll(dag, &appsv1.Component{}) Expect(len(objs)).Should(Equal(1)) - comp := objs[0].(*appsv1alpha1.Component) + comp := objs[0].(*appsv1.Component) Expect(component.ShortName(transCtx.Cluster.Name, comp.Name)).Should(Equal(comp1aName)) Expect(graphCli.IsAction(dag, comp, model.ActionUpdatePtr())).Should(BeTrue()) }) @@ -484,18 +484,18 @@ var _ = Describe("cluster component transformer test", func() { // mock components reader := &mockReader{ objs: []client.Object{ - mockCompObj(transCtx, comp1aName, func(comp *appsv1alpha1.Component) { - comp.Status.Phase = appsv1alpha1.RunningClusterCompPhase + mockCompObj(transCtx, comp1aName, func(comp *appsv1.Component) { + comp.Status.Phase = appsv1.RunningClusterCompPhase }), - mockCompObj(transCtx, comp1bName, func(comp *appsv1alpha1.Component) { - comp.Status.Phase = appsv1alpha1.RunningClusterCompPhase + mockCompObj(transCtx, comp1bName, func(comp *appsv1.Component) { + comp.Status.Phase = appsv1.RunningClusterCompPhase }), - mockCompObj(transCtx, comp2aName, func(comp *appsv1alpha1.Component) { + mockCompObj(transCtx, comp2aName, func(comp *appsv1.Component) { comp.Spec.Replicas = 2 // to update - comp.Status.Phase = appsv1alpha1.RunningClusterCompPhase + comp.Status.Phase = appsv1.RunningClusterCompPhase }), - mockCompObj(transCtx, comp2bName, func(comp *appsv1alpha1.Component) { - comp.Status.Phase = appsv1alpha1.RunningClusterCompPhase + mockCompObj(transCtx, comp2bName, func(comp *appsv1.Component) { + comp.Status.Phase = appsv1.RunningClusterCompPhase }), }, } @@ -506,9 +506,9 @@ var _ = Describe("cluster component transformer test", func() { Expect(err).Should(BeNil()) graphCli := transCtx.Client.(model.GraphClient) - objs := graphCli.FindAll(dag, &appsv1alpha1.Component{}) + objs := graphCli.FindAll(dag, &appsv1.Component{}) Expect(len(objs)).Should(Equal(1)) - comp := objs[0].(*appsv1alpha1.Component) + comp := objs[0].(*appsv1.Component) Expect(component.ShortName(transCtx.Cluster.Name, comp.Name)).Should(Equal(comp2aName)) Expect(graphCli.IsAction(dag, comp, model.ActionUpdatePtr())).Should(BeTrue()) }) @@ -519,14 +519,14 @@ var _ = Describe("cluster component transformer test", func() { // mock to stop all components reader := &mockReader{ objs: []client.Object{ - mockCompObj(transCtx, comp1aName, func(comp *appsv1alpha1.Component) { - comp.Status.Phase = appsv1alpha1.RunningClusterCompPhase + mockCompObj(transCtx, comp1aName, func(comp *appsv1.Component) { + comp.Status.Phase = appsv1.RunningClusterCompPhase }), - mockCompObj(transCtx, comp2aName, func(comp *appsv1alpha1.Component) { - comp.Status.Phase = appsv1alpha1.RunningClusterCompPhase + mockCompObj(transCtx, comp2aName, func(comp *appsv1.Component) { + comp.Status.Phase = appsv1.RunningClusterCompPhase }), - mockCompObj(transCtx, comp3aName, func(comp *appsv1alpha1.Component) { - comp.Status.Phase = appsv1alpha1.RunningClusterCompPhase + mockCompObj(transCtx, comp3aName, func(comp *appsv1.Component) { + comp.Status.Phase = appsv1.RunningClusterCompPhase }), }, } @@ -542,9 +542,9 @@ var _ = Describe("cluster component transformer test", func() { // should have the first component to update only graphCli := transCtx.Client.(model.GraphClient) - objs := graphCli.FindAll(dag, &appsv1alpha1.Component{}) + objs := graphCli.FindAll(dag, &appsv1.Component{}) Expect(len(objs)).Should(Equal(1)) - comp := objs[0].(*appsv1alpha1.Component) + comp := objs[0].(*appsv1.Component) Expect(component.ShortName(transCtx.Cluster.Name, comp.Name)).Should(Equal(comp1aName)) Expect(graphCli.IsAction(dag, comp, model.ActionUpdatePtr())).Should(BeTrue()) Expect(comp.Spec.Stop).ShouldNot(BeNil()) @@ -557,15 +557,15 @@ var _ = Describe("cluster component transformer test", func() { // mock to stop all components and the first component has been stopped reader := &mockReader{ objs: []client.Object{ - mockCompObj(transCtx, comp1aName, func(comp *appsv1alpha1.Component) { + mockCompObj(transCtx, comp1aName, func(comp *appsv1.Component) { comp.Spec.Stop = &[]bool{true}[0] - comp.Status.Phase = appsv1alpha1.StoppedClusterCompPhase + comp.Status.Phase = appsv1.StoppedClusterCompPhase }), - mockCompObj(transCtx, comp2aName, func(comp *appsv1alpha1.Component) { - comp.Status.Phase = appsv1alpha1.RunningClusterCompPhase + mockCompObj(transCtx, comp2aName, func(comp *appsv1.Component) { + comp.Status.Phase = appsv1.RunningClusterCompPhase }), - mockCompObj(transCtx, comp3aName, func(comp *appsv1alpha1.Component) { - comp.Status.Phase = appsv1alpha1.RunningClusterCompPhase + mockCompObj(transCtx, comp3aName, func(comp *appsv1.Component) { + comp.Status.Phase = appsv1.RunningClusterCompPhase }), }, } @@ -581,9 +581,9 @@ var _ = Describe("cluster component transformer test", func() { // should have the second component to update only graphCli := transCtx.Client.(model.GraphClient) - objs := graphCli.FindAll(dag, &appsv1alpha1.Component{}) + objs := graphCli.FindAll(dag, &appsv1.Component{}) Expect(len(objs)).Should(Equal(1)) - comp := objs[0].(*appsv1alpha1.Component) + comp := objs[0].(*appsv1.Component) Expect(component.ShortName(transCtx.Cluster.Name, comp.Name)).Should(Equal(comp2aName)) Expect(graphCli.IsAction(dag, comp, model.ActionUpdatePtr())).Should(BeTrue()) Expect(comp.Spec.Stop).ShouldNot(BeNil()) @@ -596,11 +596,11 @@ var _ = Describe("cluster component transformer test", func() { // mock first two components status as running reader := &mockReader{ objs: []client.Object{ - mockCompObj(transCtx, comp1aName, func(comp *appsv1alpha1.Component) { - comp.Status.Phase = appsv1alpha1.RunningClusterCompPhase + mockCompObj(transCtx, comp1aName, func(comp *appsv1.Component) { + comp.Status.Phase = appsv1.RunningClusterCompPhase }), - mockCompObj(transCtx, comp1bName, func(comp *appsv1alpha1.Component) { - comp.Status.Phase = appsv1alpha1.RunningClusterCompPhase + mockCompObj(transCtx, comp1bName, func(comp *appsv1.Component) { + comp.Status.Phase = appsv1.RunningClusterCompPhase }), }, } @@ -613,21 +613,21 @@ var _ = Describe("cluster component transformer test", func() { // check the last two components under provisioning graphCli := transCtx.Client.(model.GraphClient) - objs := graphCli.FindAll(dag, &appsv1alpha1.Component{}) + objs := graphCli.FindAll(dag, &appsv1.Component{}) Expect(len(objs)).Should(Equal(2)) for _, obj := range objs { - comp := obj.(*appsv1alpha1.Component) + comp := obj.(*appsv1.Component) Expect(component.ShortName(transCtx.Cluster.Name, comp.Name)).Should(Or(Equal(comp2aName), Equal(comp2bName))) Expect(graphCli.IsAction(dag, comp, model.ActionCreatePtr())).Should(BeTrue()) } // mock last two components status as running reader.objs = append(reader.objs, []client.Object{ - mockCompObj(transCtx, comp2aName, func(comp *appsv1alpha1.Component) { - comp.Status.Phase = appsv1alpha1.RunningClusterCompPhase + mockCompObj(transCtx, comp2aName, func(comp *appsv1.Component) { + comp.Status.Phase = appsv1.RunningClusterCompPhase }), - mockCompObj(transCtx, comp2bName, func(comp *appsv1alpha1.Component) { - comp.Status.Phase = appsv1alpha1.RunningClusterCompPhase + mockCompObj(transCtx, comp2bName, func(comp *appsv1.Component) { + comp.Status.Phase = appsv1.RunningClusterCompPhase }), }...) diff --git a/controllers/apps/transformer_cluster_deletion.go b/controllers/apps/transformer_cluster_deletion.go index 27e445af50a..cd217cd909f 100644 --- a/controllers/apps/transformer_cluster_deletion.go +++ b/controllers/apps/transformer_cluster_deletion.go @@ -34,6 +34,7 @@ import ( "k8s.io/apimachinery/pkg/util/sets" "sigs.k8s.io/controller-runtime/pkg/client" + kbappsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" dpv1alpha1 "github.com/apecloud/kubeblocks/apis/dataprotection/v1alpha1" "github.com/apecloud/kubeblocks/pkg/constant" @@ -153,7 +154,7 @@ func kindsForDoNotTerminate() ([]client.ObjectList, []client.ObjectList) { func kindsForHalt() ([]client.ObjectList, []client.ObjectList) { namespacedKinds, nonNamespacedKinds := kindsForDoNotTerminate() namespacedKindsPlus := []client.ObjectList{ - &appsv1alpha1.ComponentList{}, + &kbappsv1.ComponentList{}, &appsv1alpha1.OpsRequestList{}, &appsv1.StatefulSetList{}, // be compatible with 0.6 workloads. &policyv1.PodDisruptionBudgetList{}, // be compatible with 0.6 workloads. diff --git a/controllers/apps/transformer_cluster_service.go b/controllers/apps/transformer_cluster_service.go index 77393d9ac84..91de1aa106c 100644 --- a/controllers/apps/transformer_cluster_service.go +++ b/controllers/apps/transformer_cluster_service.go @@ -30,6 +30,7 @@ import ( "k8s.io/apimachinery/pkg/types" "sigs.k8s.io/controller-runtime/pkg/client" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" "github.com/apecloud/kubeblocks/pkg/common" "github.com/apecloud/kubeblocks/pkg/constant" @@ -246,7 +247,7 @@ func (t *clusterServiceTransformer) builtinSelector(cluster *appsv1alpha1.Cluste return selectors } -func (t *clusterServiceTransformer) checkComponent(transCtx *clusterTransformContext, clusterService *appsv1alpha1.ClusterService) (*appsv1alpha1.ComponentDefinition, error) { +func (t *clusterServiceTransformer) checkComponent(transCtx *clusterTransformContext, clusterService *appsv1alpha1.ClusterService) (*appsv1.ComponentDefinition, error) { compName := clusterService.ComponentSelector for _, compSpec := range transCtx.ComponentSpecs { if compSpec.Name == compName { @@ -260,7 +261,7 @@ func (t *clusterServiceTransformer) checkComponent(transCtx *clusterTransformCon return nil, fmt.Errorf("the component of service selector is not exist, service: %s, component: %s", clusterService.Name, compName) } -func (t *clusterServiceTransformer) checkComponentRoles(compDef *appsv1alpha1.ComponentDefinition, clusterService *appsv1alpha1.ClusterService) error { +func (t *clusterServiceTransformer) checkComponentRoles(compDef *appsv1.ComponentDefinition, clusterService *appsv1alpha1.ClusterService) error { definedRoles := make(map[string]bool) for _, role := range compDef.Spec.Roles { definedRoles[strings.ToLower(role.Name)] = true diff --git a/controllers/apps/transformer_component_account.go b/controllers/apps/transformer_component_account.go index 5a42697c673..04d7258d5d9 100644 --- a/controllers/apps/transformer_component_account.go +++ b/controllers/apps/transformer_component_account.go @@ -28,7 +28,7 @@ import ( "k8s.io/apimachinery/pkg/types" "sigs.k8s.io/controller-runtime/pkg/client" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" "github.com/apecloud/kubeblocks/pkg/common" "github.com/apecloud/kubeblocks/pkg/constant" "github.com/apecloud/kubeblocks/pkg/controller/builder" @@ -75,7 +75,7 @@ func (t *componentAccountTransformer) Transform(ctx graph.TransformContext, dag } func (t *componentAccountTransformer) checkAccountSecretExist(ctx graph.TransformContext, - synthesizeComp *component.SynthesizedComponent, account appsv1alpha1.SystemAccount) (bool, error) { + synthesizeComp *component.SynthesizedComponent, account appsv1.SystemAccount) (bool, error) { secretKey := types.NamespacedName{ Namespace: synthesizeComp.Namespace, Name: constant.GenerateAccountSecretName(synthesizeComp.ClusterName, synthesizeComp.Name, account.Name), @@ -92,7 +92,7 @@ func (t *componentAccountTransformer) checkAccountSecretExist(ctx graph.Transfor } func (t *componentAccountTransformer) buildAccountSecret(ctx *componentTransformContext, - synthesizeComp *component.SynthesizedComponent, account appsv1alpha1.SystemAccount) (*corev1.Secret, error) { + synthesizeComp *component.SynthesizedComponent, account appsv1.SystemAccount) (*corev1.Secret, error) { var password []byte switch { case account.SecretRef != nil: @@ -106,7 +106,7 @@ func (t *componentAccountTransformer) buildAccountSecret(ctx *componentTransform return t.buildAccountSecretWithPassword(ctx, synthesizeComp, account, password) } -func (t *componentAccountTransformer) getPasswordFromSecret(ctx graph.TransformContext, account appsv1alpha1.SystemAccount) ([]byte, error) { +func (t *componentAccountTransformer) getPasswordFromSecret(ctx graph.TransformContext, account appsv1.SystemAccount) ([]byte, error) { secretKey := types.NamespacedName{ Namespace: account.SecretRef.Namespace, Name: account.SecretRef.Name, @@ -121,7 +121,7 @@ func (t *componentAccountTransformer) getPasswordFromSecret(ctx graph.TransformC return secret.Data[constant.AccountPasswdForSecret], nil } -func (t *componentAccountTransformer) buildPassword(ctx *componentTransformContext, account appsv1alpha1.SystemAccount) []byte { +func (t *componentAccountTransformer) buildPassword(ctx *componentTransformContext, account appsv1.SystemAccount) []byte { // get restore password if exists during recovery. password := factory.GetRestoreSystemAccountPassword(ctx.SynthesizeComponent, account) if account.InitAccount && password == "" { @@ -135,20 +135,20 @@ func (t *componentAccountTransformer) buildPassword(ctx *componentTransformConte return []byte(password) } -func (t *componentAccountTransformer) generatePassword(account appsv1alpha1.SystemAccount) []byte { +func (t *componentAccountTransformer) generatePassword(account appsv1.SystemAccount) []byte { config := account.PasswordGenerationPolicy passwd, _ := common.GeneratePassword((int)(config.Length), (int)(config.NumDigits), (int)(config.NumSymbols), false, config.Seed) switch config.LetterCase { - case appsv1alpha1.UpperCases: + case appsv1.UpperCases: passwd = strings.ToUpper(passwd) - case appsv1alpha1.LowerCases: + case appsv1.LowerCases: passwd = strings.ToLower(passwd) } return []byte(passwd) } func (t *componentAccountTransformer) buildAccountSecretWithPassword(ctx *componentTransformContext, - synthesizeComp *component.SynthesizedComponent, account appsv1alpha1.SystemAccount, password []byte) (*corev1.Secret, error) { + synthesizeComp *component.SynthesizedComponent, account appsv1.SystemAccount, password []byte) (*corev1.Secret, error) { secretName := constant.GenerateAccountSecretName(synthesizeComp.ClusterName, synthesizeComp.Name, account.Name) labels := constant.GetComponentWellKnownLabels(synthesizeComp.ClusterName, synthesizeComp.Name) secret := builder.NewSecretBuilder(synthesizeComp.Namespace, secretName). diff --git a/controllers/apps/transformer_component_account_provision.go b/controllers/apps/transformer_component_account_provision.go index 66fccdf4c22..60d24e1eb9e 100644 --- a/controllers/apps/transformer_component_account_provision.go +++ b/controllers/apps/transformer_component_account_provision.go @@ -28,7 +28,7 @@ import ( "k8s.io/apimachinery/pkg/types" "sigs.k8s.io/controller-runtime/pkg/client" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" "github.com/apecloud/kubeblocks/pkg/common" "github.com/apecloud/kubeblocks/pkg/constant" "github.com/apecloud/kubeblocks/pkg/controller/component" @@ -62,7 +62,7 @@ func (t *componentAccountProvisionTransformer) Transform(ctx graph.TransformCont if len(transCtx.SynthesizeComponent.SystemAccounts) == 0 { return nil } - if transCtx.Component.Status.Phase != appsv1alpha1.RunningClusterCompPhase { + if transCtx.Component.Status.Phase != appsv1.RunningClusterCompPhase { return nil } // TODO: (good-first-issue) if the component's account is deleted by user, we should re-provision it @@ -154,7 +154,7 @@ func (t *componentAccountProvisionTransformer) markProvisioned(transCtx *compone transCtx.Component.Status.Conditions = conditions } -func (t *componentAccountProvisionTransformer) isAccountProvisioned(cond metav1.Condition, account appsv1alpha1.SystemAccount) bool { +func (t *componentAccountProvisionTransformer) isAccountProvisioned(cond metav1.Condition, account appsv1.SystemAccount) bool { if len(cond.Message) == 0 { return false } @@ -162,7 +162,7 @@ func (t *componentAccountProvisionTransformer) isAccountProvisioned(cond metav1. return slices.Contains(accounts, account.Name) } -func (t *componentAccountProvisionTransformer) markAccountProvisioned(cond *metav1.Condition, account appsv1alpha1.SystemAccount) { +func (t *componentAccountProvisionTransformer) markAccountProvisioned(cond *metav1.Condition, account appsv1.SystemAccount) { if len(cond.Message) == 0 { cond.Message = account.Name return @@ -190,7 +190,7 @@ func (t *componentAccountProvisionTransformer) lifecycleAction(transCtx *compone } func (t *componentAccountProvisionTransformer) provisionAccount(transCtx *componentTransformContext, - _ metav1.Condition, lfa lifecycle.Lifecycle, account appsv1alpha1.SystemAccount) error { + _ metav1.Condition, lfa lifecycle.Lifecycle, account appsv1.SystemAccount) error { synthesizedComp := transCtx.SynthesizeComponent secret, err := t.getAccountSecret(transCtx, synthesizedComp, account) @@ -208,7 +208,7 @@ func (t *componentAccountProvisionTransformer) provisionAccount(transCtx *compon } func (t *componentAccountProvisionTransformer) getAccountSecret(ctx graph.TransformContext, - synthesizeComp *component.SynthesizedComponent, account appsv1alpha1.SystemAccount) (*corev1.Secret, error) { + synthesizeComp *component.SynthesizedComponent, account appsv1.SystemAccount) (*corev1.Secret, error) { secretKey := types.NamespacedName{ Namespace: synthesizeComp.Namespace, Name: constant.GenerateAccountSecretName(synthesizeComp.ClusterName, synthesizeComp.Name, account.Name), diff --git a/controllers/apps/transformer_component_deletion.go b/controllers/apps/transformer_component_deletion.go index 2b8cf275569..d40d3862862 100644 --- a/controllers/apps/transformer_component_deletion.go +++ b/controllers/apps/transformer_component_deletion.go @@ -32,6 +32,7 @@ import ( "k8s.io/apimachinery/pkg/types" "sigs.k8s.io/controller-runtime/pkg/client" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" dpv1alpha1 "github.com/apecloud/kubeblocks/apis/dataprotection/v1alpha1" wlv1alpha1 "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" @@ -61,8 +62,8 @@ func (t *componentDeletionTransformer) Transform(ctx graph.TransformContext, dag } // step1: update the component status to deleting - if comp.Status.Phase != appsv1alpha1.DeletingClusterCompPhase { - comp.Status.Phase = appsv1alpha1.DeletingClusterCompPhase + if comp.Status.Phase != appsv1.DeletingClusterCompPhase { + comp.Status.Phase = appsv1.DeletingClusterCompPhase graphCli.Status(dag, comp, transCtx.Component) return newRequeueError(time.Second*1, "updating component status to deleting") } @@ -83,13 +84,13 @@ func (t *componentDeletionTransformer) Transform(ctx graph.TransformContext, dag // handleCompDeleteWhenScaleIn handles the component deletion when scale-in, this scenario will delete all the sub-resources owned by the component by default. func (t *componentDeletionTransformer) handleCompDeleteWhenScaleIn(transCtx *componentTransformContext, graphCli model.GraphClient, - dag *graph.DAG, comp *appsv1alpha1.Component, matchLabels map[string]string) error { + dag *graph.DAG, comp *appsv1.Component, matchLabels map[string]string) error { return t.deleteCompResources(transCtx, graphCli, dag, comp, matchLabels, kindsForCompWipeOut()) } // handleCompDeleteWhenClusterDelete handles the component deletion when the cluster is being deleted, the sub-resources owned by the component depends on the cluster's TerminationPolicy. func (t *componentDeletionTransformer) handleCompDeleteWhenClusterDelete(transCtx *componentTransformContext, graphCli model.GraphClient, - dag *graph.DAG, cluster *appsv1alpha1.Cluster, comp *appsv1alpha1.Component, matchLabels map[string]string) error { + dag *graph.DAG, cluster *appsv1alpha1.Cluster, comp *appsv1.Component, matchLabels map[string]string) error { var ( toPreserveKinds, toDeleteKinds []client.ObjectList ) @@ -113,7 +114,7 @@ func (t *componentDeletionTransformer) handleCompDeleteWhenClusterDelete(transCt } func (t *componentDeletionTransformer) deleteCompResources(transCtx *componentTransformContext, graphCli model.GraphClient, - dag *graph.DAG, comp *appsv1alpha1.Component, matchLabels map[string]string, toDeleteKinds []client.ObjectList) error { + dag *graph.DAG, comp *appsv1.Component, matchLabels map[string]string, toDeleteKinds []client.ObjectList) error { // firstly, delete the workloads owned by the component workloads, err := model.ReadCacheSnapshot(transCtx, comp, matchLabels, compOwnedWorkloadKinds()...) @@ -158,7 +159,7 @@ func (t *componentDeletionTransformer) deleteCompResources(transCtx *componentTr return graph.ErrPrematureStop } -func (t *componentDeletionTransformer) getCluster(transCtx *componentTransformContext, comp *appsv1alpha1.Component) (*appsv1alpha1.Cluster, error) { +func (t *componentDeletionTransformer) getCluster(transCtx *componentTransformContext, comp *appsv1.Component) (*appsv1alpha1.Cluster, error) { clusterName, err := component.GetClusterName(comp) if err != nil { return nil, err @@ -221,6 +222,6 @@ func kindsForCompWipeOut() []client.ObjectList { // preserveCompObjects preserves the objects owned by the component when the component is being deleted func preserveCompObjects(ctx context.Context, cli client.Reader, graphCli model.GraphClient, dag *graph.DAG, - comp *appsv1alpha1.Component, ml client.MatchingLabels, toPreserveKinds []client.ObjectList) error { + comp *appsv1.Component, ml client.MatchingLabels, toPreserveKinds []client.ObjectList) error { return preserveObjects(ctx, cli, graphCli, dag, comp, ml, toPreserveKinds, constant.DBComponentFinalizerName, constant.LastAppliedClusterAnnotationKey) } diff --git a/controllers/apps/transformer_component_pre_terminate.go b/controllers/apps/transformer_component_pre_terminate.go index 285ac9135e8..732c08cbbe2 100644 --- a/controllers/apps/transformer_component_pre_terminate.go +++ b/controllers/apps/transformer_component_pre_terminate.go @@ -25,6 +25,7 @@ import ( "k8s.io/apimachinery/pkg/types" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" "github.com/apecloud/kubeblocks/pkg/controller/component" "github.com/apecloud/kubeblocks/pkg/controller/component/lifecycle" @@ -44,7 +45,7 @@ var _ graph.Transformer = &componentPreTerminateTransformer{} func (t *componentPreTerminateTransformer) Transform(ctx graph.TransformContext, dag *graph.DAG) error { transCtx, _ := ctx.(*componentTransformContext) comp := transCtx.Component - if comp.GetDeletionTimestamp().IsZero() || comp.Status.Phase != appsv1alpha1.DeletingClusterCompPhase { + if comp.GetDeletionTimestamp().IsZero() || comp.Status.Phase != appsv1.DeletingClusterCompPhase { return nil } @@ -54,7 +55,7 @@ func (t *componentPreTerminateTransformer) Transform(ctx graph.TransformContext, compDefKey := types.NamespacedName{ Name: comp.Spec.CompDef, } - compDef := &appsv1alpha1.ComponentDefinition{} + compDef := &appsv1.ComponentDefinition{} if err := transCtx.Client.Get(transCtx.Context, compDefKey, compDef); err != nil { return err } @@ -102,7 +103,7 @@ func (t *componentPreTerminateTransformer) markPreTerminateDone(transCtx *compon return intctrlutil.NewErrorf(intctrlutil.ErrorTypeRequeue, "requeue to waiting for pre-terminate annotation to be set") } -func (t *componentPreTerminateTransformer) preTerminate(transCtx *componentTransformContext, compDef *appsv1alpha1.ComponentDefinition) error { +func (t *componentPreTerminateTransformer) preTerminate(transCtx *componentTransformContext, compDef *appsv1.ComponentDefinition) error { lfa, err := t.lifecycleAction4Component(transCtx, compDef) if err != nil { return err @@ -110,7 +111,7 @@ func (t *componentPreTerminateTransformer) preTerminate(transCtx *componentTrans return lfa.PreTerminate(transCtx.Context, transCtx.Client, nil) } -func (t *componentPreTerminateTransformer) lifecycleAction4Component(transCtx *componentTransformContext, compDef *appsv1alpha1.ComponentDefinition) (lifecycle.Lifecycle, error) { +func (t *componentPreTerminateTransformer) lifecycleAction4Component(transCtx *componentTransformContext, compDef *appsv1.ComponentDefinition) (lifecycle.Lifecycle, error) { synthesizedComp, err1 := t.synthesizedComponent(transCtx, compDef) if err1 != nil { return nil, err1 @@ -127,7 +128,7 @@ func (t *componentPreTerminateTransformer) lifecycleAction4Component(transCtx *c return lifecycle.New(synthesizedComp, nil, pods...) } -func (t *componentPreTerminateTransformer) synthesizedComponent(transCtx *componentTransformContext, compDef *appsv1alpha1.ComponentDefinition) (*component.SynthesizedComponent, error) { +func (t *componentPreTerminateTransformer) synthesizedComponent(transCtx *componentTransformContext, compDef *appsv1.ComponentDefinition) (*component.SynthesizedComponent, error) { var ( ctx = transCtx.Context cli = transCtx.Client diff --git a/controllers/apps/transformer_component_rbac.go b/controllers/apps/transformer_component_rbac.go index 1a61dbe9d8b..c9286d606a4 100644 --- a/controllers/apps/transformer_component_rbac.go +++ b/controllers/apps/transformer_component_rbac.go @@ -30,6 +30,7 @@ import ( "k8s.io/apimachinery/pkg/types" "sigs.k8s.io/controller-runtime/pkg/client" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" "github.com/apecloud/kubeblocks/pkg/common" @@ -104,11 +105,11 @@ func (t *componentRBACTransformer) Transform(ctx graph.TransformContext, dag *gr return nil } -func isLifecycleActionsEnabled(compDef *appsv1alpha1.ComponentDefinition) bool { +func isLifecycleActionsEnabled(compDef *appsv1.ComponentDefinition) bool { return compDef.Spec.LifecycleActions != nil } -func isDataProtectionEnabled(backupTpl *appsv1alpha1.BackupPolicyTemplate, cluster *appsv1alpha1.Cluster, comp *appsv1alpha1.Component) bool { +func isDataProtectionEnabled(backupTpl *appsv1alpha1.BackupPolicyTemplate, cluster *appsv1alpha1.Cluster, comp *appsv1.Component) bool { if backupTpl != nil && len(comp.Spec.CompDef) > 0 { for _, policy := range backupTpl.Spec.BackupPolicies { for _, compDef := range policy.ComponentDefs { @@ -121,7 +122,7 @@ func isDataProtectionEnabled(backupTpl *appsv1alpha1.BackupPolicyTemplate, clust return false } -func isVolumeProtectionEnabled(compDef *appsv1alpha1.ComponentDefinition) bool { +func isVolumeProtectionEnabled(compDef *appsv1.ComponentDefinition) bool { for _, vol := range compDef.Spec.Volumes { if vol.HighWatermark > 0 && vol.HighWatermark < 100 { return true @@ -283,7 +284,7 @@ func buildServiceAccount(transCtx *componentTransformContext) (*corev1.ServiceAc return saObj, volumeProtectionEnable, nil } -func buildRoleBinding(cluster *appsv1alpha1.Cluster, comp *appsv1alpha1.Component, serviceAccountName string) (*rbacv1.RoleBinding, error) { +func buildRoleBinding(cluster *appsv1alpha1.Cluster, comp *appsv1.Component, serviceAccountName string) (*rbacv1.RoleBinding, error) { roleBinding := factory.BuildRoleBinding(cluster, serviceAccountName) if err := setCompOwnershipNFinalizer(comp, roleBinding); err != nil { return nil, err diff --git a/controllers/apps/transformer_component_rbac_test.go b/controllers/apps/transformer_component_rbac_test.go index 5df5e4ed0b8..6a8469eeb54 100644 --- a/controllers/apps/transformer_component_rbac_test.go +++ b/controllers/apps/transformer_component_rbac_test.go @@ -26,6 +26,7 @@ import ( corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/types" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" "github.com/apecloud/kubeblocks/pkg/constant" @@ -49,8 +50,8 @@ var _ = Describe("object rbac transformer test.", func() { var graphCli model.GraphClient var transformer graph.Transformer var cluster *appsv1alpha1.Cluster - var compDefObj *appsv1alpha1.ComponentDefinition - var compObj *appsv1alpha1.Component + var compDefObj *appsv1.ComponentDefinition + var compObj *appsv1.Component var saKey types.NamespacedName var allSettings map[string]interface{} diff --git a/controllers/apps/transformer_component_service.go b/controllers/apps/transformer_component_service.go index 87aec4571f0..e98a70ebc5b 100644 --- a/controllers/apps/transformer_component_service.go +++ b/controllers/apps/transformer_component_service.go @@ -30,7 +30,7 @@ import ( corev1 "k8s.io/api/core/v1" "sigs.k8s.io/controller-runtime/pkg/client" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" "github.com/apecloud/kubeblocks/pkg/common" "github.com/apecloud/kubeblocks/pkg/constant" @@ -97,7 +97,7 @@ func (t *componentServiceTransformer) Transform(ctx graph.TransformContext, dag } func (t *componentServiceTransformer) listOwnedServices(ctx context.Context, cli client.Reader, - comp *appsv1alpha1.Component, synthesizedComp *component.SynthesizedComponent) (map[string]*corev1.Service, error) { + comp *appsv1.Component, synthesizedComp *component.SynthesizedComponent) (map[string]*corev1.Service, error) { services, err := component.ListOwnedServices(ctx, cli, synthesizedComp.Namespace, synthesizedComp.ClusterName, synthesizedComp.Name) if err != nil { return nil, err @@ -111,8 +111,8 @@ func (t *componentServiceTransformer) listOwnedServices(ctx context.Context, cli return owned, nil } -func (t *componentServiceTransformer) buildCompService(comp *appsv1alpha1.Component, - synthesizeComp *component.SynthesizedComponent, service *appsv1alpha1.ComponentService) ([]*corev1.Service, error) { +func (t *componentServiceTransformer) buildCompService(comp *appsv1.Component, + synthesizeComp *component.SynthesizedComponent, service *appsv1.ComponentService) ([]*corev1.Service, error) { if service.DisableAutoProvision != nil && *service.DisableAutoProvision { return nil, nil } @@ -120,21 +120,21 @@ func (t *componentServiceTransformer) buildCompService(comp *appsv1alpha1.Compon if t.isPodService(service) { return t.buildPodService(comp, synthesizeComp, service) } - return t.buildServices(comp, synthesizeComp, []*appsv1alpha1.ComponentService{service}) + return t.buildServices(comp, synthesizeComp, []*appsv1.ComponentService{service}) } -func (t *componentServiceTransformer) isPodService(service *appsv1alpha1.ComponentService) bool { +func (t *componentServiceTransformer) isPodService(service *appsv1.ComponentService) bool { return service.PodService != nil && *service.PodService } -func (t *componentServiceTransformer) buildPodService(comp *appsv1alpha1.Component, - synthesizeComp *component.SynthesizedComponent, service *appsv1alpha1.ComponentService) ([]*corev1.Service, error) { +func (t *componentServiceTransformer) buildPodService(comp *appsv1.Component, + synthesizeComp *component.SynthesizedComponent, service *appsv1.ComponentService) ([]*corev1.Service, error) { pods, err := t.podsNameNOrdinal(synthesizeComp) if err != nil { return nil, err } - services := make([]*appsv1alpha1.ComponentService, 0) + services := make([]*appsv1.ComponentService, 0) for name, ordinal := range pods { svc := service.DeepCopy() svc.Name = fmt.Sprintf("%s-%d", service.Name, ordinal) @@ -175,8 +175,8 @@ func (t *componentServiceTransformer) podsNameNOrdinal(synthesizeComp *component return pods, nil } -func (t *componentServiceTransformer) buildServices(comp *appsv1alpha1.Component, - synthesizeComp *component.SynthesizedComponent, compServices []*appsv1alpha1.ComponentService) ([]*corev1.Service, error) { +func (t *componentServiceTransformer) buildServices(comp *appsv1.Component, + synthesizeComp *component.SynthesizedComponent, compServices []*appsv1.ComponentService) ([]*corev1.Service, error) { services := make([]*corev1.Service, 0, len(compServices)) for _, compService := range compServices { svc, err := t.buildService(comp, synthesizeComp, compService) @@ -188,8 +188,8 @@ func (t *componentServiceTransformer) buildServices(comp *appsv1alpha1.Component return services, nil } -func (t *componentServiceTransformer) buildService(comp *appsv1alpha1.Component, - synthesizeComp *component.SynthesizedComponent, service *appsv1alpha1.ComponentService) (*corev1.Service, error) { +func (t *componentServiceTransformer) buildService(comp *appsv1.Component, + synthesizeComp *component.SynthesizedComponent, service *appsv1.ComponentService) (*corev1.Service, error) { var ( namespace = synthesizeComp.Namespace clusterName = synthesizeComp.ClusterName @@ -219,7 +219,7 @@ func (t *componentServiceTransformer) buildService(comp *appsv1alpha1.Component, return svcObj, nil } -func (t *componentServiceTransformer) builtinSelector(comp *appsv1alpha1.Component) map[string]string { +func (t *componentServiceTransformer) builtinSelector(comp *appsv1.Component) map[string]string { selectors := map[string]string{ constant.AppManagedByLabelKey: "", constant.AppInstanceLabelKey: "", @@ -245,14 +245,14 @@ func (t *componentServiceTransformer) checkRoleSelector(synthesizeComp *componen return nil } -func (t *componentServiceTransformer) skipDefaultHeadlessSvc(synthesizeComp *component.SynthesizedComponent, service *appsv1alpha1.ComponentService) bool { +func (t *componentServiceTransformer) skipDefaultHeadlessSvc(synthesizeComp *component.SynthesizedComponent, service *appsv1.ComponentService) bool { svcName := constant.GenerateComponentServiceName(synthesizeComp.ClusterName, synthesizeComp.Name, service.ServiceName) defaultHeadlessSvcName := constant.GenerateDefaultComponentHeadlessServiceName(synthesizeComp.ClusterName, synthesizeComp.Name) return svcName == defaultHeadlessSvcName } func (t *componentServiceTransformer) createOrUpdateService(ctx graph.TransformContext, dag *graph.DAG, - graphCli model.GraphClient, compService *appsv1alpha1.ComponentService, service *corev1.Service, owner client.Object) error { + graphCli model.GraphClient, compService *appsv1.ComponentService, service *corev1.Service, owner client.Object) error { var ( kind string podService = t.isPodService(compService) diff --git a/controllers/apps/transformer_component_service_test.go b/controllers/apps/transformer_component_service_test.go index 79214889761..51253944d78 100644 --- a/controllers/apps/transformer_component_service_test.go +++ b/controllers/apps/transformer_component_service_test.go @@ -21,6 +21,7 @@ package apps import ( "fmt" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" @@ -30,7 +31,6 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/client" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" "github.com/apecloud/kubeblocks/pkg/constant" "github.com/apecloud/kubeblocks/pkg/controller/component" "github.com/apecloud/kubeblocks/pkg/controller/graph" @@ -50,7 +50,7 @@ var _ = Describe(" component service transformer test", func() { transCtx *componentTransformContext ) - newDAG := func(graphCli model.GraphClient, comp *appsv1alpha1.Component) *graph.DAG { + newDAG := func(graphCli model.GraphClient, comp *appsv1.Component) *graph.DAG { d := graph.NewDAG() graphCli.Root(d, comp, comp, model.ActionStatusPtr()) return d @@ -58,7 +58,7 @@ var _ = Describe(" component service transformer test", func() { BeforeEach(func() { reader = &mockReader{} - comp := &appsv1alpha1.Component{ + comp := &appsv1.Component{ ObjectMeta: metav1.ObjectMeta{ Namespace: testCtx.DefaultNamespace, Name: constant.GenerateClusterComponentName(clusterName, compName), @@ -68,7 +68,7 @@ var _ = Describe(" component service transformer test", func() { constant.KBAppComponentLabelKey: compName, }, }, - Spec: appsv1alpha1.ComponentSpec{}, + Spec: appsv1.ComponentSpec{}, } graphCli := model.NewGraphClient(reader) dag = newDAG(graphCli, comp) @@ -83,9 +83,9 @@ var _ = Describe(" component service transformer test", func() { Namespace: testCtx.DefaultNamespace, ClusterName: clusterName, Name: compName, - ComponentServices: []appsv1alpha1.ComponentService{ + ComponentServices: []appsv1.ComponentService{ { - Service: appsv1alpha1.Service{ + Service: appsv1.Service{ Name: "default", ServiceName: "default", }, diff --git a/controllers/apps/transformer_component_status.go b/controllers/apps/transformer_component_status.go index 2e14e6a87c0..9052c267371 100644 --- a/controllers/apps/transformer_component_status.go +++ b/controllers/apps/transformer_component_status.go @@ -30,6 +30,7 @@ import ( "k8s.io/apimachinery/pkg/util/sets" "sigs.k8s.io/controller-runtime/pkg/client" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" dpv1alpha1 "github.com/apecloud/kubeblocks/apis/dataprotection/v1alpha1" workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" @@ -55,7 +56,7 @@ type componentStatusTransformer struct { client.Client cluster *appsv1alpha1.Cluster - comp *appsv1alpha1.Component + comp *appsv1.Component synthesizeComp *component.SynthesizedComponent dag *graph.DAG @@ -164,7 +165,7 @@ func (t *componentStatusTransformer) reconcileStatus(transCtx *componentTransfor // check if the component is in creating phase isInCreatingPhase := func() bool { phase := t.comp.Status.Phase - return phase == "" || phase == appsv1alpha1.CreatingClusterCompPhase + return phase == "" || phase == appsv1.CreatingClusterCompPhase }() transCtx.Logger.Info( @@ -173,21 +174,21 @@ func (t *componentStatusTransformer) reconcileStatus(transCtx *componentTransfor switch { case isDeleting: - t.setComponentStatusPhase(transCtx, appsv1alpha1.DeletingClusterCompPhase, nil, "component is Deleting") + t.setComponentStatusPhase(transCtx, appsv1.DeletingClusterCompPhase, nil, "component is Deleting") case stopped && hasRunningPods: - t.setComponentStatusPhase(transCtx, appsv1alpha1.StoppingClusterCompPhase, nil, "component is Stopping") + t.setComponentStatusPhase(transCtx, appsv1.StoppingClusterCompPhase, nil, "component is Stopping") case stopped: - t.setComponentStatusPhase(transCtx, appsv1alpha1.StoppedClusterCompPhase, nil, "component is Stopped") + t.setComponentStatusPhase(transCtx, appsv1.StoppedClusterCompPhase, nil, "component is Stopped") case isITSUpdatedNRunning && isAllConfigSynced && !hasRunningVolumeExpansion: - t.setComponentStatusPhase(transCtx, appsv1alpha1.RunningClusterCompPhase, nil, "component is Running") + t.setComponentStatusPhase(transCtx, appsv1.RunningClusterCompPhase, nil, "component is Running") case !hasFailure && isInCreatingPhase: - t.setComponentStatusPhase(transCtx, appsv1alpha1.CreatingClusterCompPhase, nil, "component is Creating") + t.setComponentStatusPhase(transCtx, appsv1.CreatingClusterCompPhase, nil, "component is Creating") case !hasFailure: - t.setComponentStatusPhase(transCtx, appsv1alpha1.UpdatingClusterCompPhase, nil, "component is Updating") + t.setComponentStatusPhase(transCtx, appsv1.UpdatingClusterCompPhase, nil, "component is Updating") case !isComponentAvailable: - t.setComponentStatusPhase(transCtx, appsv1alpha1.FailedClusterCompPhase, messages, "component is Failed") + t.setComponentStatusPhase(transCtx, appsv1.FailedClusterCompPhase, messages, "component is Failed") default: - t.setComponentStatusPhase(transCtx, appsv1alpha1.AbnormalClusterCompPhase, nil, "component is Abnormal") + t.setComponentStatusPhase(transCtx, appsv1.AbnormalClusterCompPhase, nil, "component is Abnormal") } return nil @@ -392,8 +393,8 @@ func (t *componentStatusTransformer) hasFailedPod() (bool, appsv1alpha1.Componen // setComponentStatusPhase sets the component phase and messages conditionally. func (t *componentStatusTransformer) setComponentStatusPhase(transCtx *componentTransformContext, - phase appsv1alpha1.ClusterComponentPhase, statusMessage appsv1alpha1.ComponentMessageMap, phaseTransitionMsg string) { - updateFn := func(status *appsv1alpha1.ComponentStatus) error { + phase appsv1.ClusterComponentPhase, statusMessage map[string]string, phaseTransitionMsg string) { + updateFn := func(status *appsv1.ComponentStatus) error { if status.Phase == phase { return nil } @@ -414,7 +415,7 @@ func (t *componentStatusTransformer) setComponentStatusPhase(transCtx *component // updateComponentStatus updates the component status by @updateFn, with additional message to explain the transition occurred. func (t *componentStatusTransformer) updateComponentStatus(transCtx *componentTransformContext, - phaseTransitionMsg string, updateFn func(status *appsv1alpha1.ComponentStatus) error) error { + phaseTransitionMsg string, updateFn func(status *appsv1.ComponentStatus) error) error { if updateFn == nil { return nil } diff --git a/controllers/apps/transformer_component_tls.go b/controllers/apps/transformer_component_tls.go index 72aaa246e45..314feaf5d8e 100644 --- a/controllers/apps/transformer_component_tls.go +++ b/controllers/apps/transformer_component_tls.go @@ -22,6 +22,7 @@ package apps import ( "context" "fmt" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" "strings" corev1 "k8s.io/api/core/v1" @@ -144,11 +145,11 @@ func buildTLSCert(ctx context.Context, cli client.Reader, synthesizedComp compon } switch tls.Issuer.Name { - case appsv1alpha1.IssuerUserProvided: + case appsv1.IssuerUserProvided: if err := plan.CheckTLSSecretRef(ctx, cli, synthesizedComp.Namespace, tls.Issuer.SecretRef); err != nil { return err } - case appsv1alpha1.IssuerKubeBlocks: + case appsv1.IssuerKubeBlocks: secretName := plan.GenerateTLSSecretName(synthesizedComp.ClusterName, synthesizedComp.Name) preSecret := &corev1.Secret{} if err := cli.Get(ctx, types.NamespacedName{Namespace: synthesizedComp.Namespace, Name: secretName}, preSecret); !errors.IsNotFound(err) { @@ -199,18 +200,18 @@ func composeTLSVolume(clusterName string, synthesizeComp component.SynthesizedCo if tls.Issuer == nil { return nil, fmt.Errorf("issuer shouldn't be nil when TLS enabled") } - if tls.Issuer.Name == appsv1alpha1.IssuerUserProvided && tls.Issuer.SecretRef == nil { + if tls.Issuer.Name == appsv1.IssuerUserProvided && tls.Issuer.SecretRef == nil { return nil, fmt.Errorf("secret ref shouldn't be nil when issuer is UserProvided") } var secretName, ca, cert, key string switch tls.Issuer.Name { - case appsv1alpha1.IssuerKubeBlocks: + case appsv1.IssuerKubeBlocks: secretName = plan.GenerateTLSSecretName(clusterName, synthesizeComp.Name) ca = constant.CAName cert = constant.CertName key = constant.KeyName - case appsv1alpha1.IssuerUserProvided: + case appsv1.IssuerUserProvided: secretName = tls.Issuer.SecretRef.Name ca = tls.Issuer.SecretRef.CA cert = tls.Issuer.SecretRef.Cert diff --git a/controllers/apps/transformer_component_tls_test.go b/controllers/apps/transformer_component_tls_test.go index b968193b44c..bbe3d8256ad 100644 --- a/controllers/apps/transformer_component_tls_test.go +++ b/controllers/apps/transformer_component_tls_test.go @@ -31,6 +31,7 @@ import ( "k8s.io/apimachinery/pkg/types" "sigs.k8s.io/controller-runtime/pkg/client" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" appsv1beta1 "github.com/apecloud/kubeblocks/apis/apps/v1beta1" cfgcore "github.com/apecloud/kubeblocks/pkg/configuration/core" @@ -53,7 +54,7 @@ var _ = Describe("TLS self-signed cert function", func() { ) var ( - compDefObj *appsv1alpha1.ComponentDefinition + compDefObj *appsv1.ComponentDefinition ) ctx := context.Background() @@ -228,10 +229,10 @@ var _ = Describe("TLS self-signed cert function", func() { Namespace: testCtx.DefaultNamespace, ClusterName: "test-kb", Name: "test-kb-tls", - TLSConfig: &appsv1alpha1.TLSConfig{ + TLSConfig: &appsv1.TLSConfig{ Enable: true, - Issuer: &appsv1alpha1.Issuer{ - Name: appsv1alpha1.IssuerKubeBlocks, + Issuer: &appsv1.Issuer{ + Name: appsv1.IssuerKubeBlocks, }, }, } diff --git a/controllers/apps/transformer_component_utils.go b/controllers/apps/transformer_component_utils.go index e3f69564870..0a5c7a8e48c 100644 --- a/controllers/apps/transformer_component_utils.go +++ b/controllers/apps/transformer_component_utils.go @@ -28,12 +28,12 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" "github.com/apecloud/kubeblocks/pkg/constant" intctrlutil "github.com/apecloud/kubeblocks/pkg/controllerutil" ) -func setCompOwnershipNFinalizer(comp *appsv1alpha1.Component, object client.Object) error { +func setCompOwnershipNFinalizer(comp *appsv1.Component, object client.Object) error { if skipSetCompOwnershipNFinalizer(object) { return nil } @@ -58,14 +58,14 @@ func skipSetCompOwnershipNFinalizer(obj client.Object) bool { } } -func addFinalizer(obj client.Object, comp *appsv1alpha1.Component) { +func addFinalizer(obj client.Object, comp *appsv1.Component) { if skipAddCompFinalizer(obj, comp) { return } controllerutil.AddFinalizer(obj, constant.DBComponentFinalizerName) } -func skipAddCompFinalizer(obj client.Object, comp *appsv1alpha1.Component) bool { +func skipAddCompFinalizer(obj client.Object, comp *appsv1.Component) bool { // Due to compatibility reasons, the component controller creates cluster-scoped RoleBinding and ServiceAccount objects in the following two scenarios: // 1. When the user does not specify a ServiceAccount, KubeBlocks automatically creates a ServiceAccount and a RoleBinding with named pattern kb-{cluster.Name}. // 2. When the user specifies a ServiceAccount that does not exist, KubeBlocks will automatically create a ServiceAccount and a RoleBinding with the same name. diff --git a/controllers/apps/transformer_component_validation.go b/controllers/apps/transformer_component_validation.go index 9cb5921e5f1..edc9c02df48 100644 --- a/controllers/apps/transformer_component_validation.go +++ b/controllers/apps/transformer_component_validation.go @@ -22,12 +22,12 @@ package apps import ( "fmt" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" "github.com/apecloud/kubeblocks/pkg/controller/graph" ) var ( - defaultReplicasLimit = appsv1alpha1.ReplicasLimit{ + defaultReplicasLimit = appsv1.ReplicasLimit{ MinReplicas: 1, MaxReplicas: 16384, } @@ -59,7 +59,7 @@ func (t *componentValidationTransformer) Transform(ctx graph.TransformContext, d return nil } -func validateEnabledLogs(comp *appsv1alpha1.Component, compDef *appsv1alpha1.ComponentDefinition) error { +func validateEnabledLogs(comp *appsv1.Component, compDef *appsv1.ComponentDefinition) error { invalidLogNames := validateEnabledLogConfigs(compDef, comp.Spec.EnabledLogs) if len(invalidLogNames) > 0 { return fmt.Errorf("logs %s are not defined in the definition", invalidLogNames) @@ -67,7 +67,7 @@ func validateEnabledLogs(comp *appsv1alpha1.Component, compDef *appsv1alpha1.Com return nil } -func validateEnabledLogConfigs(compDef *appsv1alpha1.ComponentDefinition, enabledLogs []string) []string { +func validateEnabledLogConfigs(compDef *appsv1.ComponentDefinition, enabledLogs []string) []string { invalidLogNames := make([]string, 0, len(enabledLogs)) logTypes := make(map[string]struct{}) @@ -87,7 +87,7 @@ func validateEnabledLogConfigs(compDef *appsv1alpha1.ComponentDefinition, enable return invalidLogNames } -func validateCompReplicas(comp *appsv1alpha1.Component, compDef *appsv1alpha1.ComponentDefinition) error { +func validateCompReplicas(comp *appsv1.Component, compDef *appsv1.ComponentDefinition) error { replicasLimit := &defaultReplicasLimit // always respect the replicas limit if set. if compDef.Spec.ReplicasLimit != nil { @@ -101,6 +101,6 @@ func validateCompReplicas(comp *appsv1alpha1.Component, compDef *appsv1alpha1.Co return replicasOutOfLimitError(replicas, *replicasLimit) } -func replicasOutOfLimitError(replicas int32, replicasLimit appsv1alpha1.ReplicasLimit) error { +func replicasOutOfLimitError(replicas int32, replicasLimit appsv1.ReplicasLimit) error { return fmt.Errorf("replicas %d out-of-limit [%d, %d]", replicas, replicasLimit.MinReplicas, replicasLimit.MaxReplicas) } diff --git a/controllers/apps/transformer_component_workload.go b/controllers/apps/transformer_component_workload.go index ff271cda03f..65d97f5fae9 100644 --- a/controllers/apps/transformer_component_workload.go +++ b/controllers/apps/transformer_component_workload.go @@ -36,6 +36,7 @@ import ( "k8s.io/apimachinery/pkg/util/sets" "sigs.k8s.io/controller-runtime/pkg/client" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" "github.com/apecloud/kubeblocks/pkg/constant" @@ -139,7 +140,7 @@ func (t *componentWorkloadTransformer) runningInstanceSetObject(ctx graph.Transf } func (t *componentWorkloadTransformer) reconcileWorkload(synthesizedComp *component.SynthesizedComponent, - comp *appsv1alpha1.Component, runningITS, protoITS *workloads.InstanceSet) error { + comp *appsv1.Component, runningITS, protoITS *workloads.InstanceSet) error { if runningITS != nil { *protoITS.Spec.Selector = *runningITS.Spec.Selector protoITS.Spec.Template.Labels = intctrlutil.MergeMetadataMaps(runningITS.Spec.Template.Labels, synthesizedComp.UserDefinedLabels) @@ -905,7 +906,7 @@ func getRunningVolumes(ctx context.Context, cli client.Client, synthesizedComp * return matchedPVCs, nil } -func buildInstanceSetPlacementAnnotation(comp *appsv1alpha1.Component, its *workloads.InstanceSet) { +func buildInstanceSetPlacementAnnotation(comp *appsv1.Component, its *workloads.InstanceSet) { p := placement(comp) if len(p) > 0 { if its.Annotations == nil { diff --git a/controllers/apps/transformer_component_workload_upgrade.go b/controllers/apps/transformer_component_workload_upgrade.go index 5a6c3282f14..976a08f2162 100644 --- a/controllers/apps/transformer_component_workload_upgrade.go +++ b/controllers/apps/transformer_component_workload_upgrade.go @@ -30,7 +30,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/client" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" + kbappsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" "github.com/apecloud/kubeblocks/apis/workloads/legacy" workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" "github.com/apecloud/kubeblocks/pkg/constant" @@ -163,7 +163,7 @@ func legacyCRDExists(ctx context.Context, cli model.GraphClient) (bool, error) { return false, err } -func buildRevision(synthesizeComp *component.SynthesizedComponent, componentDef *appsv1alpha1.ComponentDefinition) (string, error) { +func buildRevision(synthesizeComp *component.SynthesizedComponent, componentDef *kbappsv1.ComponentDefinition) (string, error) { buildPodSpecVolumeMounts(synthesizeComp) its, err := factory.BuildInstanceSet(synthesizeComp, componentDef) if err != nil { diff --git a/deploy/helm/crds/apps.kubeblocks.io_componentdefinitions.yaml b/deploy/helm/crds/apps.kubeblocks.io_componentdefinitions.yaml index 6ee9d7c1abb..4360700ec17 100644 --- a/deploy/helm/crds/apps.kubeblocks.io_componentdefinitions.yaml +++ b/deploy/helm/crds/apps.kubeblocks.io_componentdefinitions.yaml @@ -86,15 +86,13040 @@ spec: metadata: type: object spec: - description: ComponentDefinitionSpec defines the desired state of ComponentDefinition properties: - foo: - description: Foo is an example field of ComponentDefinition. Edit - componentdefinition_types.go to remove/update + annotations: + additionalProperties: + type: string + description: |- + Specifies static annotations that will be patched to all Kubernetes resources created for the Component. + + + Note: If an annotation key in the `annotations` field conflicts with any system annotations + or user-specified annotations, it will be silently ignored to avoid overriding higher-priority annotations. + + + This field is immutable. + type: object + configs: + description: |- + Specifies the configuration file templates and volume mount parameters used by the Component. + It also includes descriptions of the parameters in the ConfigMaps, such as value range limitations. + + + This field specifies a list of templates that will be rendered into Component containers' configuration files. + Each template is represented as a ConfigMap and may contain multiple configuration files, + with each file being a key in the ConfigMap. + + + The rendered configuration files will be mounted into the Component's containers + according to the specified volume mount parameters. + + + This field is immutable. + items: + properties: + asEnvFrom: + description: |- + Specifies the containers to inject the ConfigMap parameters as environment variables. + + + This is useful when application images accept parameters through environment variables and + generate the final configuration file in the startup script based on these variables. + + + This field allows users to specify a list of container names, and KubeBlocks will inject the environment + variables converted from the ConfigMap into these designated containers. This provides a flexible way to + pass the configuration items from the ConfigMap to the container without modifying the image. + + + Deprecated: `asEnvFrom` has been deprecated since 0.9.0 and will be removed in 0.10.0. + Use `injectEnvTo` instead. + items: + type: string + type: array + x-kubernetes-list-type: set + constraintRef: + description: Specifies the name of the referenced configuration + constraints object. + maxLength: 63 + pattern: ^[a-z0-9]([a-z0-9\.\-]*[a-z0-9])?$ + type: string + defaultMode: + description: |- + The operator attempts to set default file permissions for scripts (0555) and configurations (0444). + However, certain database engines may require different file permissions. + You can specify the desired file permissions here. + + + Must be specified as an octal value between 0000 and 0777 (inclusive), + or as a decimal value between 0 and 511 (inclusive). + YAML supports both octal and decimal values for file permissions. + + + Please note that this setting only affects the permissions of the files themselves. + Directories within the specified path are not impacted by this setting. + It's important to be aware that this setting might conflict with other options + that influence the file mode, such as fsGroup. + In such cases, the resulting file mode may have additional bits set. + Refers to documents of k8s.ConfigMapVolumeSource.defaultMode for more information. + format: int32 + type: integer + injectEnvTo: + description: |- + Specifies the containers to inject the ConfigMap parameters as environment variables. + + + This is useful when application images accept parameters through environment variables and + generate the final configuration file in the startup script based on these variables. + + + This field allows users to specify a list of container names, and KubeBlocks will inject the environment + variables converted from the ConfigMap into these designated containers. This provides a flexible way to + pass the configuration items from the ConfigMap to the container without modifying the image. + items: + type: string + type: array + x-kubernetes-list-type: set + keys: + description: |- + Specifies the configuration files within the ConfigMap that support dynamic updates. + + + A configuration template (provided in the form of a ConfigMap) may contain templates for multiple + configuration files. + Each configuration file corresponds to a key in the ConfigMap. + Some of these configuration files may support dynamic modification and reloading without requiring + a pod restart. + + + If empty or omitted, all configuration files in the ConfigMap are assumed to support dynamic updates, + and ConfigConstraint applies to all keys. + items: + type: string + type: array + x-kubernetes-list-type: set + legacyRenderedConfigSpec: + description: |- + Specifies the secondary rendered config spec for pod-specific customization. + + + The template is rendered inside the pod (by the "config-manager" sidecar container) and merged with the main + template's render result to generate the final configuration file. + + + This field is intended to handle scenarios where different pods within the same Component have + varying configurations. It allows for pod-specific customization of the configuration. + + + Note: This field will be deprecated in future versions, and the functionality will be moved to + `cluster.spec.componentSpecs[*].instances[*]`. + properties: + namespace: + default: default + description: |- + Specifies the namespace of the referenced configuration template ConfigMap object. + An empty namespace is equivalent to the "default" namespace. + pattern: ^[a-z0-9]([a-z0-9\-]*[a-z0-9])?$ + type: string + policy: + default: none + description: Defines the strategy for merging externally + imported templates into component templates. + enum: + - patch + - replace + - none + type: string + templateRef: + description: Specifies the name of the referenced configuration + template ConfigMap object. + pattern: ^[a-z0-9]([a-z0-9\.\-]*[a-z0-9])?$ + type: string + required: + - templateRef + type: object + name: + description: Specifies the name of the configuration template. + maxLength: 63 + pattern: ^[a-z0-9]([a-z0-9\.\-]*[a-z0-9])?$ + type: string + namespace: + default: default + description: |- + Specifies the namespace of the referenced configuration template ConfigMap object. + An empty namespace is equivalent to the "default" namespace. + maxLength: 63 + pattern: ^[a-z0-9]([a-z0-9\-]*[a-z0-9])?$ + type: string + reRenderResourceTypes: + description: |- + Specifies whether the configuration needs to be re-rendered after v-scale or h-scale operations to reflect changes. + + + In some scenarios, the configuration may need to be updated to reflect the changes in resource allocation + or cluster topology. Examples: + + + - Redis: adjust maxmemory after v-scale operation. + - MySQL: increase max connections after v-scale operation. + - Zookeeper: update zoo.cfg with new node addresses after h-scale operation. + items: + description: RerenderResourceType defines the resource requirements + for a component. + enum: + - vscale + - hscale + - tls + type: string + type: array + x-kubernetes-list-type: set + templateRef: + description: Specifies the name of the referenced configuration + template ConfigMap object. + maxLength: 63 + pattern: ^[a-z0-9]([a-z0-9\.\-]*[a-z0-9])?$ + type: string + volumeName: + description: |- + Refers to the volume name of PodTemplate. The configuration file produced through the configuration + template will be mounted to the corresponding volume. Must be a DNS_LABEL name. + The volume name must be defined in podSpec.containers[*].volumeMounts. + maxLength: 63 + pattern: ^[a-z]([a-z0-9\-]*[a-z0-9])?$ + type: string + required: + - name + - volumeName + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + description: + description: |- + Provides a brief and concise explanation of the Component's purpose, functionality, and any relevant details. + It serves as a quick reference for users to understand the Component's role and characteristics. + maxLength: 256 type: string + exporter: + description: Defines the built-in metrics exporter container. + properties: + containerName: + description: Specifies the name of the built-in metrics exporter + container. + type: string + scrapePath: + description: |- + Specifies the http/https url path to scrape for metrics. + If empty, Prometheus uses the default value (e.g. `/metrics`). + type: string + scrapePort: + description: Specifies the port name to scrape for metrics. + type: string + scrapeScheme: + description: |- + Specifies the schema to use for scraping. + `http` and `https` are the expected values unless you rewrite the `__scheme__` label via relabeling. + If empty, Prometheus uses the default value `http`. + enum: + - http + - https + type: string + type: object + hostNetwork: + description: |- + Specifies the host network configuration for the Component. + + + When `hostNetwork` option is enabled, the Pods share the host's network namespace and can directly access + the host's network interfaces. + This means that if multiple Pods need to use the same port, they cannot run on the same host simultaneously + due to port conflicts. + + + The DNSPolicy field in the Pod spec determines how containers within the Pod perform DNS resolution. + When using hostNetwork, the operator will set the DNSPolicy to 'ClusterFirstWithHostNet'. + With this policy, DNS queries will first go through the K8s cluster's DNS service. + If the query fails, it will fall back to the host's DNS settings. + + + If set, the DNS policy will be automatically set to "ClusterFirstWithHostNet". + + + This field is immutable. + properties: + containerPorts: + description: The list of container ports that are required by + the component. + items: + properties: + container: + description: Container specifies the target container within + the Pod. + type: string + ports: + description: |- + Ports are named container ports within the specified container. + These container ports must be defined in the container for proper port allocation. + items: + type: string + minItems: 1 + type: array + required: + - container + - ports + type: object + type: array + type: object + labels: + additionalProperties: + type: string + description: |- + Specifies static labels that will be patched to all Kubernetes resources created for the Component. + + + Note: If a label key in the `labels` field conflicts with any system labels or user-specified labels, + it will be silently ignored to avoid overriding higher-priority labels. + + + This field is immutable. + type: object + lifecycleActions: + description: |- + Defines a set of hooks and procedures that customize the behavior of a Component throughout its lifecycle. + Actions are triggered at specific lifecycle stages: + + + - `postProvision`: Defines the hook to be executed after the creation of a Component, + with `preCondition` specifying when the action should be fired relative to the Component's lifecycle stages: + `Immediately`, `RuntimeReady`, `ComponentReady`, and `ClusterReady`. + - `preTerminate`: Defines the hook to be executed before terminating a Component. + - `roleProbe`: Defines the procedure which is invoked regularly to assess the role of replicas. + - `switchover`: Defines the procedure for a controlled transition of leadership from the current leader to a new replica. + This approach aims to minimize downtime and maintain availability in systems with a leader-follower topology, + such as before planned maintenance or upgrades on the current leader node. + - `memberJoin`: Defines the procedure to add a new replica to the replication group. + - `memberLeave`: Defines the method to remove a replica from the replication group. + - `readOnly`: Defines the procedure to switch a replica into the read-only state. + - `readWrite`: transition a replica from the read-only state back to the read-write state. + - `dataDump`: Defines the procedure to export the data from a replica. + - `dataLoad`: Defines the procedure to import data into a replica. + - `reconfigure`: Defines the procedure that update a replica with new configuration file. + - `accountProvision`: Defines the procedure to generate a new database account. + + + This field is immutable. + properties: + accountProvision: + description: |- + Defines the procedure to generate a new database account. + + + Use Case: + This action is designed to create system accounts that are utilized for replication, monitoring, backup, + and other administrative tasks. + + + The container executing this action has access to following variables: + + + - KB_ACCOUNT_NAME: The name of the system account to be created. + - KB_ACCOUNT_PASSWORD: The password for the system account. // TODO: how to pass the password securely? + - KB_ACCOUNT_STATEMENT: The statement used to create the system account. + + + Note: This field is immutable once it has been set. + properties: + exec: + description: |- + Defines the command to run. + + + This field cannot be updated. + properties: + args: + description: Args represents the arguments that are passed + to the `command` for execution. + items: + type: string + type: array + command: + description: |- + Specifies the command to be executed inside the container. + The working directory for this command is the container's root directory('/'). + Commands are executed directly without a shell environment, meaning shell-specific syntax ('|', etc.) is not supported. + If the shell is required, it must be explicitly invoked in the command. + + + A successful execution is indicated by an exit status of 0; any non-zero status signifies a failure. + items: + type: string + type: array + container: + description: |- + Specifies the name of the container within the same pod whose resources will be shared with the action. + This allows the action to utilize the specified container's resources without executing within it. + + + The name must match one of the containers defined in `componentDefinition.spec.runtime`. + + + The resources that can be shared are included: + + + - volume mounts + + + This field cannot be updated. + type: string + env: + description: |- + Represents a list of environment variables that will be injected into the container. + These variables enable the container to adapt its behavior based on the environment it's running in. + + + This field cannot be updated. + items: + description: EnvVar represents an environment variable + present in a Container. + properties: + name: + description: Name of the environment variable. Must + be a C_IDENTIFIER. + type: string + value: + description: |- + Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in the container and + any service environment variables. If a variable cannot be resolved, + the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless of whether the variable + exists or not. + Defaults to "". + type: string + valueFrom: + description: Source for the environment variable's + value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select + in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required for + volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format + of the exposed resources, defaults to + "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in the + pod's namespace + properties: + key: + description: The key of the secret to select + from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + image: + description: |- + Specifies the container image to be used for running the Action. + + + When specified, a dedicated container will be created using this image to execute the Action. + All actions with same image will share the same container. + + + This field cannot be updated. + type: string + matchingKey: + description: |- + Used in conjunction with the `targetPodSelector` field to refine the selection of target pod(s) for Action execution. + The impact of this field depends on the `targetPodSelector` value: + + + - When `targetPodSelector` is set to `Any` or `All`, this field will be ignored. + - When `targetPodSelector` is set to `Role`, only those replicas whose role matches the `matchingKey` + will be selected for the Action. + + + This field cannot be updated. + type: string + targetPodSelector: + description: |- + Defines the criteria used to select the target Pod(s) for executing the Action. + This is useful when there is no default target replica identified. + It allows for precise control over which Pod(s) the Action should run in. + + + If not specified, the Action will be executed in the pod where the Action is triggered, such as the pod + to be removed or added; or a random pod if the Action is triggered at the component level, such as + post-provision or pre-terminate of the component. + + + This field cannot be updated. + enum: + - Any + - All + - Role + - Ordinal + type: string + type: object + preCondition: + description: |- + Specifies the state that the cluster must reach before the Action is executed. + Currently, this is only applicable to the `postProvision` action. + + + The conditions are as follows: + + + - `Immediately`: Executed right after the Component object is created. + The readiness of the Component and its resources is not guaranteed at this stage. + - `RuntimeReady`: The Action is triggered after the Component object has been created and all associated + runtime resources (e.g. Pods) are in a ready state. + - `ComponentReady`: The Action is triggered after the Component itself is in a ready state. + This process does not affect the readiness state of the Component or the Cluster. + - `ClusterReady`: The Action is executed after the Cluster is in a ready state. + This execution does not alter the Component or the Cluster's state of readiness. + + + This field cannot be updated. + type: string + retryPolicy: + description: |- + Defines the strategy to be taken when retrying the Action after a failure. + + + It specifies the conditions under which the Action should be retried and the limits to apply, + such as the maximum number of retries and backoff strategy. + + + This field cannot be updated. + properties: + maxRetries: + default: 0 + description: |- + Defines the maximum number of retry attempts that should be made for a given Action. + This value is set to 0 by default, indicating that no retries will be made. + type: integer + retryInterval: + default: 0 + description: |- + Indicates the duration of time to wait between each retry attempt. + This value is set to 0 by default, indicating that there will be no delay between retry attempts. + format: int64 + type: integer + type: object + timeoutSeconds: + default: 0 + description: |- + Specifies the maximum duration in seconds that the Action is allowed to run. + + + If the Action does not complete within this time frame, it will be terminated. + + + This field cannot be updated. + format: int32 + type: integer + type: object + dataDump: + description: |- + Defines the procedure for exporting the data from a replica. + + + Use Case: + This action is intended for initializing a newly created replica with data. It involves exporting data + from an existing replica and importing it into the new, empty replica. This is essential for synchronizing + the state of replicas across the system. + + + Applicability: + Some database engines or associated sidecar applications (e.g., Patroni) may already provide this functionality. + In such cases, this action may not be required. + + + The output should be a valid data dump streamed to stdout. It must exclude any irrelevant information to ensure + that only the necessary data is exported for import into the new replica. + + + Note: This field is immutable once it has been set. + properties: + exec: + description: |- + Defines the command to run. + + + This field cannot be updated. + properties: + args: + description: Args represents the arguments that are passed + to the `command` for execution. + items: + type: string + type: array + command: + description: |- + Specifies the command to be executed inside the container. + The working directory for this command is the container's root directory('/'). + Commands are executed directly without a shell environment, meaning shell-specific syntax ('|', etc.) is not supported. + If the shell is required, it must be explicitly invoked in the command. + + + A successful execution is indicated by an exit status of 0; any non-zero status signifies a failure. + items: + type: string + type: array + container: + description: |- + Specifies the name of the container within the same pod whose resources will be shared with the action. + This allows the action to utilize the specified container's resources without executing within it. + + + The name must match one of the containers defined in `componentDefinition.spec.runtime`. + + + The resources that can be shared are included: + + + - volume mounts + + + This field cannot be updated. + type: string + env: + description: |- + Represents a list of environment variables that will be injected into the container. + These variables enable the container to adapt its behavior based on the environment it's running in. + + + This field cannot be updated. + items: + description: EnvVar represents an environment variable + present in a Container. + properties: + name: + description: Name of the environment variable. Must + be a C_IDENTIFIER. + type: string + value: + description: |- + Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in the container and + any service environment variables. If a variable cannot be resolved, + the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless of whether the variable + exists or not. + Defaults to "". + type: string + valueFrom: + description: Source for the environment variable's + value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select + in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required for + volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format + of the exposed resources, defaults to + "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in the + pod's namespace + properties: + key: + description: The key of the secret to select + from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + image: + description: |- + Specifies the container image to be used for running the Action. + + + When specified, a dedicated container will be created using this image to execute the Action. + All actions with same image will share the same container. + + + This field cannot be updated. + type: string + matchingKey: + description: |- + Used in conjunction with the `targetPodSelector` field to refine the selection of target pod(s) for Action execution. + The impact of this field depends on the `targetPodSelector` value: + + + - When `targetPodSelector` is set to `Any` or `All`, this field will be ignored. + - When `targetPodSelector` is set to `Role`, only those replicas whose role matches the `matchingKey` + will be selected for the Action. + + + This field cannot be updated. + type: string + targetPodSelector: + description: |- + Defines the criteria used to select the target Pod(s) for executing the Action. + This is useful when there is no default target replica identified. + It allows for precise control over which Pod(s) the Action should run in. + + + If not specified, the Action will be executed in the pod where the Action is triggered, such as the pod + to be removed or added; or a random pod if the Action is triggered at the component level, such as + post-provision or pre-terminate of the component. + + + This field cannot be updated. + enum: + - Any + - All + - Role + - Ordinal + type: string + type: object + preCondition: + description: |- + Specifies the state that the cluster must reach before the Action is executed. + Currently, this is only applicable to the `postProvision` action. + + + The conditions are as follows: + + + - `Immediately`: Executed right after the Component object is created. + The readiness of the Component and its resources is not guaranteed at this stage. + - `RuntimeReady`: The Action is triggered after the Component object has been created and all associated + runtime resources (e.g. Pods) are in a ready state. + - `ComponentReady`: The Action is triggered after the Component itself is in a ready state. + This process does not affect the readiness state of the Component or the Cluster. + - `ClusterReady`: The Action is executed after the Cluster is in a ready state. + This execution does not alter the Component or the Cluster's state of readiness. + + + This field cannot be updated. + type: string + retryPolicy: + description: |- + Defines the strategy to be taken when retrying the Action after a failure. + + + It specifies the conditions under which the Action should be retried and the limits to apply, + such as the maximum number of retries and backoff strategy. + + + This field cannot be updated. + properties: + maxRetries: + default: 0 + description: |- + Defines the maximum number of retry attempts that should be made for a given Action. + This value is set to 0 by default, indicating that no retries will be made. + type: integer + retryInterval: + default: 0 + description: |- + Indicates the duration of time to wait between each retry attempt. + This value is set to 0 by default, indicating that there will be no delay between retry attempts. + format: int64 + type: integer + type: object + timeoutSeconds: + default: 0 + description: |- + Specifies the maximum duration in seconds that the Action is allowed to run. + + + If the Action does not complete within this time frame, it will be terminated. + + + This field cannot be updated. + format: int32 + type: integer + type: object + dataLoad: + description: |- + Defines the procedure for importing data into a replica. + + + Use Case: + This action is intended for initializing a newly created replica with data. It involves exporting data + from an existing replica and importing it into the new, empty replica. This is essential for synchronizing + the state of replicas across the system. + + + Some database engines or associated sidecar applications (e.g., Patroni) may already provide this functionality. + In such cases, this action may not be required. + + + Data should be received through stdin. If any error occurs during the process, + the action must be able to guarantee idempotence to allow for retries from the beginning. + + + Note: This field is immutable once it has been set. + properties: + exec: + description: |- + Defines the command to run. + + + This field cannot be updated. + properties: + args: + description: Args represents the arguments that are passed + to the `command` for execution. + items: + type: string + type: array + command: + description: |- + Specifies the command to be executed inside the container. + The working directory for this command is the container's root directory('/'). + Commands are executed directly without a shell environment, meaning shell-specific syntax ('|', etc.) is not supported. + If the shell is required, it must be explicitly invoked in the command. + + + A successful execution is indicated by an exit status of 0; any non-zero status signifies a failure. + items: + type: string + type: array + container: + description: |- + Specifies the name of the container within the same pod whose resources will be shared with the action. + This allows the action to utilize the specified container's resources without executing within it. + + + The name must match one of the containers defined in `componentDefinition.spec.runtime`. + + + The resources that can be shared are included: + + + - volume mounts + + + This field cannot be updated. + type: string + env: + description: |- + Represents a list of environment variables that will be injected into the container. + These variables enable the container to adapt its behavior based on the environment it's running in. + + + This field cannot be updated. + items: + description: EnvVar represents an environment variable + present in a Container. + properties: + name: + description: Name of the environment variable. Must + be a C_IDENTIFIER. + type: string + value: + description: |- + Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in the container and + any service environment variables. If a variable cannot be resolved, + the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless of whether the variable + exists or not. + Defaults to "". + type: string + valueFrom: + description: Source for the environment variable's + value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select + in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required for + volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format + of the exposed resources, defaults to + "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in the + pod's namespace + properties: + key: + description: The key of the secret to select + from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + image: + description: |- + Specifies the container image to be used for running the Action. + + + When specified, a dedicated container will be created using this image to execute the Action. + All actions with same image will share the same container. + + + This field cannot be updated. + type: string + matchingKey: + description: |- + Used in conjunction with the `targetPodSelector` field to refine the selection of target pod(s) for Action execution. + The impact of this field depends on the `targetPodSelector` value: + + + - When `targetPodSelector` is set to `Any` or `All`, this field will be ignored. + - When `targetPodSelector` is set to `Role`, only those replicas whose role matches the `matchingKey` + will be selected for the Action. + + + This field cannot be updated. + type: string + targetPodSelector: + description: |- + Defines the criteria used to select the target Pod(s) for executing the Action. + This is useful when there is no default target replica identified. + It allows for precise control over which Pod(s) the Action should run in. + + + If not specified, the Action will be executed in the pod where the Action is triggered, such as the pod + to be removed or added; or a random pod if the Action is triggered at the component level, such as + post-provision or pre-terminate of the component. + + + This field cannot be updated. + enum: + - Any + - All + - Role + - Ordinal + type: string + type: object + preCondition: + description: |- + Specifies the state that the cluster must reach before the Action is executed. + Currently, this is only applicable to the `postProvision` action. + + + The conditions are as follows: + + + - `Immediately`: Executed right after the Component object is created. + The readiness of the Component and its resources is not guaranteed at this stage. + - `RuntimeReady`: The Action is triggered after the Component object has been created and all associated + runtime resources (e.g. Pods) are in a ready state. + - `ComponentReady`: The Action is triggered after the Component itself is in a ready state. + This process does not affect the readiness state of the Component or the Cluster. + - `ClusterReady`: The Action is executed after the Cluster is in a ready state. + This execution does not alter the Component or the Cluster's state of readiness. + + + This field cannot be updated. + type: string + retryPolicy: + description: |- + Defines the strategy to be taken when retrying the Action after a failure. + + + It specifies the conditions under which the Action should be retried and the limits to apply, + such as the maximum number of retries and backoff strategy. + + + This field cannot be updated. + properties: + maxRetries: + default: 0 + description: |- + Defines the maximum number of retry attempts that should be made for a given Action. + This value is set to 0 by default, indicating that no retries will be made. + type: integer + retryInterval: + default: 0 + description: |- + Indicates the duration of time to wait between each retry attempt. + This value is set to 0 by default, indicating that there will be no delay between retry attempts. + format: int64 + type: integer + type: object + timeoutSeconds: + default: 0 + description: |- + Specifies the maximum duration in seconds that the Action is allowed to run. + + + If the Action does not complete within this time frame, it will be terminated. + + + This field cannot be updated. + format: int32 + type: integer + type: object + memberJoin: + description: "Defines the procedure to add a new replica to the + replication group.\n\n\nThis action is initiated after a replica + pod becomes ready.\n\n\nThe role of the replica (e.g., primary, + secondary) will be determined and assigned as part of the action + command\nimplementation, or automatically by the database kernel + or a sidecar utility like Patroni that implements\na consensus + algorithm.\n\n\nThe container executing this action has access + to following variables:\n\n\n- KB_JOIN_MEMBER_POD_FQDN: The + pod FQDN of the replica being added to the group.\n- KB_JOIN_MEMBER_POD_NAME: + The pod name of the replica being added to the group.\n\n\nExpected + action output:\n- On Failure: An error message detailing the + reason for any failure encountered\n during the addition of + the new member.\n\n\nFor example, to add a new OBServer to an + OceanBase Cluster in 'zone1', the following command may be used:\n\n\n```yaml\ncommand:\n- + bash\n- -c\n- |\n CLIENT=\"mysql -u $SERVICE_USER -p$SERVICE_PASSWORD + -P $SERVICE_PORT -h $SERVICE_HOST -e\"\n\t $CLIENT \"ALTER + SYSTEM ADD SERVER '$KB_POD_FQDN:$SERVICE_PORT' ZONE 'zone1'\"\n```\n\n\nNote: + This field is immutable once it has been set." + properties: + exec: + description: |- + Defines the command to run. + + + This field cannot be updated. + properties: + args: + description: Args represents the arguments that are passed + to the `command` for execution. + items: + type: string + type: array + command: + description: |- + Specifies the command to be executed inside the container. + The working directory for this command is the container's root directory('/'). + Commands are executed directly without a shell environment, meaning shell-specific syntax ('|', etc.) is not supported. + If the shell is required, it must be explicitly invoked in the command. + + + A successful execution is indicated by an exit status of 0; any non-zero status signifies a failure. + items: + type: string + type: array + container: + description: |- + Specifies the name of the container within the same pod whose resources will be shared with the action. + This allows the action to utilize the specified container's resources without executing within it. + + + The name must match one of the containers defined in `componentDefinition.spec.runtime`. + + + The resources that can be shared are included: + + + - volume mounts + + + This field cannot be updated. + type: string + env: + description: |- + Represents a list of environment variables that will be injected into the container. + These variables enable the container to adapt its behavior based on the environment it's running in. + + + This field cannot be updated. + items: + description: EnvVar represents an environment variable + present in a Container. + properties: + name: + description: Name of the environment variable. Must + be a C_IDENTIFIER. + type: string + value: + description: |- + Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in the container and + any service environment variables. If a variable cannot be resolved, + the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless of whether the variable + exists or not. + Defaults to "". + type: string + valueFrom: + description: Source for the environment variable's + value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select + in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required for + volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format + of the exposed resources, defaults to + "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in the + pod's namespace + properties: + key: + description: The key of the secret to select + from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + image: + description: |- + Specifies the container image to be used for running the Action. + + + When specified, a dedicated container will be created using this image to execute the Action. + All actions with same image will share the same container. + + + This field cannot be updated. + type: string + matchingKey: + description: |- + Used in conjunction with the `targetPodSelector` field to refine the selection of target pod(s) for Action execution. + The impact of this field depends on the `targetPodSelector` value: + + + - When `targetPodSelector` is set to `Any` or `All`, this field will be ignored. + - When `targetPodSelector` is set to `Role`, only those replicas whose role matches the `matchingKey` + will be selected for the Action. + + + This field cannot be updated. + type: string + targetPodSelector: + description: |- + Defines the criteria used to select the target Pod(s) for executing the Action. + This is useful when there is no default target replica identified. + It allows for precise control over which Pod(s) the Action should run in. + + + If not specified, the Action will be executed in the pod where the Action is triggered, such as the pod + to be removed or added; or a random pod if the Action is triggered at the component level, such as + post-provision or pre-terminate of the component. + + + This field cannot be updated. + enum: + - Any + - All + - Role + - Ordinal + type: string + type: object + preCondition: + description: |- + Specifies the state that the cluster must reach before the Action is executed. + Currently, this is only applicable to the `postProvision` action. + + + The conditions are as follows: + + + - `Immediately`: Executed right after the Component object is created. + The readiness of the Component and its resources is not guaranteed at this stage. + - `RuntimeReady`: The Action is triggered after the Component object has been created and all associated + runtime resources (e.g. Pods) are in a ready state. + - `ComponentReady`: The Action is triggered after the Component itself is in a ready state. + This process does not affect the readiness state of the Component or the Cluster. + - `ClusterReady`: The Action is executed after the Cluster is in a ready state. + This execution does not alter the Component or the Cluster's state of readiness. + + + This field cannot be updated. + type: string + retryPolicy: + description: |- + Defines the strategy to be taken when retrying the Action after a failure. + + + It specifies the conditions under which the Action should be retried and the limits to apply, + such as the maximum number of retries and backoff strategy. + + + This field cannot be updated. + properties: + maxRetries: + default: 0 + description: |- + Defines the maximum number of retry attempts that should be made for a given Action. + This value is set to 0 by default, indicating that no retries will be made. + type: integer + retryInterval: + default: 0 + description: |- + Indicates the duration of time to wait between each retry attempt. + This value is set to 0 by default, indicating that there will be no delay between retry attempts. + format: int64 + type: integer + type: object + timeoutSeconds: + default: 0 + description: |- + Specifies the maximum duration in seconds that the Action is allowed to run. + + + If the Action does not complete within this time frame, it will be terminated. + + + This field cannot be updated. + format: int32 + type: integer + type: object + memberLeave: + description: "Defines the procedure to remove a replica from the + replication group.\n\n\nThis action is initiated before remove + a replica from the group.\nThe operator will wait for MemberLeave + to complete successfully before releasing the replica and cleaning + up\nrelated Kubernetes resources.\n\n\nThe process typically + includes updating configurations and informing other group members + about the removal.\nData migration is generally not part of + this action and should be handled separately if needed.\n\n\nThe + container executing this action has access to following variables:\n\n\n- + KB_LEAVE_MEMBER_POD_FQDN: The pod name of the replica being + removed from the group.\n- KB_LEAVE_MEMBER_POD_NAME: The pod + name of the replica being removed from the group.\n\n\nExpected + action output:\n- On Failure: An error message, if applicable, + indicating why the action failed.\n\n\nFor example, to remove + an OBServer from an OceanBase Cluster in 'zone1', the following + command can be executed:\n\n\n```yaml\ncommand:\n- bash\n- -c\n- + |\n CLIENT=\"mysql -u $SERVICE_USER -p$SERVICE_PASSWORD -P + $SERVICE_PORT -h $SERVICE_HOST -e\"\n\t $CLIENT \"ALTER SYSTEM + DELETE SERVER '$KB_POD_FQDN:$SERVICE_PORT' ZONE 'zone1'\"\n```\n\n\nNote: + This field is immutable once it has been set." + properties: + exec: + description: |- + Defines the command to run. + + + This field cannot be updated. + properties: + args: + description: Args represents the arguments that are passed + to the `command` for execution. + items: + type: string + type: array + command: + description: |- + Specifies the command to be executed inside the container. + The working directory for this command is the container's root directory('/'). + Commands are executed directly without a shell environment, meaning shell-specific syntax ('|', etc.) is not supported. + If the shell is required, it must be explicitly invoked in the command. + + + A successful execution is indicated by an exit status of 0; any non-zero status signifies a failure. + items: + type: string + type: array + container: + description: |- + Specifies the name of the container within the same pod whose resources will be shared with the action. + This allows the action to utilize the specified container's resources without executing within it. + + + The name must match one of the containers defined in `componentDefinition.spec.runtime`. + + + The resources that can be shared are included: + + + - volume mounts + + + This field cannot be updated. + type: string + env: + description: |- + Represents a list of environment variables that will be injected into the container. + These variables enable the container to adapt its behavior based on the environment it's running in. + + + This field cannot be updated. + items: + description: EnvVar represents an environment variable + present in a Container. + properties: + name: + description: Name of the environment variable. Must + be a C_IDENTIFIER. + type: string + value: + description: |- + Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in the container and + any service environment variables. If a variable cannot be resolved, + the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless of whether the variable + exists or not. + Defaults to "". + type: string + valueFrom: + description: Source for the environment variable's + value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select + in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required for + volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format + of the exposed resources, defaults to + "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in the + pod's namespace + properties: + key: + description: The key of the secret to select + from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + image: + description: |- + Specifies the container image to be used for running the Action. + + + When specified, a dedicated container will be created using this image to execute the Action. + All actions with same image will share the same container. + + + This field cannot be updated. + type: string + matchingKey: + description: |- + Used in conjunction with the `targetPodSelector` field to refine the selection of target pod(s) for Action execution. + The impact of this field depends on the `targetPodSelector` value: + + + - When `targetPodSelector` is set to `Any` or `All`, this field will be ignored. + - When `targetPodSelector` is set to `Role`, only those replicas whose role matches the `matchingKey` + will be selected for the Action. + + + This field cannot be updated. + type: string + targetPodSelector: + description: |- + Defines the criteria used to select the target Pod(s) for executing the Action. + This is useful when there is no default target replica identified. + It allows for precise control over which Pod(s) the Action should run in. + + + If not specified, the Action will be executed in the pod where the Action is triggered, such as the pod + to be removed or added; or a random pod if the Action is triggered at the component level, such as + post-provision or pre-terminate of the component. + + + This field cannot be updated. + enum: + - Any + - All + - Role + - Ordinal + type: string + type: object + preCondition: + description: |- + Specifies the state that the cluster must reach before the Action is executed. + Currently, this is only applicable to the `postProvision` action. + + + The conditions are as follows: + + + - `Immediately`: Executed right after the Component object is created. + The readiness of the Component and its resources is not guaranteed at this stage. + - `RuntimeReady`: The Action is triggered after the Component object has been created and all associated + runtime resources (e.g. Pods) are in a ready state. + - `ComponentReady`: The Action is triggered after the Component itself is in a ready state. + This process does not affect the readiness state of the Component or the Cluster. + - `ClusterReady`: The Action is executed after the Cluster is in a ready state. + This execution does not alter the Component or the Cluster's state of readiness. + + + This field cannot be updated. + type: string + retryPolicy: + description: |- + Defines the strategy to be taken when retrying the Action after a failure. + + + It specifies the conditions under which the Action should be retried and the limits to apply, + such as the maximum number of retries and backoff strategy. + + + This field cannot be updated. + properties: + maxRetries: + default: 0 + description: |- + Defines the maximum number of retry attempts that should be made for a given Action. + This value is set to 0 by default, indicating that no retries will be made. + type: integer + retryInterval: + default: 0 + description: |- + Indicates the duration of time to wait between each retry attempt. + This value is set to 0 by default, indicating that there will be no delay between retry attempts. + format: int64 + type: integer + type: object + timeoutSeconds: + default: 0 + description: |- + Specifies the maximum duration in seconds that the Action is allowed to run. + + + If the Action does not complete within this time frame, it will be terminated. + + + This field cannot be updated. + format: int32 + type: integer + type: object + postProvision: + description: |- + Specifies the hook to be executed after a component's creation. + + + By setting `postProvision.customHandler.preCondition`, you can determine the specific lifecycle stage + at which the action should trigger: `Immediately`, `RuntimeReady`, `ComponentReady`, and `ClusterReady`. + with `ComponentReady` being the default. + + + The PostProvision Action is intended to run only once. + + + Note: This field is immutable once it has been set. + properties: + exec: + description: |- + Defines the command to run. + + + This field cannot be updated. + properties: + args: + description: Args represents the arguments that are passed + to the `command` for execution. + items: + type: string + type: array + command: + description: |- + Specifies the command to be executed inside the container. + The working directory for this command is the container's root directory('/'). + Commands are executed directly without a shell environment, meaning shell-specific syntax ('|', etc.) is not supported. + If the shell is required, it must be explicitly invoked in the command. + + + A successful execution is indicated by an exit status of 0; any non-zero status signifies a failure. + items: + type: string + type: array + container: + description: |- + Specifies the name of the container within the same pod whose resources will be shared with the action. + This allows the action to utilize the specified container's resources without executing within it. + + + The name must match one of the containers defined in `componentDefinition.spec.runtime`. + + + The resources that can be shared are included: + + + - volume mounts + + + This field cannot be updated. + type: string + env: + description: |- + Represents a list of environment variables that will be injected into the container. + These variables enable the container to adapt its behavior based on the environment it's running in. + + + This field cannot be updated. + items: + description: EnvVar represents an environment variable + present in a Container. + properties: + name: + description: Name of the environment variable. Must + be a C_IDENTIFIER. + type: string + value: + description: |- + Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in the container and + any service environment variables. If a variable cannot be resolved, + the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless of whether the variable + exists or not. + Defaults to "". + type: string + valueFrom: + description: Source for the environment variable's + value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select + in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required for + volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format + of the exposed resources, defaults to + "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in the + pod's namespace + properties: + key: + description: The key of the secret to select + from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + image: + description: |- + Specifies the container image to be used for running the Action. + + + When specified, a dedicated container will be created using this image to execute the Action. + All actions with same image will share the same container. + + + This field cannot be updated. + type: string + matchingKey: + description: |- + Used in conjunction with the `targetPodSelector` field to refine the selection of target pod(s) for Action execution. + The impact of this field depends on the `targetPodSelector` value: + + + - When `targetPodSelector` is set to `Any` or `All`, this field will be ignored. + - When `targetPodSelector` is set to `Role`, only those replicas whose role matches the `matchingKey` + will be selected for the Action. + + + This field cannot be updated. + type: string + targetPodSelector: + description: |- + Defines the criteria used to select the target Pod(s) for executing the Action. + This is useful when there is no default target replica identified. + It allows for precise control over which Pod(s) the Action should run in. + + + If not specified, the Action will be executed in the pod where the Action is triggered, such as the pod + to be removed or added; or a random pod if the Action is triggered at the component level, such as + post-provision or pre-terminate of the component. + + + This field cannot be updated. + enum: + - Any + - All + - Role + - Ordinal + type: string + type: object + preCondition: + description: |- + Specifies the state that the cluster must reach before the Action is executed. + Currently, this is only applicable to the `postProvision` action. + + + The conditions are as follows: + + + - `Immediately`: Executed right after the Component object is created. + The readiness of the Component and its resources is not guaranteed at this stage. + - `RuntimeReady`: The Action is triggered after the Component object has been created and all associated + runtime resources (e.g. Pods) are in a ready state. + - `ComponentReady`: The Action is triggered after the Component itself is in a ready state. + This process does not affect the readiness state of the Component or the Cluster. + - `ClusterReady`: The Action is executed after the Cluster is in a ready state. + This execution does not alter the Component or the Cluster's state of readiness. + + + This field cannot be updated. + type: string + retryPolicy: + description: |- + Defines the strategy to be taken when retrying the Action after a failure. + + + It specifies the conditions under which the Action should be retried and the limits to apply, + such as the maximum number of retries and backoff strategy. + + + This field cannot be updated. + properties: + maxRetries: + default: 0 + description: |- + Defines the maximum number of retry attempts that should be made for a given Action. + This value is set to 0 by default, indicating that no retries will be made. + type: integer + retryInterval: + default: 0 + description: |- + Indicates the duration of time to wait between each retry attempt. + This value is set to 0 by default, indicating that there will be no delay between retry attempts. + format: int64 + type: integer + type: object + timeoutSeconds: + default: 0 + description: |- + Specifies the maximum duration in seconds that the Action is allowed to run. + + + If the Action does not complete within this time frame, it will be terminated. + + + This field cannot be updated. + format: int32 + type: integer + type: object + preTerminate: + description: |- + Specifies the hook to be executed prior to terminating a component. + + + The PreTerminate Action is intended to run only once. + + + This action is executed immediately when a scale-down operation for the Component is initiated. + The actual termination and cleanup of the Component and its associated resources will not proceed + until the PreTerminate action has completed successfully. + + + Note: This field is immutable once it has been set. + properties: + exec: + description: |- + Defines the command to run. + + + This field cannot be updated. + properties: + args: + description: Args represents the arguments that are passed + to the `command` for execution. + items: + type: string + type: array + command: + description: |- + Specifies the command to be executed inside the container. + The working directory for this command is the container's root directory('/'). + Commands are executed directly without a shell environment, meaning shell-specific syntax ('|', etc.) is not supported. + If the shell is required, it must be explicitly invoked in the command. + + + A successful execution is indicated by an exit status of 0; any non-zero status signifies a failure. + items: + type: string + type: array + container: + description: |- + Specifies the name of the container within the same pod whose resources will be shared with the action. + This allows the action to utilize the specified container's resources without executing within it. + + + The name must match one of the containers defined in `componentDefinition.spec.runtime`. + + + The resources that can be shared are included: + + + - volume mounts + + + This field cannot be updated. + type: string + env: + description: |- + Represents a list of environment variables that will be injected into the container. + These variables enable the container to adapt its behavior based on the environment it's running in. + + + This field cannot be updated. + items: + description: EnvVar represents an environment variable + present in a Container. + properties: + name: + description: Name of the environment variable. Must + be a C_IDENTIFIER. + type: string + value: + description: |- + Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in the container and + any service environment variables. If a variable cannot be resolved, + the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless of whether the variable + exists or not. + Defaults to "". + type: string + valueFrom: + description: Source for the environment variable's + value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select + in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required for + volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format + of the exposed resources, defaults to + "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in the + pod's namespace + properties: + key: + description: The key of the secret to select + from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + image: + description: |- + Specifies the container image to be used for running the Action. + + + When specified, a dedicated container will be created using this image to execute the Action. + All actions with same image will share the same container. + + + This field cannot be updated. + type: string + matchingKey: + description: |- + Used in conjunction with the `targetPodSelector` field to refine the selection of target pod(s) for Action execution. + The impact of this field depends on the `targetPodSelector` value: + + + - When `targetPodSelector` is set to `Any` or `All`, this field will be ignored. + - When `targetPodSelector` is set to `Role`, only those replicas whose role matches the `matchingKey` + will be selected for the Action. + + + This field cannot be updated. + type: string + targetPodSelector: + description: |- + Defines the criteria used to select the target Pod(s) for executing the Action. + This is useful when there is no default target replica identified. + It allows for precise control over which Pod(s) the Action should run in. + + + If not specified, the Action will be executed in the pod where the Action is triggered, such as the pod + to be removed or added; or a random pod if the Action is triggered at the component level, such as + post-provision or pre-terminate of the component. + + + This field cannot be updated. + enum: + - Any + - All + - Role + - Ordinal + type: string + type: object + preCondition: + description: |- + Specifies the state that the cluster must reach before the Action is executed. + Currently, this is only applicable to the `postProvision` action. + + + The conditions are as follows: + + + - `Immediately`: Executed right after the Component object is created. + The readiness of the Component and its resources is not guaranteed at this stage. + - `RuntimeReady`: The Action is triggered after the Component object has been created and all associated + runtime resources (e.g. Pods) are in a ready state. + - `ComponentReady`: The Action is triggered after the Component itself is in a ready state. + This process does not affect the readiness state of the Component or the Cluster. + - `ClusterReady`: The Action is executed after the Cluster is in a ready state. + This execution does not alter the Component or the Cluster's state of readiness. + + + This field cannot be updated. + type: string + retryPolicy: + description: |- + Defines the strategy to be taken when retrying the Action after a failure. + + + It specifies the conditions under which the Action should be retried and the limits to apply, + such as the maximum number of retries and backoff strategy. + + + This field cannot be updated. + properties: + maxRetries: + default: 0 + description: |- + Defines the maximum number of retry attempts that should be made for a given Action. + This value is set to 0 by default, indicating that no retries will be made. + type: integer + retryInterval: + default: 0 + description: |- + Indicates the duration of time to wait between each retry attempt. + This value is set to 0 by default, indicating that there will be no delay between retry attempts. + format: int64 + type: integer + type: object + timeoutSeconds: + default: 0 + description: |- + Specifies the maximum duration in seconds that the Action is allowed to run. + + + If the Action does not complete within this time frame, it will be terminated. + + + This field cannot be updated. + format: int32 + type: integer + type: object + readonly: + description: |- + Defines the procedure to switch a replica into the read-only state. + + + Use Case: + This action is invoked when the database's volume capacity nears its upper limit and space is about to be exhausted. + + + The container executing this action has access to following environment variables: + + + - KB_POD_FQDN: The FQDN of the replica pod whose role is being checked. + + + Expected action output: + - On Failure: An error message, if applicable, indicating why the action failed. + + + Note: This field is immutable once it has been set. + properties: + exec: + description: |- + Defines the command to run. + + + This field cannot be updated. + properties: + args: + description: Args represents the arguments that are passed + to the `command` for execution. + items: + type: string + type: array + command: + description: |- + Specifies the command to be executed inside the container. + The working directory for this command is the container's root directory('/'). + Commands are executed directly without a shell environment, meaning shell-specific syntax ('|', etc.) is not supported. + If the shell is required, it must be explicitly invoked in the command. + + + A successful execution is indicated by an exit status of 0; any non-zero status signifies a failure. + items: + type: string + type: array + container: + description: |- + Specifies the name of the container within the same pod whose resources will be shared with the action. + This allows the action to utilize the specified container's resources without executing within it. + + + The name must match one of the containers defined in `componentDefinition.spec.runtime`. + + + The resources that can be shared are included: + + + - volume mounts + + + This field cannot be updated. + type: string + env: + description: |- + Represents a list of environment variables that will be injected into the container. + These variables enable the container to adapt its behavior based on the environment it's running in. + + + This field cannot be updated. + items: + description: EnvVar represents an environment variable + present in a Container. + properties: + name: + description: Name of the environment variable. Must + be a C_IDENTIFIER. + type: string + value: + description: |- + Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in the container and + any service environment variables. If a variable cannot be resolved, + the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless of whether the variable + exists or not. + Defaults to "". + type: string + valueFrom: + description: Source for the environment variable's + value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select + in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required for + volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format + of the exposed resources, defaults to + "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in the + pod's namespace + properties: + key: + description: The key of the secret to select + from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + image: + description: |- + Specifies the container image to be used for running the Action. + + + When specified, a dedicated container will be created using this image to execute the Action. + All actions with same image will share the same container. + + + This field cannot be updated. + type: string + matchingKey: + description: |- + Used in conjunction with the `targetPodSelector` field to refine the selection of target pod(s) for Action execution. + The impact of this field depends on the `targetPodSelector` value: + + + - When `targetPodSelector` is set to `Any` or `All`, this field will be ignored. + - When `targetPodSelector` is set to `Role`, only those replicas whose role matches the `matchingKey` + will be selected for the Action. + + + This field cannot be updated. + type: string + targetPodSelector: + description: |- + Defines the criteria used to select the target Pod(s) for executing the Action. + This is useful when there is no default target replica identified. + It allows for precise control over which Pod(s) the Action should run in. + + + If not specified, the Action will be executed in the pod where the Action is triggered, such as the pod + to be removed or added; or a random pod if the Action is triggered at the component level, such as + post-provision or pre-terminate of the component. + + + This field cannot be updated. + enum: + - Any + - All + - Role + - Ordinal + type: string + type: object + preCondition: + description: |- + Specifies the state that the cluster must reach before the Action is executed. + Currently, this is only applicable to the `postProvision` action. + + + The conditions are as follows: + + + - `Immediately`: Executed right after the Component object is created. + The readiness of the Component and its resources is not guaranteed at this stage. + - `RuntimeReady`: The Action is triggered after the Component object has been created and all associated + runtime resources (e.g. Pods) are in a ready state. + - `ComponentReady`: The Action is triggered after the Component itself is in a ready state. + This process does not affect the readiness state of the Component or the Cluster. + - `ClusterReady`: The Action is executed after the Cluster is in a ready state. + This execution does not alter the Component or the Cluster's state of readiness. + + + This field cannot be updated. + type: string + retryPolicy: + description: |- + Defines the strategy to be taken when retrying the Action after a failure. + + + It specifies the conditions under which the Action should be retried and the limits to apply, + such as the maximum number of retries and backoff strategy. + + + This field cannot be updated. + properties: + maxRetries: + default: 0 + description: |- + Defines the maximum number of retry attempts that should be made for a given Action. + This value is set to 0 by default, indicating that no retries will be made. + type: integer + retryInterval: + default: 0 + description: |- + Indicates the duration of time to wait between each retry attempt. + This value is set to 0 by default, indicating that there will be no delay between retry attempts. + format: int64 + type: integer + type: object + timeoutSeconds: + default: 0 + description: |- + Specifies the maximum duration in seconds that the Action is allowed to run. + + + If the Action does not complete within this time frame, it will be terminated. + + + This field cannot be updated. + format: int32 + type: integer + type: object + readwrite: + description: |- + Defines the procedure to transition a replica from the read-only state back to the read-write state. + + + Use Case: + This action is used to bring back a replica that was previously in a read-only state, + which restricted write operations, to its normal operational state where it can handle + both read and write operations. + + + The container executing this action has access to following environment variables: + + + - KB_POD_FQDN: The FQDN of the replica pod whose role is being checked. + + + Expected action output: + - On Failure: An error message, if applicable, indicating why the action failed. + + + Note: This field is immutable once it has been set. + properties: + exec: + description: |- + Defines the command to run. + + + This field cannot be updated. + properties: + args: + description: Args represents the arguments that are passed + to the `command` for execution. + items: + type: string + type: array + command: + description: |- + Specifies the command to be executed inside the container. + The working directory for this command is the container's root directory('/'). + Commands are executed directly without a shell environment, meaning shell-specific syntax ('|', etc.) is not supported. + If the shell is required, it must be explicitly invoked in the command. + + + A successful execution is indicated by an exit status of 0; any non-zero status signifies a failure. + items: + type: string + type: array + container: + description: |- + Specifies the name of the container within the same pod whose resources will be shared with the action. + This allows the action to utilize the specified container's resources without executing within it. + + + The name must match one of the containers defined in `componentDefinition.spec.runtime`. + + + The resources that can be shared are included: + + + - volume mounts + + + This field cannot be updated. + type: string + env: + description: |- + Represents a list of environment variables that will be injected into the container. + These variables enable the container to adapt its behavior based on the environment it's running in. + + + This field cannot be updated. + items: + description: EnvVar represents an environment variable + present in a Container. + properties: + name: + description: Name of the environment variable. Must + be a C_IDENTIFIER. + type: string + value: + description: |- + Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in the container and + any service environment variables. If a variable cannot be resolved, + the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless of whether the variable + exists or not. + Defaults to "". + type: string + valueFrom: + description: Source for the environment variable's + value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select + in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required for + volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format + of the exposed resources, defaults to + "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in the + pod's namespace + properties: + key: + description: The key of the secret to select + from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + image: + description: |- + Specifies the container image to be used for running the Action. + + + When specified, a dedicated container will be created using this image to execute the Action. + All actions with same image will share the same container. + + + This field cannot be updated. + type: string + matchingKey: + description: |- + Used in conjunction with the `targetPodSelector` field to refine the selection of target pod(s) for Action execution. + The impact of this field depends on the `targetPodSelector` value: + + + - When `targetPodSelector` is set to `Any` or `All`, this field will be ignored. + - When `targetPodSelector` is set to `Role`, only those replicas whose role matches the `matchingKey` + will be selected for the Action. + + + This field cannot be updated. + type: string + targetPodSelector: + description: |- + Defines the criteria used to select the target Pod(s) for executing the Action. + This is useful when there is no default target replica identified. + It allows for precise control over which Pod(s) the Action should run in. + + + If not specified, the Action will be executed in the pod where the Action is triggered, such as the pod + to be removed or added; or a random pod if the Action is triggered at the component level, such as + post-provision or pre-terminate of the component. + + + This field cannot be updated. + enum: + - Any + - All + - Role + - Ordinal + type: string + type: object + preCondition: + description: |- + Specifies the state that the cluster must reach before the Action is executed. + Currently, this is only applicable to the `postProvision` action. + + + The conditions are as follows: + + + - `Immediately`: Executed right after the Component object is created. + The readiness of the Component and its resources is not guaranteed at this stage. + - `RuntimeReady`: The Action is triggered after the Component object has been created and all associated + runtime resources (e.g. Pods) are in a ready state. + - `ComponentReady`: The Action is triggered after the Component itself is in a ready state. + This process does not affect the readiness state of the Component or the Cluster. + - `ClusterReady`: The Action is executed after the Cluster is in a ready state. + This execution does not alter the Component or the Cluster's state of readiness. + + + This field cannot be updated. + type: string + retryPolicy: + description: |- + Defines the strategy to be taken when retrying the Action after a failure. + + + It specifies the conditions under which the Action should be retried and the limits to apply, + such as the maximum number of retries and backoff strategy. + + + This field cannot be updated. + properties: + maxRetries: + default: 0 + description: |- + Defines the maximum number of retry attempts that should be made for a given Action. + This value is set to 0 by default, indicating that no retries will be made. + type: integer + retryInterval: + default: 0 + description: |- + Indicates the duration of time to wait between each retry attempt. + This value is set to 0 by default, indicating that there will be no delay between retry attempts. + format: int64 + type: integer + type: object + timeoutSeconds: + default: 0 + description: |- + Specifies the maximum duration in seconds that the Action is allowed to run. + + + If the Action does not complete within this time frame, it will be terminated. + + + This field cannot be updated. + format: int32 + type: integer + type: object + reconfigure: + description: |- + Defines the procedure that update a replica with new configuration. + + + Note: This field is immutable once it has been set. + + + This Action is reserved for future versions. + properties: + exec: + description: |- + Defines the command to run. + + + This field cannot be updated. + properties: + args: + description: Args represents the arguments that are passed + to the `command` for execution. + items: + type: string + type: array + command: + description: |- + Specifies the command to be executed inside the container. + The working directory for this command is the container's root directory('/'). + Commands are executed directly without a shell environment, meaning shell-specific syntax ('|', etc.) is not supported. + If the shell is required, it must be explicitly invoked in the command. + + + A successful execution is indicated by an exit status of 0; any non-zero status signifies a failure. + items: + type: string + type: array + container: + description: |- + Specifies the name of the container within the same pod whose resources will be shared with the action. + This allows the action to utilize the specified container's resources without executing within it. + + + The name must match one of the containers defined in `componentDefinition.spec.runtime`. + + + The resources that can be shared are included: + + + - volume mounts + + + This field cannot be updated. + type: string + env: + description: |- + Represents a list of environment variables that will be injected into the container. + These variables enable the container to adapt its behavior based on the environment it's running in. + + + This field cannot be updated. + items: + description: EnvVar represents an environment variable + present in a Container. + properties: + name: + description: Name of the environment variable. Must + be a C_IDENTIFIER. + type: string + value: + description: |- + Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in the container and + any service environment variables. If a variable cannot be resolved, + the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless of whether the variable + exists or not. + Defaults to "". + type: string + valueFrom: + description: Source for the environment variable's + value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select + in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required for + volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format + of the exposed resources, defaults to + "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in the + pod's namespace + properties: + key: + description: The key of the secret to select + from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + image: + description: |- + Specifies the container image to be used for running the Action. + + + When specified, a dedicated container will be created using this image to execute the Action. + All actions with same image will share the same container. + + + This field cannot be updated. + type: string + matchingKey: + description: |- + Used in conjunction with the `targetPodSelector` field to refine the selection of target pod(s) for Action execution. + The impact of this field depends on the `targetPodSelector` value: + + + - When `targetPodSelector` is set to `Any` or `All`, this field will be ignored. + - When `targetPodSelector` is set to `Role`, only those replicas whose role matches the `matchingKey` + will be selected for the Action. + + + This field cannot be updated. + type: string + targetPodSelector: + description: |- + Defines the criteria used to select the target Pod(s) for executing the Action. + This is useful when there is no default target replica identified. + It allows for precise control over which Pod(s) the Action should run in. + + + If not specified, the Action will be executed in the pod where the Action is triggered, such as the pod + to be removed or added; or a random pod if the Action is triggered at the component level, such as + post-provision or pre-terminate of the component. + + + This field cannot be updated. + enum: + - Any + - All + - Role + - Ordinal + type: string + type: object + preCondition: + description: |- + Specifies the state that the cluster must reach before the Action is executed. + Currently, this is only applicable to the `postProvision` action. + + + The conditions are as follows: + + + - `Immediately`: Executed right after the Component object is created. + The readiness of the Component and its resources is not guaranteed at this stage. + - `RuntimeReady`: The Action is triggered after the Component object has been created and all associated + runtime resources (e.g. Pods) are in a ready state. + - `ComponentReady`: The Action is triggered after the Component itself is in a ready state. + This process does not affect the readiness state of the Component or the Cluster. + - `ClusterReady`: The Action is executed after the Cluster is in a ready state. + This execution does not alter the Component or the Cluster's state of readiness. + + + This field cannot be updated. + type: string + retryPolicy: + description: |- + Defines the strategy to be taken when retrying the Action after a failure. + + + It specifies the conditions under which the Action should be retried and the limits to apply, + such as the maximum number of retries and backoff strategy. + + + This field cannot be updated. + properties: + maxRetries: + default: 0 + description: |- + Defines the maximum number of retry attempts that should be made for a given Action. + This value is set to 0 by default, indicating that no retries will be made. + type: integer + retryInterval: + default: 0 + description: |- + Indicates the duration of time to wait between each retry attempt. + This value is set to 0 by default, indicating that there will be no delay between retry attempts. + format: int64 + type: integer + type: object + timeoutSeconds: + default: 0 + description: |- + Specifies the maximum duration in seconds that the Action is allowed to run. + + + If the Action does not complete within this time frame, it will be terminated. + + + This field cannot be updated. + format: int32 + type: integer + type: object + roleProbe: + description: |- + Defines the procedure which is invoked regularly to assess the role of replicas. + + + This action is periodically triggered at the specified interval to determine the role of each replica. + Upon successful execution, the action's output designates the role of the replica, + which should match one of the predefined role names within `componentDefinition.spec.roles`. + The output is then compared with the previous successful execution result. + If a role change is detected, an event is generated to inform the controller, + which initiates an update of the replica's role. + + + Defining a RoleProbe Action for a Component is required if roles are defined for the Component. + It ensures replicas are correctly labeled with their respective roles. + Without this, services that rely on roleSelectors might improperly direct traffic to wrong replicas. + + + The container executing this action has access to following variables: + + + - KB_POD_FQDN: The FQDN of the Pod whose role is being assessed. + + + Expected output of this action: + - On Success: The determined role of the replica, which must align with one of the roles specified + in the component definition. + - On Failure: An error message, if applicable, indicating why the action failed. + + + Note: This field is immutable once it has been set. + properties: + exec: + description: |- + Defines the command to run. + + + This field cannot be updated. + properties: + args: + description: Args represents the arguments that are passed + to the `command` for execution. + items: + type: string + type: array + command: + description: |- + Specifies the command to be executed inside the container. + The working directory for this command is the container's root directory('/'). + Commands are executed directly without a shell environment, meaning shell-specific syntax ('|', etc.) is not supported. + If the shell is required, it must be explicitly invoked in the command. + + + A successful execution is indicated by an exit status of 0; any non-zero status signifies a failure. + items: + type: string + type: array + container: + description: |- + Specifies the name of the container within the same pod whose resources will be shared with the action. + This allows the action to utilize the specified container's resources without executing within it. + + + The name must match one of the containers defined in `componentDefinition.spec.runtime`. + + + The resources that can be shared are included: + + + - volume mounts + + + This field cannot be updated. + type: string + env: + description: |- + Represents a list of environment variables that will be injected into the container. + These variables enable the container to adapt its behavior based on the environment it's running in. + + + This field cannot be updated. + items: + description: EnvVar represents an environment variable + present in a Container. + properties: + name: + description: Name of the environment variable. Must + be a C_IDENTIFIER. + type: string + value: + description: |- + Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in the container and + any service environment variables. If a variable cannot be resolved, + the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless of whether the variable + exists or not. + Defaults to "". + type: string + valueFrom: + description: Source for the environment variable's + value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select + in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required for + volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format + of the exposed resources, defaults to + "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in the + pod's namespace + properties: + key: + description: The key of the secret to select + from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + image: + description: |- + Specifies the container image to be used for running the Action. + + + When specified, a dedicated container will be created using this image to execute the Action. + All actions with same image will share the same container. + + + This field cannot be updated. + type: string + matchingKey: + description: |- + Used in conjunction with the `targetPodSelector` field to refine the selection of target pod(s) for Action execution. + The impact of this field depends on the `targetPodSelector` value: + + + - When `targetPodSelector` is set to `Any` or `All`, this field will be ignored. + - When `targetPodSelector` is set to `Role`, only those replicas whose role matches the `matchingKey` + will be selected for the Action. + + + This field cannot be updated. + type: string + targetPodSelector: + description: |- + Defines the criteria used to select the target Pod(s) for executing the Action. + This is useful when there is no default target replica identified. + It allows for precise control over which Pod(s) the Action should run in. + + + If not specified, the Action will be executed in the pod where the Action is triggered, such as the pod + to be removed or added; or a random pod if the Action is triggered at the component level, such as + post-provision or pre-terminate of the component. + + + This field cannot be updated. + enum: + - Any + - All + - Role + - Ordinal + type: string + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + initialDelaySeconds: + description: |- + Specifies the number of seconds to wait after the container has started before the RoleProbe + begins to detect the container's role. + format: int32 + type: integer + periodSeconds: + description: |- + Specifies the frequency at which the probe is conducted. This value is expressed in seconds. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + preCondition: + description: |- + Specifies the state that the cluster must reach before the Action is executed. + Currently, this is only applicable to the `postProvision` action. + + + The conditions are as follows: + + + - `Immediately`: Executed right after the Component object is created. + The readiness of the Component and its resources is not guaranteed at this stage. + - `RuntimeReady`: The Action is triggered after the Component object has been created and all associated + runtime resources (e.g. Pods) are in a ready state. + - `ComponentReady`: The Action is triggered after the Component itself is in a ready state. + This process does not affect the readiness state of the Component or the Cluster. + - `ClusterReady`: The Action is executed after the Cluster is in a ready state. + This execution does not alter the Component or the Cluster's state of readiness. + + + This field cannot be updated. + type: string + retryPolicy: + description: |- + Defines the strategy to be taken when retrying the Action after a failure. + + + It specifies the conditions under which the Action should be retried and the limits to apply, + such as the maximum number of retries and backoff strategy. + + + This field cannot be updated. + properties: + maxRetries: + default: 0 + description: |- + Defines the maximum number of retry attempts that should be made for a given Action. + This value is set to 0 by default, indicating that no retries will be made. + type: integer + retryInterval: + default: 0 + description: |- + Indicates the duration of time to wait between each retry attempt. + This value is set to 0 by default, indicating that there will be no delay between retry attempts. + format: int64 + type: integer + type: object + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Minimum value is 1. + format: int32 + type: integer + timeoutSeconds: + default: 0 + description: |- + Specifies the maximum duration in seconds that the Action is allowed to run. + + + If the Action does not complete within this time frame, it will be terminated. + + + This field cannot be updated. + format: int32 + type: integer + type: object + switchover: + description: |- + Defines the procedure for a controlled transition of leadership from the current leader to a new replica. + This approach aims to minimize downtime and maintain availability in systems with a leader-follower topology, + during events such as planned maintenance or when performing stop, shutdown, restart, or upgrade operations + involving the current leader node. + + + The container executing this action has access to following variables: + + + - KB_SWITCHOVER_CANDIDATE_NAME: The name of the pod for the new leader candidate, which may not be specified (empty). + - KB_SWITCHOVER_CANDIDATE_FQDN: The FQDN of the new leader candidate's pod, which may not be specified (empty). + + + Note: This field is immutable once it has been set. + properties: + exec: + description: |- + Defines the command to run. + + + This field cannot be updated. + properties: + args: + description: Args represents the arguments that are passed + to the `command` for execution. + items: + type: string + type: array + command: + description: |- + Specifies the command to be executed inside the container. + The working directory for this command is the container's root directory('/'). + Commands are executed directly without a shell environment, meaning shell-specific syntax ('|', etc.) is not supported. + If the shell is required, it must be explicitly invoked in the command. + + + A successful execution is indicated by an exit status of 0; any non-zero status signifies a failure. + items: + type: string + type: array + container: + description: |- + Specifies the name of the container within the same pod whose resources will be shared with the action. + This allows the action to utilize the specified container's resources without executing within it. + + + The name must match one of the containers defined in `componentDefinition.spec.runtime`. + + + The resources that can be shared are included: + + + - volume mounts + + + This field cannot be updated. + type: string + env: + description: |- + Represents a list of environment variables that will be injected into the container. + These variables enable the container to adapt its behavior based on the environment it's running in. + + + This field cannot be updated. + items: + description: EnvVar represents an environment variable + present in a Container. + properties: + name: + description: Name of the environment variable. Must + be a C_IDENTIFIER. + type: string + value: + description: |- + Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in the container and + any service environment variables. If a variable cannot be resolved, + the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless of whether the variable + exists or not. + Defaults to "". + type: string + valueFrom: + description: Source for the environment variable's + value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select + in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required for + volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format + of the exposed resources, defaults to + "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in the + pod's namespace + properties: + key: + description: The key of the secret to select + from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + image: + description: |- + Specifies the container image to be used for running the Action. + + + When specified, a dedicated container will be created using this image to execute the Action. + All actions with same image will share the same container. + + + This field cannot be updated. + type: string + matchingKey: + description: |- + Used in conjunction with the `targetPodSelector` field to refine the selection of target pod(s) for Action execution. + The impact of this field depends on the `targetPodSelector` value: + + + - When `targetPodSelector` is set to `Any` or `All`, this field will be ignored. + - When `targetPodSelector` is set to `Role`, only those replicas whose role matches the `matchingKey` + will be selected for the Action. + + + This field cannot be updated. + type: string + targetPodSelector: + description: |- + Defines the criteria used to select the target Pod(s) for executing the Action. + This is useful when there is no default target replica identified. + It allows for precise control over which Pod(s) the Action should run in. + + + If not specified, the Action will be executed in the pod where the Action is triggered, such as the pod + to be removed or added; or a random pod if the Action is triggered at the component level, such as + post-provision or pre-terminate of the component. + + + This field cannot be updated. + enum: + - Any + - All + - Role + - Ordinal + type: string + type: object + preCondition: + description: |- + Specifies the state that the cluster must reach before the Action is executed. + Currently, this is only applicable to the `postProvision` action. + + + The conditions are as follows: + + + - `Immediately`: Executed right after the Component object is created. + The readiness of the Component and its resources is not guaranteed at this stage. + - `RuntimeReady`: The Action is triggered after the Component object has been created and all associated + runtime resources (e.g. Pods) are in a ready state. + - `ComponentReady`: The Action is triggered after the Component itself is in a ready state. + This process does not affect the readiness state of the Component or the Cluster. + - `ClusterReady`: The Action is executed after the Cluster is in a ready state. + This execution does not alter the Component or the Cluster's state of readiness. + + + This field cannot be updated. + type: string + retryPolicy: + description: |- + Defines the strategy to be taken when retrying the Action after a failure. + + + It specifies the conditions under which the Action should be retried and the limits to apply, + such as the maximum number of retries and backoff strategy. + + + This field cannot be updated. + properties: + maxRetries: + default: 0 + description: |- + Defines the maximum number of retry attempts that should be made for a given Action. + This value is set to 0 by default, indicating that no retries will be made. + type: integer + retryInterval: + default: 0 + description: |- + Indicates the duration of time to wait between each retry attempt. + This value is set to 0 by default, indicating that there will be no delay between retry attempts. + format: int64 + type: integer + type: object + timeoutSeconds: + default: 0 + description: |- + Specifies the maximum duration in seconds that the Action is allowed to run. + + + If the Action does not complete within this time frame, it will be terminated. + + + This field cannot be updated. + format: int32 + type: integer + type: object + type: object + logConfigs: + description: |- + Defines the types of logs generated by instances of the Component and their corresponding file paths. + These logs can be collected for further analysis and monitoring. + + + The `logConfigs` field is an optional list of LogConfig objects, where each object represents + a specific log type and its configuration. + It allows you to specify multiple log types and their respective file paths for the Component. + + + Examples: + + + ```yaml + logConfigs: + - filePathPattern: /data/mysql/log/mysqld-error.log + name: error + - filePathPattern: /data/mysql/log/mysqld.log + name: general + - filePathPattern: /data/mysql/log/mysqld-slowquery.log + name: slow + ``` + + + This field is immutable. + items: + properties: + filePathPattern: + description: |- + Specifies the paths or patterns identifying where the log files are stored. + This field allows the system to locate and manage log files effectively. + + + Examples: + + + - /home/postgres/pgdata/pgroot/data/log/postgresql-* + - /data/mysql/log/mysqld-error.log + maxLength: 4096 + type: string + name: + description: |- + Specifies a descriptive label for the log type, such as 'slow' for a MySQL slow log file. + It provides a clear identification of the log's purpose and content. + maxLength: 128 + type: string + required: + - filePathPattern + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + minReadySeconds: + default: 0 + description: |- + `minReadySeconds` is the minimum duration in seconds that a new Pod should remain in the ready + state without any of its containers crashing to be considered available. + This ensures the Pod's stability and readiness to serve requests. + + + A default value of 0 seconds means the Pod is considered available as soon as it enters the ready state. + format: int32 + minimum: 0 + type: integer + podManagementPolicy: + description: |- + InstanceSet controls the creation of pods during initial scale up, replacement of pods on nodes, and scaling down. + + + - `OrderedReady`: Creates pods in increasing order (pod-0, then pod-1, etc). The controller waits until each pod + is ready before continuing. Pods are removed in reverse order when scaling down. + - `Parallel`: Creates pods in parallel to match the desired scale without waiting. All pods are deleted at once + when scaling down. + type: string + policyRules: + description: |- + Defines the namespaced policy rules required by the Component. + + + The `policyRules` field is an array of `rbacv1.PolicyRule` objects that define the policy rules + needed by the Component to operate within a namespace. + These policy rules determine the permissions and verbs the Component is allowed to perform on + Kubernetes resources within the namespace. + + + The purpose of this field is to automatically generate the necessary RBAC roles + for the Component based on the specified policy rules. + This ensures that the Pods in the Component has appropriate permissions to function. + + + Note: This field is currently non-functional and is reserved for future implementation. + + + This field is immutable. + items: + description: |- + PolicyRule holds information that describes a policy rule, but does not contain information + about who the rule applies to or which namespace the rule applies to. + properties: + apiGroups: + description: |- + APIGroups is the name of the APIGroup that contains the resources. If multiple API groups are specified, any action requested against one of + the enumerated resources in any API group will be allowed. "" represents the core API group and "*" represents all API groups. + items: + type: string + type: array + nonResourceURLs: + description: |- + NonResourceURLs is a set of partial urls that a user should have access to. *s are allowed, but only as the full, final step in the path + Since non-resource URLs are not namespaced, this field is only applicable for ClusterRoles referenced from a ClusterRoleBinding. + Rules can either apply to API resources (such as "pods" or "secrets") or non-resource URL paths (such as "/api"), but not both. + items: + type: string + type: array + resourceNames: + description: ResourceNames is an optional white list of names + that the rule applies to. An empty set means that everything + is allowed. + items: + type: string + type: array + resources: + description: Resources is a list of resources this rule applies + to. '*' represents all resources. + items: + type: string + type: array + verbs: + description: Verbs is a list of Verbs that apply to ALL the + ResourceKinds contained in this rule. '*' represents all verbs. + items: + type: string + type: array + required: + - verbs + type: object + type: array + provider: + description: |- + Specifies the name of the Component provider, typically the vendor or developer name. + It identifies the entity responsible for creating and maintaining the Component. + + + When specifying the provider name, consider the following guidelines: + + + - Keep the name concise and relevant to the Component. + - Use a consistent naming convention across Components from the same provider. + - Avoid using trademarked or copyrighted names without proper permission. + maxLength: 32 + type: string + replicasLimit: + description: |- + Defines the upper limit of the number of replicas supported by the Component. + + + It defines the maximum number of replicas that can be created for the Component. + This field allows you to set a limit on the scalability of the Component, preventing it from exceeding a certain number of replicas. + + + This field is immutable. + properties: + maxReplicas: + description: The maximum limit of replicas. + format: int32 + type: integer + minReplicas: + description: The minimum limit of replicas. + format: int32 + type: integer + required: + - maxReplicas + - minReplicas + type: object + x-kubernetes-validations: + - message: the minimum and maximum limit of replicas should be in + the range of [0, 16384] + rule: self.minReplicas >= 0 && self.maxReplicas <= 16384 + - message: the minimum replicas limit should be no greater than the + maximum + rule: self.minReplicas <= self.maxReplicas + roles: + description: |- + Enumerate all possible roles assigned to each replica of the Component, influencing its behavior. + + + A replica can have zero to multiple roles. + KubeBlocks operator determines the roles of each replica by invoking the `lifecycleActions.roleProbe` method. + This action returns a list of roles for each replica, and the returned roles must be predefined in the `roles` field. + + + The roles assigned to a replica can influence various aspects of the Component's behavior, such as: + + + - Service selection: The Component's exposed Services may target replicas based on their roles using `roleSelector`. + - Update order: The roles can determine the order in which replicas are updated during a Component update. + For instance, replicas with a "follower" role can be updated first, while the replica with the "leader" + role is updated last. This helps minimize the number of leader changes during the update process. + + + This field is immutable. + items: + description: ReplicaRole represents a role that can be assumed by + a component instance. + properties: + name: + description: |- + Defines the role's identifier. It is used to set the "apps.kubeblocks.io/role" label value + on the corresponding object. + + + This field is immutable once set. + maxLength: 32 + pattern: ^.*[^\s]+.*$ + type: string + serviceable: + default: false + description: |- + Indicates whether a replica assigned this role is capable of providing services. + + + This field is immutable once set. + type: boolean + votable: + default: false + description: |- + Specifies whether a replica with this role has voting rights. + In distributed systems, this typically means the replica can participate in consensus decisions, + configuration changes, or other processes that require a quorum. + + + This field is immutable once set. + type: boolean + writable: + default: false + description: |- + Determines if a replica in this role has the authority to perform write operations. + A writable replica can modify data, handle update operations. + + + This field is immutable once set. + type: boolean + required: + - name + type: object + type: array + runtime: + description: |- + Specifies the PodSpec template used in the Component. + It includes the following elements: + + + - Init containers + - Containers + - Image + - Commands + - Args + - Envs + - Mounts + - Ports + - Security context + - Probes + - Lifecycle + - Volumes + + + This field is intended to define static settings that remain consistent across all instantiated Components. + Dynamic settings such as CPU and memory resource limits, as well as scheduling settings (affinity, + toleration, priority), may vary among different instantiated Components. + They should be specified in the `cluster.spec.componentSpecs` (ClusterComponentSpec). + + + Specific instances of a Component may override settings defined here, such as using a different container image + or modifying environment variable values. + These instance-specific overrides can be specified in `cluster.spec.componentSpecs[*].instances`. + + + This field is immutable and cannot be updated once set. + properties: + activeDeadlineSeconds: + description: |- + Optional duration in seconds the pod may be active on the node relative to + StartTime before the system will actively try to mark it failed and kill associated containers. + Value must be a positive integer. + format: int64 + type: integer + affinity: + description: If specified, the pod's scheduling constraints + properties: + nodeAffinity: + description: Describes node affinity scheduling rules for + the pod. + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node matches the corresponding matchExpressions; the + node(s) with the highest sum are the most preferred. + items: + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). + properties: + preference: + description: A node selector term, associated with + the corresponding weight. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + weight: + description: Weight associated with matching the + corresponding nodeSelectorTerm, in the range 1-100. + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. + properties: + nodeSelectorTerms: + description: Required. A list of node selector terms. + The terms are ORed. + items: + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + type: array + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + description: Describes pod affinity scheduling rules (e.g. + co-locate this pod in the same node, zone, etc. as some + other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred + node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated + with the corresponding weight. + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. + Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: |- + weight associated with matching the corresponding podAffinityTerm, + in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. + items: + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. + Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + description: Describes pod anti-affinity scheduling rules + (e.g. avoid putting this pod in the same node, zone, etc. + as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the anti-affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred + node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated + with the corresponding weight. + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. + Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: |- + weight associated with matching the corresponding podAffinityTerm, + in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the anti-affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the anti-affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. + items: + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. + Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + automountServiceAccountToken: + description: AutomountServiceAccountToken indicates whether a + service account token should be automatically mounted. + type: boolean + containers: + description: |- + List of containers belonging to the pod. + Containers cannot currently be added or removed. + There must be at least one container in a Pod. + Cannot be updated. + items: + description: A single application container that you want to + run within a pod. + properties: + args: + description: |- + Arguments to the entrypoint. + The container image's CMD is used if this is not provided. + Variable references $(VAR_NAME) are expanded using the container's environment. If a variable + cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will + produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless + of whether the variable exists or not. Cannot be updated. + More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell + items: + type: string + type: array + command: + description: |- + Entrypoint array. Not executed within a shell. + The container image's ENTRYPOINT is used if this is not provided. + Variable references $(VAR_NAME) are expanded using the container's environment. If a variable + cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will + produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless + of whether the variable exists or not. Cannot be updated. + More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell + items: + type: string + type: array + env: + description: |- + List of environment variables to set in the container. + Cannot be updated. + items: + description: EnvVar represents an environment variable + present in a Container. + properties: + name: + description: Name of the environment variable. Must + be a C_IDENTIFIER. + type: string + value: + description: |- + Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in the container and + any service environment variables. If a variable cannot be resolved, + the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless of whether the variable + exists or not. + Defaults to "". + type: string + valueFrom: + description: Source for the environment variable's + value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in + the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required for + volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of + the exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in the + pod's namespace + properties: + key: + description: The key of the secret to select + from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or + its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + envFrom: + description: |- + List of sources to populate environment variables in the container. + The keys defined within a source must be a C_IDENTIFIER. All invalid keys + will be reported as an event when the container is starting. When a key exists in multiple + sources, the value associated with the last source will take precedence. + Values defined by an Env with a duplicate key will take precedence. + Cannot be updated. + items: + description: EnvFromSource represents the source of a + set of ConfigMaps + properties: + configMapRef: + description: The ConfigMap to select from + 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 + optional: + description: Specify whether the ConfigMap must + be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + description: An optional identifier to prepend to + each key in the ConfigMap. Must be a C_IDENTIFIER. + type: string + secretRef: + description: The Secret to select from + 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 + optional: + description: Specify whether the Secret must be + defined + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + image: + description: |- + Container image name. + More info: https://kubernetes.io/docs/concepts/containers/images + This field is optional to allow higher level config management to default or override + container images in workload controllers like Deployments and StatefulSets. + type: string + imagePullPolicy: + description: |- + Image pull policy. + One of Always, Never, IfNotPresent. + Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/containers/images#updating-images + type: string + lifecycle: + description: |- + Actions that the management system should take in response to container lifecycle events. + Cannot be updated. + properties: + postStart: + description: |- + PostStart is called immediately after a container is created. If the handler fails, + the container is terminated and restarted according to its restart policy. + Other management of the container blocks until the hook completes. + More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + sleep: + description: Sleep represents the duration that + the container should sleep before being terminated. + properties: + seconds: + description: Seconds is the number of seconds + to sleep. + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + description: |- + Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept + for the backward compatibility. There are no validation of this field and + lifecycle hooks will fail in runtime when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + description: |- + PreStop is called immediately before a container is terminated due to an + API request or management event such as liveness/startup probe failure, + preemption, resource contention, etc. The handler is not called if the + container crashes or exits. The Pod's termination grace period countdown begins before the + PreStop hook is executed. Regardless of the outcome of the handler, the + container will eventually terminate within the Pod's termination grace + period (unless delayed by finalizers). Other management of the container blocks until the hook completes + or until the termination grace period is reached. + More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + sleep: + description: Sleep represents the duration that + the container should sleep before being terminated. + properties: + seconds: + description: Seconds is the number of seconds + to sleep. + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + description: |- + Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept + for the backward compatibility. There are no validation of this field and + lifecycle hooks will fail in runtime when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + description: |- + Periodic probe of container liveness. + Container will be restarted if the probe fails. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC + port. + properties: + port: + description: Port number of the gRPC service. Number + must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, + defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + name: + description: |- + Name of the container specified as a DNS_LABEL. + Each container in a pod must have a unique name (DNS_LABEL). + Cannot be updated. + type: string + ports: + description: |- + List of ports to expose from the container. Not specifying a port here + DOES NOT prevent that port from being exposed. Any port which is + listening on the default "0.0.0.0" address inside a container will be + accessible from the network. + Modifying this array with strategic merge patch may corrupt the data. + For more information See https://github.com/kubernetes/kubernetes/issues/108255. + Cannot be updated. + items: + description: ContainerPort represents a network port in + a single container. + properties: + containerPort: + description: |- + Number of port to expose on the pod's IP address. + This must be a valid port number, 0 < x < 65536. + format: int32 + type: integer + hostIP: + description: What host IP to bind the external port + to. + type: string + hostPort: + description: |- + Number of port to expose on the host. + If specified, this must be a valid port number, 0 < x < 65536. + If HostNetwork is specified, this must match ContainerPort. + Most containers do not need this. + format: int32 + type: integer + name: + description: |- + If specified, this must be an IANA_SVC_NAME and unique within the pod. Each + named port in a pod must have a unique name. Name for the port that can be + referred to by services. + type: string + protocol: + default: TCP + description: |- + Protocol for port. Must be UDP, TCP, or SCTP. + Defaults to "TCP". + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + description: |- + Periodic probe of container service readiness. + Container will be removed from service endpoints if the probe fails. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC + port. + properties: + port: + description: Port number of the gRPC service. Number + must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, + defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + resizePolicy: + description: Resources resize policy for the container. + items: + description: ContainerResizePolicy represents resource + resize policy for the container. + properties: + resourceName: + description: |- + Name of the resource to which this resource resize policy applies. + Supported values: cpu, memory. + type: string + restartPolicy: + description: |- + Restart policy to apply when specified resource is resized. + If not specified, it defaults to NotRequired. + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + description: |- + Compute Resources required by this container. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + properties: + claims: + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + + + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + + + This field is immutable. It can only be set for containers. + items: + description: ResourceClaim references one entry in + PodSpec.ResourceClaims. + properties: + name: + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + restartPolicy: + description: |- + RestartPolicy defines the restart behavior of individual containers in a pod. + This field may only be set for init containers, and the only allowed value is "Always". + For non-init containers or when this field is not specified, + the restart behavior is defined by the Pod's restart policy and the container type. + Setting the RestartPolicy as "Always" for the init container will have the following effect: + this init container will be continually restarted on + exit until all regular containers have terminated. Once all regular + containers have completed, all init containers with restartPolicy "Always" + will be shut down. This lifecycle differs from normal init containers and + is often referred to as a "sidecar" container. Although this init + container still starts in the init container sequence, it does not wait + for the container to complete before proceeding to the next init + container. Instead, the next init container starts immediately after this + init container is started, or after any startupProbe has successfully + completed. + type: string + securityContext: + description: |- + SecurityContext defines the security options the container should be run with. + If set, the fields of SecurityContext override the equivalent fields of PodSecurityContext. + More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ + properties: + allowPrivilegeEscalation: + description: |- + AllowPrivilegeEscalation controls whether a process can gain more + privileges than its parent process. This bool directly controls if + the no_new_privs flag will be set on the container process. + AllowPrivilegeEscalation is true always when the container is: + 1) run as Privileged + 2) has CAP_SYS_ADMIN + Note that this field cannot be set when spec.os.name is windows. + type: boolean + capabilities: + description: |- + The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the container runtime. + Note that this field cannot be set when spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + type: object + privileged: + description: |- + Run container in privileged mode. + Processes in privileged containers are essentially equivalent to root on the host. + Defaults to false. + Note that this field cannot be set when spec.os.name is windows. + type: boolean + procMount: + description: |- + procMount denotes the type of proc mount to use for the containers. + The default is DefaultProcMount which uses the container runtime defaults for + readonly paths and masked paths. + This requires the ProcMountType feature flag to be enabled. + Note that this field cannot be set when spec.os.name is windows. + type: string + readOnlyRootFilesystem: + description: |- + Whether this container has a read-only root filesystem. + Default is false. + Note that this field cannot be set when spec.os.name is windows. + type: boolean + runAsGroup: + description: |- + The GID to run the entrypoint of the container process. + Uses runtime default if unset. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: |- + Indicates that the container must run as a non-root user. + If true, the Kubelet will validate the image at runtime to ensure that it + does not run as UID 0 (root) and fail to start the container if it does. + If unset or false, no such validation will be performed. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: |- + The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: |- + The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random SELinux context for each + container. May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies + to the container. + type: string + role: + description: Role is a SELinux role label that applies + to the container. + type: string + type: + description: Type is a SELinux type label that applies + to the container. + type: string + user: + description: User is a SELinux user label that applies + to the container. + type: string + type: object + seccompProfile: + description: |- + The seccomp options to use by this container. If seccomp options are + provided at both the pod & container level, the container options + override the pod options. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile defined in a file on the node should be used. + The profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be set for any other type. + type: string + type: + description: |- + type indicates which kind of seccomp profile will be applied. + Valid options are: + + + Localhost - a profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile should be used. + Unconfined - no profile should be applied. + type: string + required: + - type + type: object + windowsOptions: + description: |- + The Windows specific settings applied to all containers. + If unspecified, the options from the PodSecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: |- + GMSACredentialSpec is where the GMSA admission webhook + (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the + GMSA credential spec named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name + of the GMSA credential spec to use. + type: string + hostProcess: + description: |- + HostProcess determines if a container should be run as a 'Host Process' container. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: |- + The UserName in Windows to run the entrypoint of the container process. + Defaults to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: string + type: object + type: object + startupProbe: + description: |- + StartupProbe indicates that the Pod has successfully initialized. + If specified, no other probes are executed until this completes successfully. + If this probe fails, the Pod will be restarted, just as if the livenessProbe failed. + This can be used to provide different probe parameters at the beginning of a Pod's lifecycle, + when it might take a long time to load data or warm a cache, than during steady-state operation. + This cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC + port. + properties: + port: + description: Port number of the gRPC service. Number + must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, + defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + stdin: + description: |- + Whether this container should allocate a buffer for stdin in the container runtime. If this + is not set, reads from stdin in the container will always result in EOF. + Default is false. + type: boolean + stdinOnce: + description: |- + Whether the container runtime should close the stdin channel after it has been opened by + a single attach. When stdin is true the stdin stream will remain open across multiple attach + sessions. If stdinOnce is set to true, stdin is opened on container start, is empty until the + first client attaches to stdin, and then remains open and accepts data until the client disconnects, + at which time stdin is closed and remains closed until the container is restarted. If this + flag is false, a container processes that reads from stdin will never receive an EOF. + Default is false + type: boolean + terminationMessagePath: + description: |- + Optional: Path at which the file to which the container's termination message + will be written is mounted into the container's filesystem. + Message written is intended to be brief final status, such as an assertion failure message. + Will be truncated by the node if greater than 4096 bytes. The total message length across + all containers will be limited to 12kb. + Defaults to /dev/termination-log. + Cannot be updated. + type: string + terminationMessagePolicy: + description: |- + Indicate how the termination message should be populated. File will use the contents of + terminationMessagePath to populate the container status message on both success and failure. + FallbackToLogsOnError will use the last chunk of container log output if the termination + message file is empty and the container exited with an error. + The log output is limited to 2048 bytes or 80 lines, whichever is smaller. + Defaults to File. + Cannot be updated. + type: string + tty: + description: |- + Whether this container should allocate a TTY for itself, also requires 'stdin' to be true. + Default is false. + type: boolean + volumeDevices: + description: volumeDevices is the list of block devices + to be used by the container. + items: + description: volumeDevice describes a mapping of a raw + block device within a container. + properties: + devicePath: + description: devicePath is the path inside of the + container that the device will be mapped to. + type: string + name: + description: name must match the name of a persistentVolumeClaim + in the pod + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + description: |- + Pod volumes to mount into the container's filesystem. + Cannot be updated. + items: + description: VolumeMount describes a mounting of a Volume + within a container. + properties: + mountPath: + description: |- + Path within the container at which the volume should be mounted. Must + not contain ':'. + type: string + mountPropagation: + description: |- + mountPropagation determines how mounts are propagated from the host + to container and the other way around. + When not set, MountPropagationNone is used. + This field is beta in 1.10. + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: |- + Mounted read-only if true, read-write otherwise (false or unspecified). + Defaults to false. + type: boolean + subPath: + description: |- + Path within the volume from which the container's volume should be mounted. + Defaults to "" (volume's root). + type: string + subPathExpr: + description: |- + Expanded path within the volume from which the container's volume should be mounted. + Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment. + Defaults to "" (volume's root). + SubPathExpr and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + description: |- + Container's working directory. + If not specified, the container runtime's default will be used, which + might be configured in the container image. + Cannot be updated. + type: string + required: + - name + type: object + type: array + dnsConfig: + description: |- + Specifies the DNS parameters of a pod. + Parameters specified here will be merged to the generated DNS + configuration based on DNSPolicy. + properties: + nameservers: + description: |- + A list of DNS name server IP addresses. + This will be appended to the base nameservers generated from DNSPolicy. + Duplicated nameservers will be removed. + items: + type: string + type: array + options: + description: |- + A list of DNS resolver options. + This will be merged with the base options generated from DNSPolicy. + Duplicated entries will be removed. Resolution options given in Options + will override those that appear in the base DNSPolicy. + items: + description: PodDNSConfigOption defines DNS resolver options + of a pod. + properties: + name: + description: Required. + type: string + value: + type: string + type: object + type: array + searches: + description: |- + A list of DNS search domains for host-name lookup. + This will be appended to the base search paths generated from DNSPolicy. + Duplicated search paths will be removed. + items: + type: string + type: array + type: object + dnsPolicy: + description: |- + Set DNS policy for the pod. + Defaults to "ClusterFirst". + Valid values are 'ClusterFirstWithHostNet', 'ClusterFirst', 'Default' or 'None'. + DNS parameters given in DNSConfig will be merged with the policy selected with DNSPolicy. + To have DNS options set along with hostNetwork, you have to specify DNS policy + explicitly to 'ClusterFirstWithHostNet'. + type: string + enableServiceLinks: + description: |- + EnableServiceLinks indicates whether information about services should be injected into pod's + environment variables, matching the syntax of Docker links. + Optional: Defaults to true. + type: boolean + ephemeralContainers: + description: |- + List of ephemeral containers run in this pod. Ephemeral containers may be run in an existing + pod to perform user-initiated actions such as debugging. This list cannot be specified when + creating a pod, and it cannot be modified by updating the pod spec. In order to add an + ephemeral container to an existing pod, use the pod's ephemeralcontainers subresource. + items: + description: |- + An EphemeralContainer is a temporary container that you may add to an existing Pod for + user-initiated activities such as debugging. Ephemeral containers have no resource or + scheduling guarantees, and they will not be restarted when they exit or when a Pod is + removed or restarted. The kubelet may evict a Pod if an ephemeral container causes the + Pod to exceed its resource allocation. + + + To add an ephemeral container, use the ephemeralcontainers subresource of an existing + Pod. Ephemeral containers may not be removed or restarted. + properties: + args: + description: |- + Arguments to the entrypoint. + The image's CMD is used if this is not provided. + Variable references $(VAR_NAME) are expanded using the container's environment. If a variable + cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will + produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless + of whether the variable exists or not. Cannot be updated. + More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell + items: + type: string + type: array + command: + description: |- + Entrypoint array. Not executed within a shell. + The image's ENTRYPOINT is used if this is not provided. + Variable references $(VAR_NAME) are expanded using the container's environment. If a variable + cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will + produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless + of whether the variable exists or not. Cannot be updated. + More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell + items: + type: string + type: array + env: + description: |- + List of environment variables to set in the container. + Cannot be updated. + items: + description: EnvVar represents an environment variable + present in a Container. + properties: + name: + description: Name of the environment variable. Must + be a C_IDENTIFIER. + type: string + value: + description: |- + Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in the container and + any service environment variables. If a variable cannot be resolved, + the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless of whether the variable + exists or not. + Defaults to "". + type: string + valueFrom: + description: Source for the environment variable's + value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in + the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required for + volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of + the exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in the + pod's namespace + properties: + key: + description: The key of the secret to select + from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or + its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + envFrom: + description: |- + List of sources to populate environment variables in the container. + The keys defined within a source must be a C_IDENTIFIER. All invalid keys + will be reported as an event when the container is starting. When a key exists in multiple + sources, the value associated with the last source will take precedence. + Values defined by an Env with a duplicate key will take precedence. + Cannot be updated. + items: + description: EnvFromSource represents the source of a + set of ConfigMaps + properties: + configMapRef: + description: The ConfigMap to select from + 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 + optional: + description: Specify whether the ConfigMap must + be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + description: An optional identifier to prepend to + each key in the ConfigMap. Must be a C_IDENTIFIER. + type: string + secretRef: + description: The Secret to select from + 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 + optional: + description: Specify whether the Secret must be + defined + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + image: + description: |- + Container image name. + More info: https://kubernetes.io/docs/concepts/containers/images + type: string + imagePullPolicy: + description: |- + Image pull policy. + One of Always, Never, IfNotPresent. + Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/containers/images#updating-images + type: string + lifecycle: + description: Lifecycle is not allowed for ephemeral containers. + properties: + postStart: + description: |- + PostStart is called immediately after a container is created. If the handler fails, + the container is terminated and restarted according to its restart policy. + Other management of the container blocks until the hook completes. + More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + sleep: + description: Sleep represents the duration that + the container should sleep before being terminated. + properties: + seconds: + description: Seconds is the number of seconds + to sleep. + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + description: |- + Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept + for the backward compatibility. There are no validation of this field and + lifecycle hooks will fail in runtime when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + description: |- + PreStop is called immediately before a container is terminated due to an + API request or management event such as liveness/startup probe failure, + preemption, resource contention, etc. The handler is not called if the + container crashes or exits. The Pod's termination grace period countdown begins before the + PreStop hook is executed. Regardless of the outcome of the handler, the + container will eventually terminate within the Pod's termination grace + period (unless delayed by finalizers). Other management of the container blocks until the hook completes + or until the termination grace period is reached. + More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + sleep: + description: Sleep represents the duration that + the container should sleep before being terminated. + properties: + seconds: + description: Seconds is the number of seconds + to sleep. + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + description: |- + Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept + for the backward compatibility. There are no validation of this field and + lifecycle hooks will fail in runtime when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + description: Probes are not allowed for ephemeral containers. + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC + port. + properties: + port: + description: Port number of the gRPC service. Number + must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, + defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + name: + description: |- + Name of the ephemeral container specified as a DNS_LABEL. + This name must be unique among all containers, init containers and ephemeral containers. + type: string + ports: + description: Ports are not allowed for ephemeral containers. + items: + description: ContainerPort represents a network port in + a single container. + properties: + containerPort: + description: |- + Number of port to expose on the pod's IP address. + This must be a valid port number, 0 < x < 65536. + format: int32 + type: integer + hostIP: + description: What host IP to bind the external port + to. + type: string + hostPort: + description: |- + Number of port to expose on the host. + If specified, this must be a valid port number, 0 < x < 65536. + If HostNetwork is specified, this must match ContainerPort. + Most containers do not need this. + format: int32 + type: integer + name: + description: |- + If specified, this must be an IANA_SVC_NAME and unique within the pod. Each + named port in a pod must have a unique name. Name for the port that can be + referred to by services. + type: string + protocol: + default: TCP + description: |- + Protocol for port. Must be UDP, TCP, or SCTP. + Defaults to "TCP". + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + description: Probes are not allowed for ephemeral containers. + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC + port. + properties: + port: + description: Port number of the gRPC service. Number + must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, + defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + resizePolicy: + description: Resources resize policy for the container. + items: + description: ContainerResizePolicy represents resource + resize policy for the container. + properties: + resourceName: + description: |- + Name of the resource to which this resource resize policy applies. + Supported values: cpu, memory. + type: string + restartPolicy: + description: |- + Restart policy to apply when specified resource is resized. + If not specified, it defaults to NotRequired. + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + description: |- + Resources are not allowed for ephemeral containers. Ephemeral containers use spare resources + already allocated to the pod. + properties: + claims: + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + + + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + + + This field is immutable. It can only be set for containers. + items: + description: ResourceClaim references one entry in + PodSpec.ResourceClaims. + properties: + name: + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + restartPolicy: + description: |- + Restart policy for the container to manage the restart behavior of each + container within a pod. + This may only be set for init containers. You cannot set this field on + ephemeral containers. + type: string + securityContext: + description: |- + Optional: SecurityContext defines the security options the ephemeral container should be run with. + If set, the fields of SecurityContext override the equivalent fields of PodSecurityContext. + properties: + allowPrivilegeEscalation: + description: |- + AllowPrivilegeEscalation controls whether a process can gain more + privileges than its parent process. This bool directly controls if + the no_new_privs flag will be set on the container process. + AllowPrivilegeEscalation is true always when the container is: + 1) run as Privileged + 2) has CAP_SYS_ADMIN + Note that this field cannot be set when spec.os.name is windows. + type: boolean + capabilities: + description: |- + The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the container runtime. + Note that this field cannot be set when spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + type: object + privileged: + description: |- + Run container in privileged mode. + Processes in privileged containers are essentially equivalent to root on the host. + Defaults to false. + Note that this field cannot be set when spec.os.name is windows. + type: boolean + procMount: + description: |- + procMount denotes the type of proc mount to use for the containers. + The default is DefaultProcMount which uses the container runtime defaults for + readonly paths and masked paths. + This requires the ProcMountType feature flag to be enabled. + Note that this field cannot be set when spec.os.name is windows. + type: string + readOnlyRootFilesystem: + description: |- + Whether this container has a read-only root filesystem. + Default is false. + Note that this field cannot be set when spec.os.name is windows. + type: boolean + runAsGroup: + description: |- + The GID to run the entrypoint of the container process. + Uses runtime default if unset. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: |- + Indicates that the container must run as a non-root user. + If true, the Kubelet will validate the image at runtime to ensure that it + does not run as UID 0 (root) and fail to start the container if it does. + If unset or false, no such validation will be performed. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: |- + The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: |- + The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random SELinux context for each + container. May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies + to the container. + type: string + role: + description: Role is a SELinux role label that applies + to the container. + type: string + type: + description: Type is a SELinux type label that applies + to the container. + type: string + user: + description: User is a SELinux user label that applies + to the container. + type: string + type: object + seccompProfile: + description: |- + The seccomp options to use by this container. If seccomp options are + provided at both the pod & container level, the container options + override the pod options. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile defined in a file on the node should be used. + The profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be set for any other type. + type: string + type: + description: |- + type indicates which kind of seccomp profile will be applied. + Valid options are: + + + Localhost - a profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile should be used. + Unconfined - no profile should be applied. + type: string + required: + - type + type: object + windowsOptions: + description: |- + The Windows specific settings applied to all containers. + If unspecified, the options from the PodSecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: |- + GMSACredentialSpec is where the GMSA admission webhook + (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the + GMSA credential spec named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name + of the GMSA credential spec to use. + type: string + hostProcess: + description: |- + HostProcess determines if a container should be run as a 'Host Process' container. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: |- + The UserName in Windows to run the entrypoint of the container process. + Defaults to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: string + type: object + type: object + startupProbe: + description: Probes are not allowed for ephemeral containers. + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC + port. + properties: + port: + description: Port number of the gRPC service. Number + must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, + defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + stdin: + description: |- + Whether this container should allocate a buffer for stdin in the container runtime. If this + is not set, reads from stdin in the container will always result in EOF. + Default is false. + type: boolean + stdinOnce: + description: |- + Whether the container runtime should close the stdin channel after it has been opened by + a single attach. When stdin is true the stdin stream will remain open across multiple attach + sessions. If stdinOnce is set to true, stdin is opened on container start, is empty until the + first client attaches to stdin, and then remains open and accepts data until the client disconnects, + at which time stdin is closed and remains closed until the container is restarted. If this + flag is false, a container processes that reads from stdin will never receive an EOF. + Default is false + type: boolean + targetContainerName: + description: |- + If set, the name of the container from PodSpec that this ephemeral container targets. + The ephemeral container will be run in the namespaces (IPC, PID, etc) of this container. + If not set then the ephemeral container uses the namespaces configured in the Pod spec. + + + The container runtime must implement support for this feature. If the runtime does not + support namespace targeting then the result of setting this field is undefined. + type: string + terminationMessagePath: + description: |- + Optional: Path at which the file to which the container's termination message + will be written is mounted into the container's filesystem. + Message written is intended to be brief final status, such as an assertion failure message. + Will be truncated by the node if greater than 4096 bytes. The total message length across + all containers will be limited to 12kb. + Defaults to /dev/termination-log. + Cannot be updated. + type: string + terminationMessagePolicy: + description: |- + Indicate how the termination message should be populated. File will use the contents of + terminationMessagePath to populate the container status message on both success and failure. + FallbackToLogsOnError will use the last chunk of container log output if the termination + message file is empty and the container exited with an error. + The log output is limited to 2048 bytes or 80 lines, whichever is smaller. + Defaults to File. + Cannot be updated. + type: string + tty: + description: |- + Whether this container should allocate a TTY for itself, also requires 'stdin' to be true. + Default is false. + type: boolean + volumeDevices: + description: volumeDevices is the list of block devices + to be used by the container. + items: + description: volumeDevice describes a mapping of a raw + block device within a container. + properties: + devicePath: + description: devicePath is the path inside of the + container that the device will be mapped to. + type: string + name: + description: name must match the name of a persistentVolumeClaim + in the pod + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + description: |- + Pod volumes to mount into the container's filesystem. Subpath mounts are not allowed for ephemeral containers. + Cannot be updated. + items: + description: VolumeMount describes a mounting of a Volume + within a container. + properties: + mountPath: + description: |- + Path within the container at which the volume should be mounted. Must + not contain ':'. + type: string + mountPropagation: + description: |- + mountPropagation determines how mounts are propagated from the host + to container and the other way around. + When not set, MountPropagationNone is used. + This field is beta in 1.10. + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: |- + Mounted read-only if true, read-write otherwise (false or unspecified). + Defaults to false. + type: boolean + subPath: + description: |- + Path within the volume from which the container's volume should be mounted. + Defaults to "" (volume's root). + type: string + subPathExpr: + description: |- + Expanded path within the volume from which the container's volume should be mounted. + Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment. + Defaults to "" (volume's root). + SubPathExpr and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + description: |- + Container's working directory. + If not specified, the container runtime's default will be used, which + might be configured in the container image. + Cannot be updated. + type: string + required: + - name + type: object + type: array + hostAliases: + description: |- + HostAliases is an optional list of hosts and IPs that will be injected into the pod's hosts + file if specified. This is only valid for non-hostNetwork pods. + items: + description: |- + HostAlias holds the mapping between IP and hostnames that will be injected as an entry in the + pod's hosts file. + properties: + hostnames: + description: Hostnames for the above IP address. + items: + type: string + type: array + ip: + description: IP address of the host file entry. + type: string + type: object + type: array + hostIPC: + description: |- + Use the host's ipc namespace. + Optional: Default to false. + type: boolean + hostNetwork: + description: |- + Host networking requested for this pod. Use the host's network namespace. + If this option is set, the ports that will be used must be specified. + Default to false. + type: boolean + hostPID: + description: |- + Use the host's pid namespace. + Optional: Default to false. + type: boolean + hostUsers: + description: |- + Use the host's user namespace. + Optional: Default to true. + If set to true or not present, the pod will be run in the host user namespace, useful + for when the pod needs a feature only available to the host user namespace, such as + loading a kernel module with CAP_SYS_MODULE. + When set to false, a new userns is created for the pod. Setting false is useful for + mitigating container breakout vulnerabilities even allowing users to run their + containers as root without actually having root privileges on the host. + This field is alpha-level and is only honored by servers that enable the UserNamespacesSupport feature. + type: boolean + hostname: + description: |- + Specifies the hostname of the Pod + If not specified, the pod's hostname will be set to a system-defined value. + type: string + imagePullSecrets: + description: |- + ImagePullSecrets is an optional list of references to secrets in the same namespace to use for pulling any of the images used by this PodSpec. + If specified, these secrets will be passed to individual puller implementations for them to use. + More info: https://kubernetes.io/docs/concepts/containers/images#specifying-imagepullsecrets-on-a-pod + items: + 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? + type: string + type: object + x-kubernetes-map-type: atomic + type: array + initContainers: + description: |- + List of initialization containers belonging to the pod. + Init containers are executed in order prior to containers being started. If any + init container fails, the pod is considered to have failed and is handled according + to its restartPolicy. The name for an init container or normal container must be + unique among all containers. + Init containers may not have Lifecycle actions, Readiness probes, Liveness probes, or Startup probes. + The resourceRequirements of an init container are taken into account during scheduling + by finding the highest request/limit for each resource type, and then using the max of + of that value or the sum of the normal containers. Limits are applied to init containers + in a similar fashion. + Init containers cannot currently be added or removed. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/init-containers/ + items: + description: A single application container that you want to + run within a pod. + properties: + args: + description: |- + Arguments to the entrypoint. + The container image's CMD is used if this is not provided. + Variable references $(VAR_NAME) are expanded using the container's environment. If a variable + cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will + produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless + of whether the variable exists or not. Cannot be updated. + More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell + items: + type: string + type: array + command: + description: |- + Entrypoint array. Not executed within a shell. + The container image's ENTRYPOINT is used if this is not provided. + Variable references $(VAR_NAME) are expanded using the container's environment. If a variable + cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will + produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless + of whether the variable exists or not. Cannot be updated. + More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell + items: + type: string + type: array + env: + description: |- + List of environment variables to set in the container. + Cannot be updated. + items: + description: EnvVar represents an environment variable + present in a Container. + properties: + name: + description: Name of the environment variable. Must + be a C_IDENTIFIER. + type: string + value: + description: |- + Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in the container and + any service environment variables. If a variable cannot be resolved, + the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless of whether the variable + exists or not. + Defaults to "". + type: string + valueFrom: + description: Source for the environment variable's + value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in + the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required for + volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of + the exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in the + pod's namespace + properties: + key: + description: The key of the secret to select + from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or + its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + envFrom: + description: |- + List of sources to populate environment variables in the container. + The keys defined within a source must be a C_IDENTIFIER. All invalid keys + will be reported as an event when the container is starting. When a key exists in multiple + sources, the value associated with the last source will take precedence. + Values defined by an Env with a duplicate key will take precedence. + Cannot be updated. + items: + description: EnvFromSource represents the source of a + set of ConfigMaps + properties: + configMapRef: + description: The ConfigMap to select from + 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 + optional: + description: Specify whether the ConfigMap must + be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + description: An optional identifier to prepend to + each key in the ConfigMap. Must be a C_IDENTIFIER. + type: string + secretRef: + description: The Secret to select from + 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 + optional: + description: Specify whether the Secret must be + defined + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + image: + description: |- + Container image name. + More info: https://kubernetes.io/docs/concepts/containers/images + This field is optional to allow higher level config management to default or override + container images in workload controllers like Deployments and StatefulSets. + type: string + imagePullPolicy: + description: |- + Image pull policy. + One of Always, Never, IfNotPresent. + Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/containers/images#updating-images + type: string + lifecycle: + description: |- + Actions that the management system should take in response to container lifecycle events. + Cannot be updated. + properties: + postStart: + description: |- + PostStart is called immediately after a container is created. If the handler fails, + the container is terminated and restarted according to its restart policy. + Other management of the container blocks until the hook completes. + More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + sleep: + description: Sleep represents the duration that + the container should sleep before being terminated. + properties: + seconds: + description: Seconds is the number of seconds + to sleep. + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + description: |- + Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept + for the backward compatibility. There are no validation of this field and + lifecycle hooks will fail in runtime when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + description: |- + PreStop is called immediately before a container is terminated due to an + API request or management event such as liveness/startup probe failure, + preemption, resource contention, etc. The handler is not called if the + container crashes or exits. The Pod's termination grace period countdown begins before the + PreStop hook is executed. Regardless of the outcome of the handler, the + container will eventually terminate within the Pod's termination grace + period (unless delayed by finalizers). Other management of the container blocks until the hook completes + or until the termination grace period is reached. + More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + sleep: + description: Sleep represents the duration that + the container should sleep before being terminated. + properties: + seconds: + description: Seconds is the number of seconds + to sleep. + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + description: |- + Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept + for the backward compatibility. There are no validation of this field and + lifecycle hooks will fail in runtime when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + description: |- + Periodic probe of container liveness. + Container will be restarted if the probe fails. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC + port. + properties: + port: + description: Port number of the gRPC service. Number + must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, + defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + name: + description: |- + Name of the container specified as a DNS_LABEL. + Each container in a pod must have a unique name (DNS_LABEL). + Cannot be updated. + type: string + ports: + description: |- + List of ports to expose from the container. Not specifying a port here + DOES NOT prevent that port from being exposed. Any port which is + listening on the default "0.0.0.0" address inside a container will be + accessible from the network. + Modifying this array with strategic merge patch may corrupt the data. + For more information See https://github.com/kubernetes/kubernetes/issues/108255. + Cannot be updated. + items: + description: ContainerPort represents a network port in + a single container. + properties: + containerPort: + description: |- + Number of port to expose on the pod's IP address. + This must be a valid port number, 0 < x < 65536. + format: int32 + type: integer + hostIP: + description: What host IP to bind the external port + to. + type: string + hostPort: + description: |- + Number of port to expose on the host. + If specified, this must be a valid port number, 0 < x < 65536. + If HostNetwork is specified, this must match ContainerPort. + Most containers do not need this. + format: int32 + type: integer + name: + description: |- + If specified, this must be an IANA_SVC_NAME and unique within the pod. Each + named port in a pod must have a unique name. Name for the port that can be + referred to by services. + type: string + protocol: + default: TCP + description: |- + Protocol for port. Must be UDP, TCP, or SCTP. + Defaults to "TCP". + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + description: |- + Periodic probe of container service readiness. + Container will be removed from service endpoints if the probe fails. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC + port. + properties: + port: + description: Port number of the gRPC service. Number + must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, + defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + resizePolicy: + description: Resources resize policy for the container. + items: + description: ContainerResizePolicy represents resource + resize policy for the container. + properties: + resourceName: + description: |- + Name of the resource to which this resource resize policy applies. + Supported values: cpu, memory. + type: string + restartPolicy: + description: |- + Restart policy to apply when specified resource is resized. + If not specified, it defaults to NotRequired. + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + description: |- + Compute Resources required by this container. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + properties: + claims: + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + + + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + + + This field is immutable. It can only be set for containers. + items: + description: ResourceClaim references one entry in + PodSpec.ResourceClaims. + properties: + name: + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + restartPolicy: + description: |- + RestartPolicy defines the restart behavior of individual containers in a pod. + This field may only be set for init containers, and the only allowed value is "Always". + For non-init containers or when this field is not specified, + the restart behavior is defined by the Pod's restart policy and the container type. + Setting the RestartPolicy as "Always" for the init container will have the following effect: + this init container will be continually restarted on + exit until all regular containers have terminated. Once all regular + containers have completed, all init containers with restartPolicy "Always" + will be shut down. This lifecycle differs from normal init containers and + is often referred to as a "sidecar" container. Although this init + container still starts in the init container sequence, it does not wait + for the container to complete before proceeding to the next init + container. Instead, the next init container starts immediately after this + init container is started, or after any startupProbe has successfully + completed. + type: string + securityContext: + description: |- + SecurityContext defines the security options the container should be run with. + If set, the fields of SecurityContext override the equivalent fields of PodSecurityContext. + More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ + properties: + allowPrivilegeEscalation: + description: |- + AllowPrivilegeEscalation controls whether a process can gain more + privileges than its parent process. This bool directly controls if + the no_new_privs flag will be set on the container process. + AllowPrivilegeEscalation is true always when the container is: + 1) run as Privileged + 2) has CAP_SYS_ADMIN + Note that this field cannot be set when spec.os.name is windows. + type: boolean + capabilities: + description: |- + The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the container runtime. + Note that this field cannot be set when spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + type: object + privileged: + description: |- + Run container in privileged mode. + Processes in privileged containers are essentially equivalent to root on the host. + Defaults to false. + Note that this field cannot be set when spec.os.name is windows. + type: boolean + procMount: + description: |- + procMount denotes the type of proc mount to use for the containers. + The default is DefaultProcMount which uses the container runtime defaults for + readonly paths and masked paths. + This requires the ProcMountType feature flag to be enabled. + Note that this field cannot be set when spec.os.name is windows. + type: string + readOnlyRootFilesystem: + description: |- + Whether this container has a read-only root filesystem. + Default is false. + Note that this field cannot be set when spec.os.name is windows. + type: boolean + runAsGroup: + description: |- + The GID to run the entrypoint of the container process. + Uses runtime default if unset. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: |- + Indicates that the container must run as a non-root user. + If true, the Kubelet will validate the image at runtime to ensure that it + does not run as UID 0 (root) and fail to start the container if it does. + If unset or false, no such validation will be performed. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: |- + The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: |- + The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random SELinux context for each + container. May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies + to the container. + type: string + role: + description: Role is a SELinux role label that applies + to the container. + type: string + type: + description: Type is a SELinux type label that applies + to the container. + type: string + user: + description: User is a SELinux user label that applies + to the container. + type: string + type: object + seccompProfile: + description: |- + The seccomp options to use by this container. If seccomp options are + provided at both the pod & container level, the container options + override the pod options. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile defined in a file on the node should be used. + The profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be set for any other type. + type: string + type: + description: |- + type indicates which kind of seccomp profile will be applied. + Valid options are: + + + Localhost - a profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile should be used. + Unconfined - no profile should be applied. + type: string + required: + - type + type: object + windowsOptions: + description: |- + The Windows specific settings applied to all containers. + If unspecified, the options from the PodSecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: |- + GMSACredentialSpec is where the GMSA admission webhook + (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the + GMSA credential spec named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name + of the GMSA credential spec to use. + type: string + hostProcess: + description: |- + HostProcess determines if a container should be run as a 'Host Process' container. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: |- + The UserName in Windows to run the entrypoint of the container process. + Defaults to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: string + type: object + type: object + startupProbe: + description: |- + StartupProbe indicates that the Pod has successfully initialized. + If specified, no other probes are executed until this completes successfully. + If this probe fails, the Pod will be restarted, just as if the livenessProbe failed. + This can be used to provide different probe parameters at the beginning of a Pod's lifecycle, + when it might take a long time to load data or warm a cache, than during steady-state operation. + This cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC + port. + properties: + port: + description: Port number of the gRPC service. Number + must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, + defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + stdin: + description: |- + Whether this container should allocate a buffer for stdin in the container runtime. If this + is not set, reads from stdin in the container will always result in EOF. + Default is false. + type: boolean + stdinOnce: + description: |- + Whether the container runtime should close the stdin channel after it has been opened by + a single attach. When stdin is true the stdin stream will remain open across multiple attach + sessions. If stdinOnce is set to true, stdin is opened on container start, is empty until the + first client attaches to stdin, and then remains open and accepts data until the client disconnects, + at which time stdin is closed and remains closed until the container is restarted. If this + flag is false, a container processes that reads from stdin will never receive an EOF. + Default is false + type: boolean + terminationMessagePath: + description: |- + Optional: Path at which the file to which the container's termination message + will be written is mounted into the container's filesystem. + Message written is intended to be brief final status, such as an assertion failure message. + Will be truncated by the node if greater than 4096 bytes. The total message length across + all containers will be limited to 12kb. + Defaults to /dev/termination-log. + Cannot be updated. + type: string + terminationMessagePolicy: + description: |- + Indicate how the termination message should be populated. File will use the contents of + terminationMessagePath to populate the container status message on both success and failure. + FallbackToLogsOnError will use the last chunk of container log output if the termination + message file is empty and the container exited with an error. + The log output is limited to 2048 bytes or 80 lines, whichever is smaller. + Defaults to File. + Cannot be updated. + type: string + tty: + description: |- + Whether this container should allocate a TTY for itself, also requires 'stdin' to be true. + Default is false. + type: boolean + volumeDevices: + description: volumeDevices is the list of block devices + to be used by the container. + items: + description: volumeDevice describes a mapping of a raw + block device within a container. + properties: + devicePath: + description: devicePath is the path inside of the + container that the device will be mapped to. + type: string + name: + description: name must match the name of a persistentVolumeClaim + in the pod + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + description: |- + Pod volumes to mount into the container's filesystem. + Cannot be updated. + items: + description: VolumeMount describes a mounting of a Volume + within a container. + properties: + mountPath: + description: |- + Path within the container at which the volume should be mounted. Must + not contain ':'. + type: string + mountPropagation: + description: |- + mountPropagation determines how mounts are propagated from the host + to container and the other way around. + When not set, MountPropagationNone is used. + This field is beta in 1.10. + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: |- + Mounted read-only if true, read-write otherwise (false or unspecified). + Defaults to false. + type: boolean + subPath: + description: |- + Path within the volume from which the container's volume should be mounted. + Defaults to "" (volume's root). + type: string + subPathExpr: + description: |- + Expanded path within the volume from which the container's volume should be mounted. + Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment. + Defaults to "" (volume's root). + SubPathExpr and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + description: |- + Container's working directory. + If not specified, the container runtime's default will be used, which + might be configured in the container image. + Cannot be updated. + type: string + required: + - name + type: object + type: array + nodeName: + description: |- + NodeName is a request to schedule this pod onto a specific node. If it is non-empty, + the scheduler simply schedules this pod onto that node, assuming that it fits resource + requirements. + type: string + nodeSelector: + additionalProperties: + type: string + description: |- + NodeSelector is a selector which must be true for the pod to fit on a node. + Selector which must match a node's labels for the pod to be scheduled on that node. + More info: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ + type: object + x-kubernetes-map-type: atomic + os: + description: |- + Specifies the OS of the containers in the pod. + Some pod and container fields are restricted if this is set. + + + If the OS field is set to linux, the following fields must be unset: + -securityContext.windowsOptions + + + If the OS field is set to windows, following fields must be unset: + - spec.hostPID + - spec.hostIPC + - spec.hostUsers + - spec.securityContext.seLinuxOptions + - spec.securityContext.seccompProfile + - spec.securityContext.fsGroup + - spec.securityContext.fsGroupChangePolicy + - spec.securityContext.sysctls + - spec.shareProcessNamespace + - spec.securityContext.runAsUser + - spec.securityContext.runAsGroup + - spec.securityContext.supplementalGroups + - spec.containers[*].securityContext.seLinuxOptions + - spec.containers[*].securityContext.seccompProfile + - spec.containers[*].securityContext.capabilities + - spec.containers[*].securityContext.readOnlyRootFilesystem + - spec.containers[*].securityContext.privileged + - spec.containers[*].securityContext.allowPrivilegeEscalation + - spec.containers[*].securityContext.procMount + - spec.containers[*].securityContext.runAsUser + - spec.containers[*].securityContext.runAsGroup + properties: + name: + description: |- + Name is the name of the operating system. The currently supported values are linux and windows. + Additional value may be defined in future and can be one of: + https://github.com/opencontainers/runtime-spec/blob/master/config.md#platform-specific-configuration + Clients should expect to handle additional values and treat unrecognized values in this field as os: null + type: string + required: + - name + type: object + overhead: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Overhead represents the resource overhead associated with running a pod for a given RuntimeClass. + This field will be autopopulated at admission time by the RuntimeClass admission controller. If + the RuntimeClass admission controller is enabled, overhead must not be set in Pod create requests. + The RuntimeClass admission controller will reject Pod create requests which have the overhead already + set. If RuntimeClass is configured and selected in the PodSpec, Overhead will be set to the value + defined in the corresponding RuntimeClass, otherwise it will remain unset and treated as zero. + More info: https://git.k8s.io/enhancements/keps/sig-node/688-pod-overhead/README.md + type: object + preemptionPolicy: + description: |- + PreemptionPolicy is the Policy for preempting pods with lower priority. + One of Never, PreemptLowerPriority. + Defaults to PreemptLowerPriority if unset. + type: string + priority: + description: |- + The priority value. Various system components use this field to find the + priority of the pod. When Priority Admission Controller is enabled, it + prevents users from setting this field. The admission controller populates + this field from PriorityClassName. + The higher the value, the higher the priority. + format: int32 + type: integer + priorityClassName: + description: |- + If specified, indicates the pod's priority. "system-node-critical" and + "system-cluster-critical" are two special keywords which indicate the + highest priorities with the former being the highest priority. Any other + name must be defined by creating a PriorityClass object with that name. + If not specified, the pod priority will be default or zero if there is no + default. + type: string + readinessGates: + description: |- + If specified, all readiness gates will be evaluated for pod readiness. + A pod is ready when all its containers are ready AND + all conditions specified in the readiness gates have status equal to "True" + More info: https://git.k8s.io/enhancements/keps/sig-network/580-pod-readiness-gates + items: + description: PodReadinessGate contains the reference to a pod + condition + properties: + conditionType: + description: ConditionType refers to a condition in the + pod's condition list with matching type. + type: string + required: + - conditionType + type: object + type: array + resourceClaims: + description: |- + ResourceClaims defines which ResourceClaims must be allocated + and reserved before the Pod is allowed to start. The resources + will be made available to those containers which consume them + by name. + + + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + + + This field is immutable. + items: + description: |- + PodResourceClaim references exactly one ResourceClaim through a ClaimSource. + It adds a name to it that uniquely identifies the ResourceClaim inside the Pod. + Containers that need access to the ResourceClaim reference it with this name. + properties: + name: + description: |- + Name uniquely identifies this resource claim inside the pod. + This must be a DNS_LABEL. + type: string + source: + description: Source describes where to find the ResourceClaim. + properties: + resourceClaimName: + description: |- + ResourceClaimName is the name of a ResourceClaim object in the same + namespace as this pod. + type: string + resourceClaimTemplateName: + description: |- + ResourceClaimTemplateName is the name of a ResourceClaimTemplate + object in the same namespace as this pod. + + + The template will be used to create a new ResourceClaim, which will + be bound to this pod. When this pod is deleted, the ResourceClaim + will also be deleted. The pod name and resource name, along with a + generated component, will be used to form a unique name for the + ResourceClaim, which will be recorded in pod.status.resourceClaimStatuses. + + + This field is immutable and no changes will be made to the + corresponding ResourceClaim by the control plane after creating the + ResourceClaim. + type: string + type: object + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + restartPolicy: + description: |- + Restart policy for all containers within the pod. + One of Always, OnFailure, Never. In some contexts, only a subset of those values may be permitted. + Default to Always. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#restart-policy + type: string + runtimeClassName: + description: |- + RuntimeClassName refers to a RuntimeClass object in the node.k8s.io group, which should be used + to run this pod. If no RuntimeClass resource matches the named class, the pod will not be run. + If unset or empty, the "legacy" RuntimeClass will be used, which is an implicit class with an + empty definition that uses the default runtime handler. + More info: https://git.k8s.io/enhancements/keps/sig-node/585-runtime-class + type: string + schedulerName: + description: |- + If specified, the pod will be dispatched by specified scheduler. + If not specified, the pod will be dispatched by default scheduler. + type: string + schedulingGates: + description: |- + SchedulingGates is an opaque list of values that if specified will block scheduling the pod. + If schedulingGates is not empty, the pod will stay in the SchedulingGated state and the + scheduler will not attempt to schedule the pod. + + + SchedulingGates can only be set at pod creation time, and be removed only afterwards. + + + This is a beta feature enabled by the PodSchedulingReadiness feature gate. + items: + description: PodSchedulingGate is associated to a Pod to guard + its scheduling. + properties: + name: + description: |- + Name of the scheduling gate. + Each scheduling gate must have a unique name field. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + securityContext: + description: |- + SecurityContext holds pod-level security attributes and common container settings. + Optional: Defaults to empty. See type description for default values of each field. + properties: + fsGroup: + description: |- + A special supplemental group that applies to all containers in a pod. + Some volume types allow the Kubelet to change the ownership of that volume + to be owned by the pod: + + + 1. The owning GID will be the FSGroup + 2. The setgid bit is set (new files created in the volume will be owned by FSGroup) + 3. The permission bits are OR'd with rw-rw---- + + + If unset, the Kubelet will not modify the ownership and permissions of any volume. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + fsGroupChangePolicy: + description: |- + fsGroupChangePolicy defines behavior of changing ownership and permission of the volume + before being exposed inside Pod. This field will only apply to + volume types which support fsGroup based ownership(and permissions). + It will have no effect on ephemeral volume types such as: secret, configmaps + and emptydir. + Valid values are "OnRootMismatch" and "Always". If not specified, "Always" is used. + Note that this field cannot be set when spec.os.name is windows. + type: string + runAsGroup: + description: |- + The GID to run the entrypoint of the container process. + Uses runtime default if unset. + May also be set in SecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence + for that container. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: |- + Indicates that the container must run as a non-root user. + If true, the Kubelet will validate the image at runtime to ensure that it + does not run as UID 0 (root) and fail to start the container if it does. + If unset or false, no such validation will be performed. + May also be set in SecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: |- + The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in SecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence + for that container. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: |- + The SELinux context to be applied to all containers. + If unspecified, the container runtime will allocate a random SELinux context for each + container. May also be set in SecurityContext. If set in + both SecurityContext and PodSecurityContext, the value specified in SecurityContext + takes precedence for that container. + Note that this field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies + to the container. + type: string + role: + description: Role is a SELinux role label that applies + to the container. + type: string + type: + description: Type is a SELinux type label that applies + to the container. + type: string + user: + description: User is a SELinux user label that applies + to the container. + type: string + type: object + seccompProfile: + description: |- + The seccomp options to use by the containers in this pod. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile defined in a file on the node should be used. + The profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be set for any other type. + type: string + type: + description: |- + type indicates which kind of seccomp profile will be applied. + Valid options are: + + + Localhost - a profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile should be used. + Unconfined - no profile should be applied. + type: string + required: + - type + type: object + supplementalGroups: + description: |- + A list of groups applied to the first process run in each container, in addition + to the container's primary GID, the fsGroup (if specified), and group memberships + defined in the container image for the uid of the container process. If unspecified, + no additional groups are added to any container. Note that group memberships + defined in the container image for the uid of the container process are still effective, + even if they are not included in this list. + Note that this field cannot be set when spec.os.name is windows. + items: + format: int64 + type: integer + type: array + sysctls: + description: |- + Sysctls hold a list of namespaced sysctls used for the pod. Pods with unsupported + sysctls (by the container runtime) might fail to launch. + Note that this field cannot be set when spec.os.name is windows. + items: + description: Sysctl defines a kernel parameter to be set + properties: + name: + description: Name of a property to set + type: string + value: + description: Value of a property to set + type: string + required: + - name + - value + type: object + type: array + windowsOptions: + description: |- + The Windows specific settings applied to all containers. + If unspecified, the options within a container's SecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: |- + GMSACredentialSpec is where the GMSA admission webhook + (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the + GMSA credential spec named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the + GMSA credential spec to use. + type: string + hostProcess: + description: |- + HostProcess determines if a container should be run as a 'Host Process' container. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: |- + The UserName in Windows to run the entrypoint of the container process. + Defaults to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: string + type: object + type: object + serviceAccount: + description: |- + DeprecatedServiceAccount is a depreciated alias for ServiceAccountName. + Deprecated: Use serviceAccountName instead. + type: string + serviceAccountName: + description: |- + ServiceAccountName is the name of the ServiceAccount to use to run this pod. + More info: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/ + type: string + setHostnameAsFQDN: + description: |- + If true the pod's hostname will be configured as the pod's FQDN, rather than the leaf name (the default). + In Linux containers, this means setting the FQDN in the hostname field of the kernel (the nodename field of struct utsname). + In Windows containers, this means setting the registry value of hostname for the registry key HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters to FQDN. + If a pod does not have FQDN, this has no effect. + Default to false. + type: boolean + shareProcessNamespace: + description: |- + Share a single process namespace between all of the containers in a pod. + When this is set containers will be able to view and signal processes from other containers + in the same pod, and the first process in each container will not be assigned PID 1. + HostPID and ShareProcessNamespace cannot both be set. + Optional: Default to false. + type: boolean + subdomain: + description: |- + If specified, the fully qualified Pod hostname will be "...svc.". + If not specified, the pod will not have a domainname at all. + type: string + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully. May be decreased in delete request. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + If this value is nil, the default grace period will be used instead. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + Defaults to 30 seconds. + format: int64 + type: integer + tolerations: + description: If specified, the pod's tolerations. + items: + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . + properties: + effect: + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. + type: string + operator: + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. + type: string + tolerationSeconds: + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. + format: int64 + type: integer + value: + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. + type: string + type: object + type: array + topologySpreadConstraints: + description: |- + TopologySpreadConstraints describes how a group of pods ought to spread across topology + domains. Scheduler will schedule pods in a way which abides by the constraints. + All topologySpreadConstraints are ANDed. + items: + description: TopologySpreadConstraint specifies how to spread + matching pods among the given topology. + properties: + labelSelector: + description: |- + LabelSelector is used to find matching pods. + Pods that match this label selector are counted to determine the number of pods + in their corresponding topology domain. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select the pods over which + spreading will be calculated. The keys are used to lookup values from the + incoming pod labels, those key-value labels are ANDed with labelSelector + to select the group of existing pods over which spreading will be calculated + for the incoming pod. The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + MatchLabelKeys cannot be set when LabelSelector isn't set. + Keys that don't exist in the incoming pod labels will + be ignored. A null or empty list means only match against labelSelector. + + + This is a beta field and requires the MatchLabelKeysInPodTopologySpread feature gate to be enabled (enabled by default). + items: + type: string + type: array + x-kubernetes-list-type: atomic + maxSkew: + description: |- + MaxSkew describes the degree to which pods may be unevenly distributed. + When `whenUnsatisfiable=DoNotSchedule`, it is the maximum permitted difference + between the number of matching pods in the target topology and the global minimum. + The global minimum is the minimum number of matching pods in an eligible domain + or zero if the number of eligible domains is less than MinDomains. + For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same + labelSelector spread as 2/2/1: + In this case, the global minimum is 1. + | zone1 | zone2 | zone3 | + | P P | P P | P | + - if MaxSkew is 1, incoming pod can only be scheduled to zone3 to become 2/2/2; + scheduling it onto zone1(zone2) would make the ActualSkew(3-1) on zone1(zone2) + violate MaxSkew(1). + - if MaxSkew is 2, incoming pod can be scheduled onto any zone. + When `whenUnsatisfiable=ScheduleAnyway`, it is used to give higher precedence + to topologies that satisfy it. + It's a required field. Default value is 1 and 0 is not allowed. + format: int32 + type: integer + minDomains: + description: |- + MinDomains indicates a minimum number of eligible domains. + When the number of eligible domains with matching topology keys is less than minDomains, + Pod Topology Spread treats "global minimum" as 0, and then the calculation of Skew is performed. + And when the number of eligible domains with matching topology keys equals or greater than minDomains, + this value has no effect on scheduling. + As a result, when the number of eligible domains is less than minDomains, + scheduler won't schedule more than maxSkew Pods to those domains. + If value is nil, the constraint behaves as if MinDomains is equal to 1. + Valid values are integers greater than 0. + When value is not nil, WhenUnsatisfiable must be DoNotSchedule. + + + For example, in a 3-zone cluster, MaxSkew is set to 2, MinDomains is set to 5 and pods with the same + labelSelector spread as 2/2/2: + | zone1 | zone2 | zone3 | + | P P | P P | P P | + The number of domains is less than 5(MinDomains), so "global minimum" is treated as 0. + In this situation, new pod with the same labelSelector cannot be scheduled, + because computed skew will be 3(3 - 0) if new Pod is scheduled to any of the three zones, + it will violate MaxSkew. + + + This is a beta field and requires the MinDomainsInPodTopologySpread feature gate to be enabled (enabled by default). + format: int32 + type: integer + nodeAffinityPolicy: + description: |- + NodeAffinityPolicy indicates how we will treat Pod's nodeAffinity/nodeSelector + when calculating pod topology spread skew. Options are: + - Honor: only nodes matching nodeAffinity/nodeSelector are included in the calculations. + - Ignore: nodeAffinity/nodeSelector are ignored. All nodes are included in the calculations. + + + If this value is nil, the behavior is equivalent to the Honor policy. + This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag. + type: string + nodeTaintsPolicy: + description: |- + NodeTaintsPolicy indicates how we will treat node taints when calculating + pod topology spread skew. Options are: + - Honor: nodes without taints, along with tainted nodes for which the incoming pod + has a toleration, are included. + - Ignore: node taints are ignored. All nodes are included. + + + If this value is nil, the behavior is equivalent to the Ignore policy. + This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag. + type: string + topologyKey: + description: |- + TopologyKey is the key of node labels. Nodes that have a label with this key + and identical values are considered to be in the same topology. + We consider each as a "bucket", and try to put balanced number + of pods into each bucket. + We define a domain as a particular instance of a topology. + Also, we define an eligible domain as a domain whose nodes meet the requirements of + nodeAffinityPolicy and nodeTaintsPolicy. + e.g. If TopologyKey is "kubernetes.io/hostname", each Node is a domain of that topology. + And, if TopologyKey is "topology.kubernetes.io/zone", each zone is a domain of that topology. + It's a required field. + type: string + whenUnsatisfiable: + description: |- + WhenUnsatisfiable indicates how to deal with a pod if it doesn't satisfy + the spread constraint. + - DoNotSchedule (default) tells the scheduler not to schedule it. + - ScheduleAnyway tells the scheduler to schedule the pod in any location, + but giving higher precedence to topologies that would help reduce the + skew. + A constraint is considered "Unsatisfiable" for an incoming pod + if and only if every possible node assignment for that pod would violate + "MaxSkew" on some topology. + For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same + labelSelector spread as 3/1/1: + | zone1 | zone2 | zone3 | + | P P P | P | P | + If WhenUnsatisfiable is set to DoNotSchedule, incoming pod can only be scheduled + to zone2(zone3) to become 3/2/1(3/1/2) as ActualSkew(2-1) on zone2(zone3) satisfies + MaxSkew(1). In other words, the cluster can still be imbalanced, but scheduler + won't make it *more* imbalanced. + It's a required field. + type: string + required: + - maxSkew + - topologyKey + - whenUnsatisfiable + type: object + type: array + x-kubernetes-list-map-keys: + - topologyKey + - whenUnsatisfiable + x-kubernetes-list-type: map + volumes: + description: |- + List of volumes that can be mounted by containers belonging to the pod. + More info: https://kubernetes.io/docs/concepts/storage/volumes + items: + description: Volume represents a named volume in a pod that + may be accessed by any container in the pod. + properties: + awsElasticBlockStore: + description: |- + awsElasticBlockStore represents an AWS Disk resource that is attached to a + kubelet's host machine and then exposed to the pod. + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + properties: + fsType: + description: |- + fsType is the filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + partition: + description: |- + partition is the partition in the volume that you want to mount. + If omitted, the default is to mount by volume name. + Examples: For volume /dev/sda1, you specify the partition as "1". + Similarly, the volume partition for /dev/sda is "0" (or you can leave the property empty). + format: int32 + type: integer + readOnly: + description: |- + readOnly value true will force the readOnly setting in VolumeMounts. + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + type: boolean + volumeID: + description: |- + volumeID is unique ID of the persistent disk resource in AWS (Amazon EBS volume). + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + type: string + required: + - volumeID + type: object + azureDisk: + description: azureDisk represents an Azure Data Disk mount + on the host and bind mount to the pod. + properties: + cachingMode: + description: 'cachingMode is the Host Caching mode: + None, Read Only, Read Write.' + type: string + diskName: + description: diskName is the Name of the data disk in + the blob storage + type: string + diskURI: + description: diskURI is the URI of data disk in the + blob storage + type: string + fsType: + description: |- + fsType is Filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + kind: + description: 'kind expected values are Shared: multiple + blob disks per storage account Dedicated: single + blob disk per storage account Managed: azure managed + data disk (only in managed availability set). defaults + to shared' + type: string + readOnly: + description: |- + readOnly Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + description: azureFile represents an Azure File Service + mount on the host and bind mount to the pod. + properties: + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretName: + description: secretName is the name of secret that + contains Azure Storage Account Name and Key + type: string + shareName: + description: shareName is the azure share Name + type: string + required: + - secretName + - shareName + type: object + cephfs: + description: cephFS represents a Ceph FS mount on the host + that shares a pod's lifetime + properties: + monitors: + description: |- + monitors is Required: Monitors is a collection of Ceph monitors + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + items: + type: string + type: array + path: + description: 'path is Optional: Used as the mounted + root, rather than the full Ceph tree, default is /' + type: string + readOnly: + description: |- + readOnly is Optional: Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + type: boolean + secretFile: + description: |- + secretFile is Optional: SecretFile is the path to key ring for User, default is /etc/ceph/user.secret + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + type: string + secretRef: + description: |- + secretRef is Optional: SecretRef is reference to the authentication secret for User, default is empty. + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + 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 + user: + description: |- + user is optional: User is the rados user name, default is admin + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + type: string + required: + - monitors + type: object + cinder: + description: |- + cinder represents a cinder volume attached and mounted on kubelets host machine. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + type: string + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + type: boolean + secretRef: + description: |- + secretRef is optional: points to a secret object containing parameters used to connect + to OpenStack. + 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 + volumeID: + description: |- + volumeID used to identify the volume in cinder. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + type: string + required: + - volumeID + type: object + configMap: + description: configMap represents a configMap that should + populate this volume + properties: + defaultMode: + description: |- + defaultMode is optional: mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + items: + description: |- + items if unspecified, each key-value pair in the Data field of the referenced + ConfigMap will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the ConfigMap, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within a + volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + 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 + optional: + description: optional specify whether the ConfigMap + or its keys must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + csi: + description: csi (Container Storage Interface) represents + ephemeral storage that is handled by certain external + CSI drivers (Beta feature). + properties: + driver: + description: |- + driver is the name of the CSI driver that handles this volume. + Consult with your admin for the correct name as registered in the cluster. + type: string + fsType: + description: |- + fsType to mount. Ex. "ext4", "xfs", "ntfs". + If not provided, the empty value is passed to the associated CSI driver + which will determine the default filesystem to apply. + type: string + nodePublishSecretRef: + description: |- + nodePublishSecretRef is a reference to the secret object containing + sensitive information to pass to the CSI driver to complete the CSI + NodePublishVolume and NodeUnpublishVolume calls. + This field is optional, and may be empty if no secret is required. If the + secret object contains more than one secret, all secret references are passed. + 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 + readOnly: + description: |- + readOnly specifies a read-only configuration for the volume. + Defaults to false (read/write). + type: boolean + volumeAttributes: + additionalProperties: + type: string + description: |- + volumeAttributes stores driver-specific properties that are passed to the CSI + driver. Consult your driver's documentation for supported values. + type: object + required: + - driver + type: object + downwardAPI: + description: downwardAPI represents downward API about the + pod that should populate this volume + properties: + defaultMode: + description: |- + Optional: mode bits to use on created files by default. Must be a + Optional: mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + items: + description: Items is a list of downward API volume + file + items: + description: DownwardAPIVolumeFile represents information + to create the file containing the pod field + properties: + fieldRef: + description: 'Required: Selects a field of the + pod: only annotations, labels, name and namespace + are supported.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in + the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + description: |- + Optional: mode bits used to set permissions on this file, must be an octal value + between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: 'Required: Path is the relative + path name of the file to be created. Must not + be absolute or contain the ''..'' path. Must + be utf-8 encoded. The first item of the relative + path must not start with ''..''' + type: string + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported. + properties: + containerName: + description: 'Container name: required for + volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of + the exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + type: object + emptyDir: + description: |- + emptyDir represents a temporary directory that shares a pod's lifetime. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir + properties: + medium: + description: |- + medium represents what type of storage medium should back this directory. + The default is "" which means to use the node's default medium. + Must be an empty string (default) or Memory. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + description: |- + sizeLimit is the total amount of local storage required for this EmptyDir volume. + The size limit is also applicable for memory medium. + The maximum usage on memory medium EmptyDir would be the minimum value between + the SizeLimit specified here and the sum of memory limits of all containers in a pod. + The default is nil which means that the limit is undefined. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + description: |- + ephemeral represents a volume that is handled by a cluster storage driver. + The volume's lifecycle is tied to the pod that defines it - it will be created before the pod starts, + and deleted when the pod is removed. + + + Use this if: + a) the volume is only needed while the pod runs, + b) features of normal volumes like restoring from snapshot or capacity + tracking are needed, + c) the storage driver is specified through a storage class, and + d) the storage driver supports dynamic volume provisioning through + a PersistentVolumeClaim (see EphemeralVolumeSource for more + information on the connection between this volume type + and PersistentVolumeClaim). + + + Use PersistentVolumeClaim or one of the vendor-specific + APIs for volumes that persist for longer than the lifecycle + of an individual pod. + + + Use CSI for light-weight local ephemeral volumes if the CSI driver is meant to + be used that way - see the documentation of the driver for + more information. + + + A pod can use both types of ephemeral volumes and + persistent volumes at the same time. + properties: + volumeClaimTemplate: + description: |- + Will be used to create a stand-alone PVC to provision the volume. + The pod in which this EphemeralVolumeSource is embedded will be the + owner of the PVC, i.e. the PVC will be deleted together with the + pod. The name of the PVC will be `-` where + `` is the name from the `PodSpec.Volumes` array + entry. Pod validation will reject the pod if the concatenated name + is not valid for a PVC (for example, too long). + + + An existing PVC with that name that is not owned by the pod + will *not* be used for the pod to avoid using an unrelated + volume by mistake. Starting the pod is then blocked until + the unrelated PVC is removed. If such a pre-created PVC is + meant to be used by the pod, the PVC has to updated with an + owner reference to the pod once the pod exists. Normally + this should not be necessary, but it may be useful when + manually reconstructing a broken cluster. + + + This field is read-only and no changes will be made by Kubernetes + to the PVC after it has been created. + + + Required, must not be nil. + properties: + metadata: + description: |- + May contain labels and annotations that will be copied into the PVC + when creating it. No other fields are allowed and will be rejected during + validation. + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + description: |- + The specification for the PersistentVolumeClaim. The entire content is + copied unchanged into the PVC that gets created from this + template. The same fields as in a PersistentVolumeClaim + are also valid here. + properties: + accessModes: + description: |- + accessModes contains the desired access modes the volume should have. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1 + items: + type: string + type: array + dataSource: + description: |- + dataSource field can be used to specify either: + * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) + * An existing PVC (PersistentVolumeClaim) + If the provisioner or an external controller can support the specified data source, + it will create a new volume based on the contents of the specified data source. + When the AnyVolumeDataSource feature gate is enabled, dataSource contents will be copied to dataSourceRef, + and dataSourceRef contents will be copied to dataSource when dataSourceRef.namespace is not specified. + If the namespace is specified, then dataSourceRef will not be copied to dataSource. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource + being referenced + type: string + name: + description: Name is the name of resource + being referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + description: |- + dataSourceRef specifies the object from which to populate the volume with data, if a non-empty + volume is desired. This may be any object from a non-empty API group (non + core object) or a PersistentVolumeClaim object. + When this field is specified, volume binding will only succeed if the type of + the specified object matches some installed volume populator or dynamic + provisioner. + This field will replace the functionality of the dataSource field and as such + if both fields are non-empty, they must have the same value. For backwards + compatibility, when namespace isn't specified in dataSourceRef, + both fields (dataSource and dataSourceRef) will be set to the same + value automatically if one of them is empty and the other is non-empty. + When namespace is specified in dataSourceRef, + dataSource isn't set to the same value and must be empty. + There are three important differences between dataSource and dataSourceRef: + * While dataSource only allows two specific types of objects, dataSourceRef + allows any non-core object, as well as PersistentVolumeClaim objects. + * While dataSource ignores disallowed values (dropping them), dataSourceRef + preserves all values, and generates an error if a disallowed value is + specified. + * While dataSource only allows local objects, dataSourceRef allows objects + in any namespaces. + (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled. + (Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource + being referenced + type: string + name: + description: Name is the name of resource + being referenced + type: string + namespace: + description: |- + Namespace is the namespace of resource being referenced + Note that when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details. + (Alpha) This field requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + type: string + required: + - kind + - name + type: object + resources: + description: |- + resources represents the minimum resources the volume should have. + If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements + that are lower than previous value but must still be higher than capacity recorded in the + status field of the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + selector: + description: selector is a label query over + volumes to consider for binding. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + description: |- + storageClassName is the name of the StorageClass required by the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1 + type: string + volumeAttributesClassName: + description: |- + volumeAttributesClassName may be used to set the VolumeAttributesClass used by this claim. + If specified, the CSI driver will create or update the volume with the attributes defined + in the corresponding VolumeAttributesClass. This has a different purpose than storageClassName, + it can be changed after the claim is created. An empty string value means that no VolumeAttributesClass + will be applied to the claim but it's not allowed to reset this field to empty string once it is set. + If unspecified and the PersistentVolumeClaim is unbound, the default VolumeAttributesClass + will be set by the persistentvolume controller if it exists. + If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be + set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource + exists. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#volumeattributesclass + (Alpha) Using this field requires the VolumeAttributesClass feature gate to be enabled. + type: string + volumeMode: + description: |- + volumeMode defines what type of volume is required by the claim. + Value of Filesystem is implied when not included in claim spec. + type: string + volumeName: + description: volumeName is the binding reference + to the PersistentVolume backing this claim. + type: string + type: object + required: + - spec + type: object + type: object + fc: + description: fc represents a Fibre Channel resource that + is attached to a kubelet's host machine and then exposed + to the pod. + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + lun: + description: 'lun is Optional: FC target lun number' + format: int32 + type: integer + readOnly: + description: |- + readOnly is Optional: Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + targetWWNs: + description: 'targetWWNs is Optional: FC target worldwide + names (WWNs)' + items: + type: string + type: array + wwids: + description: |- + wwids Optional: FC volume world wide identifiers (wwids) + Either wwids or combination of targetWWNs and lun must be set, but not both simultaneously. + items: + type: string + type: array + type: object + flexVolume: + description: |- + flexVolume represents a generic volume resource that is + provisioned/attached using an exec based plugin. + properties: + driver: + description: driver is the name of the driver to use + for this volume. + type: string + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". The default filesystem depends on FlexVolume script. + type: string + options: + additionalProperties: + type: string + description: 'options is Optional: this field holds + extra command options if any.' + type: object + readOnly: + description: |- + readOnly is Optional: defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: |- + secretRef is Optional: secretRef is reference to the secret object containing + sensitive information to pass to the plugin scripts. This may be + empty if no secret object is specified. If the secret object + contains more than one secret, all secrets are passed to the plugin + scripts. + 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 + required: + - driver + type: object + flocker: + description: flocker represents a Flocker volume attached + to a kubelet's host machine. This depends on the Flocker + control service being running + properties: + datasetName: + description: |- + datasetName is Name of the dataset stored as metadata -> name on the dataset for Flocker + should be considered as deprecated + type: string + datasetUUID: + description: datasetUUID is the UUID of the dataset. + This is unique identifier of a Flocker dataset + type: string + type: object + gcePersistentDisk: + description: |- + gcePersistentDisk represents a GCE Disk resource that is attached to a + kubelet's host machine and then exposed to the pod. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + properties: + fsType: + description: |- + fsType is filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + partition: + description: |- + partition is the partition in the volume that you want to mount. + If omitted, the default is to mount by volume name. + Examples: For volume /dev/sda1, you specify the partition as "1". + Similarly, the volume partition for /dev/sda is "0" (or you can leave the property empty). + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + format: int32 + type: integer + pdName: + description: |- + pdName is unique name of the PD resource in GCE. Used to identify the disk in GCE. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + type: string + readOnly: + description: |- + readOnly here will force the ReadOnly setting in VolumeMounts. + Defaults to false. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + type: boolean + required: + - pdName + type: object + gitRepo: + description: |- + gitRepo represents a git repository at a particular revision. + DEPRECATED: GitRepo is deprecated. To provision a container with a git repo, mount an + EmptyDir into an InitContainer that clones the repo using git, then mount the EmptyDir + into the Pod's container. + properties: + directory: + description: |- + directory is the target directory name. + Must not contain or start with '..'. If '.' is supplied, the volume directory will be the + git repository. Otherwise, if specified, the volume will contain the git repository in + the subdirectory with the given name. + type: string + repository: + description: repository is the URL + type: string + revision: + description: revision is the commit hash for the specified + revision. + type: string + required: + - repository + type: object + glusterfs: + description: |- + glusterfs represents a Glusterfs mount on the host that shares a pod's lifetime. + More info: https://examples.k8s.io/volumes/glusterfs/README.md + properties: + endpoints: + description: |- + endpoints is the endpoint name that details Glusterfs topology. + More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod + type: string + path: + description: |- + path is the Glusterfs volume path. + More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod + type: string + readOnly: + description: |- + readOnly here will force the Glusterfs volume to be mounted with read-only permissions. + Defaults to false. + More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod + type: boolean + required: + - endpoints + - path + type: object + hostPath: + description: |- + hostPath represents a pre-existing file or directory on the host + machine that is directly exposed to the container. This is generally + used for system agents or other privileged things that are allowed + to see the host machine. Most containers will NOT need this. + More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + --- + TODO(jonesdl) We need to restrict who can use host directory mounts and who can/can not + mount host directories as read/write. + properties: + path: + description: |- + path of the directory on the host. + If the path is a symlink, it will follow the link to the real path. + More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + type: string + type: + description: |- + type for HostPath Volume + Defaults to "" + More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + type: string + required: + - path + type: object + iscsi: + description: |- + iscsi represents an ISCSI Disk resource that is attached to a + kubelet's host machine and then exposed to the pod. + More info: https://examples.k8s.io/volumes/iscsi/README.md + properties: + chapAuthDiscovery: + description: chapAuthDiscovery defines whether support + iSCSI Discovery CHAP authentication + type: boolean + chapAuthSession: + description: chapAuthSession defines whether support + iSCSI Session CHAP authentication + type: boolean + fsType: + description: |- + fsType is the filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#iscsi + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + initiatorName: + description: |- + initiatorName is the custom iSCSI Initiator Name. + If initiatorName is specified with iscsiInterface simultaneously, new iSCSI interface + : will be created for the connection. + type: string + iqn: + description: iqn is the target iSCSI Qualified Name. + type: string + iscsiInterface: + description: |- + iscsiInterface is the interface Name that uses an iSCSI transport. + Defaults to 'default' (tcp). + type: string + lun: + description: lun represents iSCSI Target Lun number. + format: int32 + type: integer + portals: + description: |- + portals is the iSCSI Target Portal List. The portal is either an IP or ip_addr:port if the port + is other than default (typically TCP ports 860 and 3260). + items: + type: string + type: array + readOnly: + description: |- + readOnly here will force the ReadOnly setting in VolumeMounts. + Defaults to false. + type: boolean + secretRef: + description: secretRef is the CHAP Secret for iSCSI + target and initiator authentication + 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 + targetPortal: + description: |- + targetPortal is iSCSI Target Portal. The Portal is either an IP or ip_addr:port if the port + is other than default (typically TCP ports 860 and 3260). + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + description: |- + name of the volume. + Must be a DNS_LABEL and unique within the pod. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + nfs: + description: |- + nfs represents an NFS mount on the host that shares a pod's lifetime + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + properties: + path: + description: |- + path that is exported by the NFS server. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + type: string + readOnly: + description: |- + readOnly here will force the NFS export to be mounted with read-only permissions. + Defaults to false. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + type: boolean + server: + description: |- + server is the hostname or IP address of the NFS server. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + description: |- + persistentVolumeClaimVolumeSource represents a reference to a + PersistentVolumeClaim in the same namespace. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims + properties: + claimName: + description: |- + claimName is the name of a PersistentVolumeClaim in the same namespace as the pod using this volume. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims + type: string + readOnly: + description: |- + readOnly Will force the ReadOnly setting in VolumeMounts. + Default false. + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + description: photonPersistentDisk represents a PhotonController + persistent disk attached and mounted on kubelets host + machine + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + pdID: + description: pdID is the ID that identifies Photon Controller + persistent disk + type: string + required: + - pdID + type: object + portworxVolume: + description: portworxVolume represents a portworx volume + attached and mounted on kubelets host machine + properties: + fsType: + description: |- + fSType represents the filesystem type to mount + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs". Implicitly inferred to be "ext4" if unspecified. + type: string + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + volumeID: + description: volumeID uniquely identifies a Portworx + volume + type: string + required: + - volumeID + type: object + projected: + description: projected items for all in one resources secrets, + configmaps, and downward API + properties: + defaultMode: + description: |- + defaultMode are the mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + sources: + description: sources is the list of volume projections + items: + description: Projection that may be projected along + with other supported volume types + properties: + clusterTrustBundle: + description: |- + ClusterTrustBundle allows a pod to access the `.spec.trustBundle` field + of ClusterTrustBundle objects in an auto-updating file. + + + Alpha, gated by the ClusterTrustBundleProjection feature gate. + + + ClusterTrustBundle objects can either be selected by name, or by the + combination of signer name and a label selector. + + + Kubelet performs aggressive normalization of the PEM contents written + into the pod filesystem. Esoteric PEM features such as inter-block + comments and block headers are stripped. Certificates are deduplicated. + The ordering of certificates within the file is arbitrary, and Kubelet + may change the order over time. + properties: + labelSelector: + description: |- + Select all ClusterTrustBundles that match this label selector. Only has + effect if signerName is set. Mutually-exclusive with name. If unset, + interpreted as "match nothing". If set but empty, interpreted as "match + everything". + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + name: + description: |- + Select a single ClusterTrustBundle by object name. Mutually-exclusive + with signerName and labelSelector. + type: string + optional: + description: |- + If true, don't block pod startup if the referenced ClusterTrustBundle(s) + aren't available. If using name, then the named ClusterTrustBundle is + allowed not to exist. If using signerName, then the combination of + signerName and labelSelector is allowed to match zero + ClusterTrustBundles. + type: boolean + path: + description: Relative path from the volume + root to write the bundle. + type: string + signerName: + description: |- + Select all ClusterTrustBundles that match this signer name. + Mutually-exclusive with name. The contents of all selected + ClusterTrustBundles will be unified and deduplicated. + type: string + required: + - path + type: object + configMap: + description: configMap information about the configMap + data to project + properties: + items: + description: |- + items if unspecified, each key-value pair in the Data field of the referenced + ConfigMap will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the ConfigMap, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path + within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + 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 + optional: + description: optional specify whether the + ConfigMap or its keys must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + downwardAPI: + description: downwardAPI information about the + downwardAPI data to project + properties: + items: + description: Items is a list of DownwardAPIVolume + file + items: + description: DownwardAPIVolumeFile represents + information to create the file containing + the pod field + properties: + fieldRef: + description: 'Required: Selects a field + of the pod: only annotations, labels, + name and namespace are supported.' + properties: + apiVersion: + description: Version of the schema + the FieldPath is written in terms + of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to + select in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + description: |- + Optional: mode bits used to set permissions on this file, must be an octal value + between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: 'Required: Path is the + relative path name of the file to + be created. Must not be absolute or + contain the ''..'' path. Must be utf-8 + encoded. The first item of the relative + path must not start with ''..''' + type: string + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported. + properties: + containerName: + description: 'Container name: required + for volumes, optional for env + vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output + format of the exposed resources, + defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource + to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + type: object + secret: + description: secret information about the secret + data to project + properties: + items: + description: |- + items if unspecified, each key-value pair in the Data field of the referenced + Secret will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the Secret, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path + within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + 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 + optional: + description: optional field specify whether + the Secret or its key must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + serviceAccountToken: + description: serviceAccountToken is information + about the serviceAccountToken data to project + properties: + audience: + description: |- + audience is the intended audience of the token. A recipient of a token + must identify itself with an identifier specified in the audience of the + token, and otherwise should reject the token. The audience defaults to the + identifier of the apiserver. + type: string + expirationSeconds: + description: |- + expirationSeconds is the requested duration of validity of the service + account token. As the token approaches expiration, the kubelet volume + plugin will proactively rotate the service account token. The kubelet will + start trying to rotate the token if the token is older than 80 percent of + its time to live or if the token is older than 24 hours.Defaults to 1 hour + and must be at least 10 minutes. + format: int64 + type: integer + path: + description: |- + path is the path relative to the mount point of the file to project the + token into. + type: string + required: + - path + type: object + type: object + type: array + type: object + quobyte: + description: quobyte represents a Quobyte mount on the host + that shares a pod's lifetime + properties: + group: + description: |- + group to map volume access to + Default is no group + type: string + readOnly: + description: |- + readOnly here will force the Quobyte volume to be mounted with read-only permissions. + Defaults to false. + type: boolean + registry: + description: |- + registry represents a single or multiple Quobyte Registry services + specified as a string as host:port pair (multiple entries are separated with commas) + which acts as the central registry for volumes + type: string + tenant: + description: |- + tenant owning the given Quobyte volume in the Backend + Used with dynamically provisioned Quobyte volumes, value is set by the plugin + type: string + user: + description: |- + user to map volume access to + Defaults to serivceaccount user + type: string + volume: + description: volume is a string that references an already + created Quobyte volume by name. + type: string + required: + - registry + - volume + type: object + rbd: + description: |- + rbd represents a Rados Block Device mount on the host that shares a pod's lifetime. + More info: https://examples.k8s.io/volumes/rbd/README.md + properties: + fsType: + description: |- + fsType is the filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#rbd + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + image: + description: |- + image is the rados image name. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + keyring: + description: |- + keyring is the path to key ring for RBDUser. + Default is /etc/ceph/keyring. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + monitors: + description: |- + monitors is a collection of Ceph monitors. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + items: + type: string + type: array + pool: + description: |- + pool is the rados pool name. + Default is rbd. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + readOnly: + description: |- + readOnly here will force the ReadOnly setting in VolumeMounts. + Defaults to false. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: boolean + secretRef: + description: |- + secretRef is name of the authentication secret for RBDUser. If provided + overrides keyring. + Default is nil. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + 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 + user: + description: |- + user is the rados user name. + Default is admin. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + required: + - image + - monitors + type: object + scaleIO: + description: scaleIO represents a ScaleIO persistent volume + attached and mounted on Kubernetes nodes. + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". + Default is "xfs". + type: string + gateway: + description: gateway is the host address of the ScaleIO + API Gateway. + type: string + protectionDomain: + description: protectionDomain is the name of the ScaleIO + Protection Domain for the configured storage. + type: string + readOnly: + description: |- + readOnly Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: |- + secretRef references to the secret for ScaleIO user and other + sensitive information. If this is not provided, Login operation will fail. + 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 + sslEnabled: + description: sslEnabled Flag enable/disable SSL communication + with Gateway, default false + type: boolean + storageMode: + description: |- + storageMode indicates whether the storage for a volume should be ThickProvisioned or ThinProvisioned. + Default is ThinProvisioned. + type: string + storagePool: + description: storagePool is the ScaleIO Storage Pool + associated with the protection domain. + type: string + system: + description: system is the name of the storage system + as configured in ScaleIO. + type: string + volumeName: + description: |- + volumeName is the name of a volume already created in the ScaleIO system + that is associated with this volume source. + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + description: |- + secret represents a secret that should populate this volume. + More info: https://kubernetes.io/docs/concepts/storage/volumes#secret + properties: + defaultMode: + description: |- + defaultMode is Optional: mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values + for mode bits. Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + items: + description: |- + items If unspecified, each key-value pair in the Data field of the referenced + Secret will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the Secret, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within a + volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + optional: + description: optional field specify whether the Secret + or its keys must be defined + type: boolean + secretName: + description: |- + secretName is the name of the secret in the pod's namespace to use. + More info: https://kubernetes.io/docs/concepts/storage/volumes#secret + type: string + type: object + storageos: + description: storageOS represents a StorageOS volume attached + and mounted on Kubernetes nodes. + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: |- + secretRef specifies the secret to use for obtaining the StorageOS API + credentials. If not specified, default values will be attempted. + 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 + volumeName: + description: |- + volumeName is the human-readable name of the StorageOS volume. Volume + names are only unique within a namespace. + type: string + volumeNamespace: + description: |- + volumeNamespace specifies the scope of the volume within StorageOS. If no + namespace is specified then the Pod's namespace will be used. This allows the + Kubernetes name scoping to be mirrored within StorageOS for tighter integration. + Set VolumeName to any name to override the default behaviour. + Set to "default" if you are not using namespaces within StorageOS. + Namespaces that do not pre-exist within StorageOS will be created. + type: string + type: object + vsphereVolume: + description: vsphereVolume represents a vSphere volume attached + and mounted on kubelets host machine + properties: + fsType: + description: |- + fsType is filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + storagePolicyID: + description: storagePolicyID is the storage Policy Based + Management (SPBM) profile ID associated with the StoragePolicyName. + type: string + storagePolicyName: + description: storagePolicyName is the storage Policy + Based Management (SPBM) profile name. + type: string + volumePath: + description: volumePath is the path that identifies + vSphere volume vmdk + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + required: + - containers + type: object + x-kubernetes-preserve-unknown-fields: true + scripts: + description: |- + Specifies groups of scripts, each provided via a ConfigMap, to be mounted as volumes in the container. + These scripts can be executed during container startup or via specific actions. + + + Each script group is encapsulated in a ComponentTemplateSpec that includes: + + + - The ConfigMap containing the scripts. + - The mount point where the scripts will be mounted inside the container. + + + This field is immutable. + items: + properties: + defaultMode: + description: |- + The operator attempts to set default file permissions for scripts (0555) and configurations (0444). + However, certain database engines may require different file permissions. + You can specify the desired file permissions here. + + + Must be specified as an octal value between 0000 and 0777 (inclusive), + or as a decimal value between 0 and 511 (inclusive). + YAML supports both octal and decimal values for file permissions. + + + Please note that this setting only affects the permissions of the files themselves. + Directories within the specified path are not impacted by this setting. + It's important to be aware that this setting might conflict with other options + that influence the file mode, such as fsGroup. + In such cases, the resulting file mode may have additional bits set. + Refers to documents of k8s.ConfigMapVolumeSource.defaultMode for more information. + format: int32 + type: integer + name: + description: Specifies the name of the configuration template. + maxLength: 63 + pattern: ^[a-z0-9]([a-z0-9\.\-]*[a-z0-9])?$ + type: string + namespace: + default: default + description: |- + Specifies the namespace of the referenced configuration template ConfigMap object. + An empty namespace is equivalent to the "default" namespace. + maxLength: 63 + pattern: ^[a-z0-9]([a-z0-9\-]*[a-z0-9])?$ + type: string + templateRef: + description: Specifies the name of the referenced configuration + template ConfigMap object. + maxLength: 63 + pattern: ^[a-z0-9]([a-z0-9\.\-]*[a-z0-9])?$ + type: string + volumeName: + description: |- + Refers to the volume name of PodTemplate. The configuration file produced through the configuration + template will be mounted to the corresponding volume. Must be a DNS_LABEL name. + The volume name must be defined in podSpec.containers[*].volumeMounts. + maxLength: 63 + pattern: ^[a-z]([a-z0-9\-]*[a-z0-9])?$ + type: string + required: + - name + - volumeName + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + serviceKind: + description: |- + Defines the type of well-known service protocol that the Component provides. + It specifies the standard or widely recognized protocol used by the Component to offer its Services. + + + The `serviceKind` field allows users to quickly identify the type of Service provided by the Component + based on common protocols or service types. This information helps in understanding the compatibility, + interoperability, and usage of the Component within a system. + + + Some examples of well-known service protocols include: + + + - "MySQL": Indicates that the Component provides a MySQL database service. + - "PostgreSQL": Indicates that the Component offers a PostgreSQL database service. + - "Redis": Signifies that the Component functions as a Redis key-value store. + - "ETCD": Denotes that the Component serves as an ETCD distributed key-value store. + + + The `serviceKind` value is case-insensitive, allowing for flexibility in specifying the protocol name. + + + When specifying the `serviceKind`, consider the following guidelines: + + + - Use well-established and widely recognized protocol names or service types. + - Ensure that the `serviceKind` accurately represents the primary service type offered by the Component. + - If the Component provides multiple services, choose the most prominent or commonly used protocol. + - Limit the `serviceKind` to a maximum of 32 characters for conciseness and readability. + + + Note: The `serviceKind` field is optional and can be left empty if the Component does not fit into a well-known + service category or if the protocol is not widely recognized. It is primarily used to convey information about + the Component's service type to users and facilitate discovery and integration. + + + The `serviceKind` field is immutable and cannot be updated. + maxLength: 32 + type: string + serviceRefDeclarations: + description: |- + Lists external service dependencies of the Component, including services from other Clusters or outside the K8s environment. + + + This field is immutable. + items: + description: |- + ServiceRefDeclaration represents a reference to a service that can be either provided by a KubeBlocks Cluster + or an external service. + It acts as a placeholder for the actual service reference, which is determined later when a Cluster is created. + + + The purpose of ServiceRefDeclaration is to declare a service dependency without specifying the concrete details + of the service. + It allows for flexibility and abstraction in defining service references within a Component. + By using ServiceRefDeclaration, you can define service dependencies in a declarative manner, enabling loose coupling + and easier management of service references across different components and clusters. + + + Upon Cluster creation, the ServiceRefDeclaration is bound to an actual service through the ServiceRef field, + effectively resolving and connecting to the specified service. + properties: + name: + description: Specifies the name of the ServiceRefDeclaration. + type: string + optional: + description: |- + Specifies whether the service reference can be optional. + + + For an optional service-ref, the component can still be created even if the service-ref is not provided. + type: boolean + serviceRefDeclarationSpecs: + description: |- + Defines a list of constraints and requirements for services that can be bound to this ServiceRefDeclaration + upon Cluster creation. + Each ServiceRefDeclarationSpec defines a ServiceKind and ServiceVersion, + outlining the acceptable service types and versions that are compatible. + + + This flexibility allows a ServiceRefDeclaration to be fulfilled by any one of the provided specs. + For example, if it requires an OLTP database, specs for both MySQL and PostgreSQL are listed, + either MySQL or PostgreSQL services can be used when binding. + items: + properties: + serviceKind: + description: |- + Specifies the type or nature of the service. This should be a well-known application cluster type, such as + {mysql, redis, mongodb}. + The field is case-insensitive and supports abbreviations for some well-known databases. + For instance, both `zk` and `zookeeper` are considered as a ZooKeeper cluster, while `pg`, `postgres`, `postgresql` + are all recognized as a PostgreSQL cluster. + type: string + serviceVersion: + description: |- + Defines the service version of the service reference. This is a regular expression that matches a version number pattern. + For instance, `^8.0.8$`, `8.0.\d{1,2}$`, `^[v\-]*?(\d{1,2}\.){0,3}\d{1,2}$` are all valid patterns. + type: string + required: + - serviceKind + - serviceVersion + type: object + type: array + required: + - name + - serviceRefDeclarationSpecs + type: object + type: array + serviceVersion: + description: |- + Specifies the version of the Service provided by the Component. + It follows the syntax and semantics of the "Semantic Versioning" specification (http://semver.org/). + + + The Semantic Versioning specification defines a version number format of X.Y.Z (MAJOR.MINOR.PATCH), where: + + + - X represents the major version and indicates incompatible API changes. + - Y represents the minor version and indicates added functionality in a backward-compatible manner. + - Z represents the patch version and indicates backward-compatible bug fixes. + + + Additional labels for pre-release and build metadata are available as extensions to the X.Y.Z format: + + + - Use pre-release labels (e.g., -alpha, -beta) for versions that are not yet stable or ready for production use. + - Use build metadata (e.g., +build.1) for additional version information if needed. + + + Examples of valid ServiceVersion values: + + + - "1.0.0" + - "2.3.1" + - "3.0.0-alpha.1" + - "4.5.2+build.1" + + + The `serviceVersion` field is immutable and cannot be updated. + maxLength: 32 + type: string + services: + description: |- + Defines additional Services to expose the Component's endpoints. + + + A default headless Service, named `{cluster.name}-{component.name}-headless`, is automatically created + for internal Cluster communication. + + + This field enables customization of additional Services to expose the Component's endpoints to + other Components within the same or different Clusters, and to external applications. + Each Service entry in this list can include properties such as ports, type, and selectors. + + + - For intra-Cluster access, Components can reference Services using variables declared in + `componentDefinition.spec.vars[*].valueFrom.serviceVarRef`. + - For inter-Cluster access, reference Services use variables declared in + `componentDefinition.spec.vars[*].valueFrom.serviceRefVarRef`, + and bind Services at Cluster creation time with `clusterComponentSpec.ServiceRef[*].clusterServiceSelector`. + + + This field is immutable. + items: + description: |- + ComponentService defines a service that would be exposed as an inter-component service within a Cluster. + A Service defined in the ComponentService is expected to be accessed by other Components within the same Cluster. + + + When a Component needs to use a ComponentService provided by another Component within the same Cluster, + it can declare a variable in the `componentDefinition.spec.vars` section and bind it to the specific exposed address + of the ComponentService using the `serviceVarRef` field. + properties: + annotations: + additionalProperties: + type: string + description: |- + If ServiceType is LoadBalancer, cloud provider related parameters can be put here + More info: https://kubernetes.io/docs/concepts/services-networking/service/#loadbalancer. + type: object + disableAutoProvision: + description: |- + Indicates whether the automatic provisioning of the service should be disabled. + + + If set to true, the service will not be automatically created at the component provisioning. + Instead, you can enable the creation of this service by specifying it explicitly in the cluster API. + type: boolean + name: + description: |- + Name defines the name of the service. + otherwise, it indicates the name of the service. + Others can refer to this service by its name. (e.g., connection credential) + Cannot be updated. + maxLength: 25 + type: string + podService: + default: false + description: |- + Indicates whether to create a corresponding Service for each Pod of the selected Component. + When set to true, a set of Services will be automatically generated for each Pod, + and the `roleSelector` field will be ignored. + + + The names of the generated Services will follow the same suffix naming pattern: `$(serviceName)-$(podOrdinal)`. + The total number of generated Services will be equal to the number of replicas specified for the Component. + + + Example usage: + + + ```yaml + name: my-service + serviceName: my-service + podService: true + disableAutoProvision: true + spec: + type: NodePort + ports: + - name: http + port: 80 + targetPort: 8080 + ``` + + + In this example, if the Component has 3 replicas, three Services will be generated: + - my-service-0: Points to the first Pod (podOrdinal: 0) + - my-service-1: Points to the second Pod (podOrdinal: 1) + - my-service-2: Points to the third Pod (podOrdinal: 2) + + + Each generated Service will have the specified spec configuration and will target its respective Pod. + + + This feature is useful when you need to expose each Pod of a Component individually, allowing external access + to specific instances of the Component. + type: boolean + roleSelector: + description: "Extends the above `serviceSpec.selector` by allowing + you to specify defined role as selector for the service.\nWhen + `roleSelector` is set, it adds a label selector \"kubeblocks.io/role: + {roleSelector}\"\nto the `serviceSpec.selector`.\nExample + usage:\n\n\n\t roleSelector: \"leader\"\n\n\nIn this example, + setting `roleSelector` to \"leader\" will add a label selector\n\"kubeblocks.io/role: + leader\" to the `serviceSpec.selector`.\nThis means that the + service will select and route traffic to Pods with the label\n\"kubeblocks.io/role\" + set to \"leader\".\n\n\nNote that if `podService` sets to + true, RoleSelector will be ignored.\nThe `podService` flag + takes precedence over `roleSelector` and generates a service + for each Pod." + type: string + serviceName: + description: |- + ServiceName defines the name of the underlying service object. + If not specified, the default service name with different patterns will be used: + + + - CLUSTER_NAME: for cluster-level services + - CLUSTER_NAME-COMPONENT_NAME: for component-level services + + + Only one default service name is allowed. + Cannot be updated. + maxLength: 25 + pattern: ^[a-z]([a-z0-9\-]*[a-z0-9])?$ + type: string + spec: + description: |- + Spec defines the behavior of a service. + https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status + properties: + allocateLoadBalancerNodePorts: + description: |- + allocateLoadBalancerNodePorts defines if NodePorts will be automatically + allocated for services with type LoadBalancer. Default is "true". It + may be set to "false" if the cluster load-balancer does not rely on + NodePorts. If the caller requests specific NodePorts (by specifying a + value), those requests will be respected, regardless of this field. + This field may only be set for services with type LoadBalancer and will + be cleared if the type is changed to any other type. + type: boolean + clusterIP: + description: |- + clusterIP is the IP address of the service and is usually assigned + randomly. If an address is specified manually, is in-range (as per + system configuration), and is not in use, it will be allocated to the + service; otherwise creation of the service will fail. This field may not + be changed through updates unless the type field is also being changed + to ExternalName (which requires this field to be blank) or the type + field is being changed from ExternalName (in which case this field may + optionally be specified, as describe above). Valid values are "None", + empty string (""), or a valid IP address. Setting this to "None" makes a + "headless service" (no virtual IP), which is useful when direct endpoint + connections are preferred and proxying is not required. Only applies to + types ClusterIP, NodePort, and LoadBalancer. If this field is specified + when creating a Service of type ExternalName, creation will fail. This + field will be wiped when updating a Service to type ExternalName. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + type: string + clusterIPs: + description: |- + ClusterIPs is a list of IP addresses assigned to this service, and are + usually assigned randomly. If an address is specified manually, is + in-range (as per system configuration), and is not in use, it will be + allocated to the service; otherwise creation of the service will fail. + This field may not be changed through updates unless the type field is + also being changed to ExternalName (which requires this field to be + empty) or the type field is being changed from ExternalName (in which + case this field may optionally be specified, as describe above). Valid + values are "None", empty string (""), or a valid IP address. Setting + this to "None" makes a "headless service" (no virtual IP), which is + useful when direct endpoint connections are preferred and proxying is + not required. Only applies to types ClusterIP, NodePort, and + LoadBalancer. If this field is specified when creating a Service of type + ExternalName, creation will fail. This field will be wiped when updating + a Service to type ExternalName. If this field is not specified, it will + be initialized from the clusterIP field. If this field is specified, + clients must ensure that clusterIPs[0] and clusterIP have the same + value. + + + This field may hold a maximum of two entries (dual-stack IPs, in either order). + These IPs must correspond to the values of the ipFamilies field. Both + clusterIPs and ipFamilies are governed by the ipFamilyPolicy field. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalIPs: + description: |- + externalIPs is a list of IP addresses for which nodes in the cluster + will also accept traffic for this service. These IPs are not managed by + Kubernetes. The user is responsible for ensuring that traffic arrives + at a node with this IP. A common example is external load-balancers + that are not part of the Kubernetes system. + items: + type: string + type: array + externalName: + description: |- + externalName is the external reference that discovery mechanisms will + return as an alias for this service (e.g. a DNS CNAME record). No + proxying will be involved. Must be a lowercase RFC-1123 hostname + (https://tools.ietf.org/html/rfc1123) and requires `type` to be "ExternalName". + type: string + externalTrafficPolicy: + description: |- + externalTrafficPolicy describes how nodes distribute service traffic they + receive on one of the Service's "externally-facing" addresses (NodePorts, + ExternalIPs, and LoadBalancer IPs). If set to "Local", the proxy will configure + the service in a way that assumes that external load balancers will take care + of balancing the service traffic between nodes, and so each node will deliver + traffic only to the node-local endpoints of the service, without masquerading + the client source IP. (Traffic mistakenly sent to a node with no endpoints will + be dropped.) The default value, "Cluster", uses the standard behavior of + routing to all endpoints evenly (possibly modified by topology and other + features). Note that traffic sent to an External IP or LoadBalancer IP from + within the cluster will always get "Cluster" semantics, but clients sending to + a NodePort from within the cluster may need to take traffic policy into account + when picking a node. + type: string + healthCheckNodePort: + description: |- + healthCheckNodePort specifies the healthcheck nodePort for the service. + This only applies when type is set to LoadBalancer and + externalTrafficPolicy is set to Local. If a value is specified, is + in-range, and is not in use, it will be used. If not specified, a value + will be automatically allocated. External systems (e.g. load-balancers) + can use this port to determine if a given node holds endpoints for this + service or not. If this field is specified when creating a Service + which does not need it, creation will fail. This field will be wiped + when updating a Service to no longer need it (e.g. changing type). + This field cannot be updated once set. + format: int32 + type: integer + internalTrafficPolicy: + description: |- + InternalTrafficPolicy describes how nodes distribute service traffic they + receive on the ClusterIP. If set to "Local", the proxy will assume that pods + only want to talk to endpoints of the service on the same node as the pod, + dropping the traffic if there are no local endpoints. The default value, + "Cluster", uses the standard behavior of routing to all endpoints evenly + (possibly modified by topology and other features). + type: string + ipFamilies: + description: |- + IPFamilies is a list of IP families (e.g. IPv4, IPv6) assigned to this + service. This field is usually assigned automatically based on cluster + configuration and the ipFamilyPolicy field. If this field is specified + manually, the requested family is available in the cluster, + and ipFamilyPolicy allows it, it will be used; otherwise creation of + the service will fail. This field is conditionally mutable: it allows + for adding or removing a secondary IP family, but it does not allow + changing the primary IP family of the Service. Valid values are "IPv4" + and "IPv6". This field only applies to Services of types ClusterIP, + NodePort, and LoadBalancer, and does apply to "headless" services. + This field will be wiped when updating a Service to type ExternalName. + + + This field may hold a maximum of two entries (dual-stack families, in + either order). These families must correspond to the values of the + clusterIPs field, if specified. Both clusterIPs and ipFamilies are + governed by the ipFamilyPolicy field. + items: + description: |- + IPFamily represents the IP Family (IPv4 or IPv6). This type is used + to express the family of an IP expressed by a type (e.g. service.spec.ipFamilies). + type: string + type: array + x-kubernetes-list-type: atomic + ipFamilyPolicy: + description: |- + IPFamilyPolicy represents the dual-stack-ness requested or required by + this Service. If there is no value provided, then this field will be set + to SingleStack. Services can be "SingleStack" (a single IP family), + "PreferDualStack" (two IP families on dual-stack configured clusters or + a single IP family on single-stack clusters), or "RequireDualStack" + (two IP families on dual-stack configured clusters, otherwise fail). The + ipFamilies and clusterIPs fields depend on the value of this field. This + field will be wiped when updating a service to type ExternalName. + type: string + loadBalancerClass: + description: |- + loadBalancerClass is the class of the load balancer implementation this Service belongs to. + If specified, the value of this field must be a label-style identifier, with an optional prefix, + e.g. "internal-vip" or "example.com/internal-vip". Unprefixed names are reserved for end-users. + This field can only be set when the Service type is 'LoadBalancer'. If not set, the default load + balancer implementation is used, today this is typically done through the cloud provider integration, + but should apply for any default implementation. If set, it is assumed that a load balancer + implementation is watching for Services with a matching class. Any default load balancer + implementation (e.g. cloud providers) should ignore Services that set this field. + This field can only be set when creating or updating a Service to type 'LoadBalancer'. + Once set, it can not be changed. This field will be wiped when a service is updated to a non 'LoadBalancer' type. + type: string + loadBalancerIP: + description: |- + Only applies to Service Type: LoadBalancer. + This feature depends on whether the underlying cloud-provider supports specifying + the loadBalancerIP when a load balancer is created. + This field will be ignored if the cloud-provider does not support the feature. + Deprecated: This field was under-specified and its meaning varies across implementations. + Using it is non-portable and it may not support dual-stack. + Users are encouraged to use implementation-specific annotations when available. + type: string + loadBalancerSourceRanges: + description: |- + If specified and supported by the platform, this will restrict traffic through the cloud-provider + load-balancer will be restricted to the specified client IPs. This field will be ignored if the + cloud-provider does not support the feature." + More info: https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/ + items: + type: string + type: array + ports: + description: |- + The list of ports that are exposed by this service. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + items: + description: ServicePort contains information on service's + port. + properties: + appProtocol: + description: |- + The application protocol for this port. + This is used as a hint for implementations to offer richer behavior for protocols that they understand. + This field follows standard Kubernetes label syntax. + Valid values are either: + + + * Un-prefixed protocol names - reserved for IANA standard service names (as per + RFC-6335 and https://www.iana.org/assignments/service-names). + + + * Kubernetes-defined prefixed names: + * 'kubernetes.io/h2c' - HTTP/2 prior knowledge over cleartext as described in https://www.rfc-editor.org/rfc/rfc9113.html#name-starting-http-2-with-prior- + * 'kubernetes.io/ws' - WebSocket over cleartext as described in https://www.rfc-editor.org/rfc/rfc6455 + * 'kubernetes.io/wss' - WebSocket over TLS as described in https://www.rfc-editor.org/rfc/rfc6455 + + + * Other protocols should use implementation-defined prefixed names such as + mycompany.com/my-custom-protocol. + type: string + name: + description: |- + The name of this port within the service. This must be a DNS_LABEL. + All ports within a ServiceSpec must have unique names. When considering + the endpoints for a Service, this must match the 'name' field in the + EndpointPort. + Optional if only one ServicePort is defined on this service. + type: string + nodePort: + description: |- + The port on each node on which this service is exposed when type is + NodePort or LoadBalancer. Usually assigned by the system. If a value is + specified, in-range, and not in use it will be used, otherwise the + operation will fail. If not specified, a port will be allocated if this + Service requires one. If this field is specified when creating a + Service which does not need it, creation will fail. This field will be + wiped when updating a Service to no longer need it (e.g. changing type + from NodePort to ClusterIP). + More info: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport + format: int32 + type: integer + port: + description: The port that will be exposed by this + service. + format: int32 + type: integer + protocol: + default: TCP + description: |- + The IP protocol for this port. Supports "TCP", "UDP", and "SCTP". + Default is TCP. + type: string + targetPort: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the pods targeted by the service. + Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + If this is a string, it will be looked up as a named port in the + target Pod's container ports. If this is not specified, the value + of the 'port' field is used (an identity map). + This field is ignored for services with clusterIP=None, and should be + omitted or set equal to the 'port' field. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#defining-a-service + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-map-keys: + - port + - protocol + x-kubernetes-list-type: map + publishNotReadyAddresses: + description: |- + publishNotReadyAddresses indicates that any agent which deals with endpoints for this + Service should disregard any indications of ready/not-ready. + The primary use case for setting this field is for a StatefulSet's Headless Service to + propagate SRV DNS records for its Pods for the purpose of peer discovery. + The Kubernetes controllers that generate Endpoints and EndpointSlice resources for + Services interpret this to mean that all endpoints are considered "ready" even if the + Pods themselves are not. Agents which consume only Kubernetes generated endpoints + through the Endpoints or EndpointSlice resources can safely assume this behavior. + type: boolean + selector: + additionalProperties: + type: string + description: |- + Route service traffic to pods with label keys and values matching this + selector. If empty or not present, the service is assumed to have an + external process managing its endpoints, which Kubernetes will not + modify. Only applies to types ClusterIP, NodePort, and LoadBalancer. + Ignored if type is ExternalName. + More info: https://kubernetes.io/docs/concepts/services-networking/service/ + type: object + x-kubernetes-map-type: atomic + sessionAffinity: + description: |- + Supports "ClientIP" and "None". Used to maintain session affinity. + Enable client IP based session affinity. + Must be ClientIP or None. + Defaults to None. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + type: string + sessionAffinityConfig: + description: sessionAffinityConfig contains the configurations + of session affinity. + properties: + clientIP: + description: clientIP contains the configurations of + Client IP based session affinity. + properties: + timeoutSeconds: + description: |- + timeoutSeconds specifies the seconds of ClientIP type session sticky time. + The value must be >0 && <=86400(for 1 day) if ServiceAffinity == "ClientIP". + Default value is 10800(for 3 hours). + format: int32 + type: integer + type: object + type: object + type: + description: |- + type determines how the Service is exposed. Defaults to ClusterIP. Valid + options are ExternalName, ClusterIP, NodePort, and LoadBalancer. + "ClusterIP" allocates a cluster-internal IP address for load-balancing + to endpoints. Endpoints are determined by the selector or if that is not + specified, by manual construction of an Endpoints object or + EndpointSlice objects. If clusterIP is "None", no virtual IP is + allocated and the endpoints are published as a set of endpoints rather + than a virtual IP. + "NodePort" builds on ClusterIP and allocates a port on every node which + routes to the same endpoints as the clusterIP. + "LoadBalancer" builds on NodePort and creates an external load-balancer + (if supported in the current cloud) which routes to the same endpoints + as the clusterIP. + "ExternalName" aliases this service to the specified externalName. + Several other fields do not apply to ExternalName services. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types + type: string + type: object + required: + - name + type: object + type: array + systemAccounts: + description: |- + An array of `SystemAccount` objects that define the system accounts needed + for the management operations of the Component. + + + Each `SystemAccount` includes: + + + - Account name. + - The SQL statement template: Used to create the system account. + - Password Source: Either generated based on certain rules or retrieved from a Secret. + + + Use cases for system accounts typically involve tasks like system initialization, backups, monitoring, + health checks, replication, and other system-level operations. + + + System accounts are distinct from user accounts, although both are database accounts. + + + - **System Accounts**: Created during Cluster setup by the KubeBlocks operator, + these accounts have higher privileges for system management and are fully managed + through a declarative API by the operator. + - **User Accounts**: Managed by users or administrator. + User account permissions should follow the principle of least privilege, + granting only the necessary access rights to complete their required tasks. + + + This field is immutable. + items: + properties: + initAccount: + default: false + description: |- + Indicates if this account is a system initialization account (e.g., MySQL root). + + + This field is immutable once set. + type: boolean + name: + description: |- + Specifies the unique identifier for the account. This name is used by other entities to reference the account. + + + This field is immutable once set. + type: string + passwordGenerationPolicy: + description: |- + Specifies the policy for generating the account's password. + + + This field is immutable once set. + properties: + length: + default: 16 + description: The length of the password. + format: int32 + maximum: 32 + minimum: 8 + type: integer + letterCase: + default: MixedCases + description: The case of the letters in the password. + enum: + - LowerCases + - UpperCases + - MixedCases + type: string + numDigits: + default: 4 + description: The number of digits in the password. + format: int32 + maximum: 8 + minimum: 0 + type: integer + numSymbols: + default: 0 + description: The number of symbols in the password. + format: int32 + maximum: 8 + minimum: 0 + type: integer + seed: + description: |- + Seed to generate the account's password. + Cannot be updated. + type: string + type: object + secretRef: + description: |- + Refers to the secret from which data will be copied to create the new account. + + + This field is immutable once set. + properties: + name: + description: The unique identifier of the secret. + type: string + namespace: + description: The namespace where the secret is located. + type: string + required: + - name + - namespace + type: object + statement: + description: |- + Defines the statement used to create the account with the necessary privileges. + + + This field is immutable once set. + type: string + required: + - name + type: object + type: array + updateStrategy: + default: Serial + description: "Specifies the concurrency strategy for updating multiple + instances of the Component.\nAvailable strategies:\n\n\n- `Serial`: + Updates replicas one at a time, ensuring minimal downtime by waiting + for each replica to become ready\n before updating the next.\n- + `Parallel`: Updates all replicas simultaneously, optimizing for + speed but potentially reducing availability\n during the update.\n- + `BestEffortParallel`: Updates replicas concurrently with a limit + on simultaneous updates to ensure a minimum\n number of operational + replicas for maintaining quorum.\n\t For example, in a 5-replica + component, updating a maximum of 2 replicas simultaneously keeps\n\t + at least 3 operational for quorum.\n\n\nThis field is immutable + and defaults to 'Serial'." + enum: + - Serial + - BestEffortParallel + - Parallel + type: string + vars: + description: |- + Defines variables which are determined after Cluster instantiation and reflect + dynamic or runtime attributes of instantiated Clusters. + These variables serve as placeholders for setting environment variables in Pods and Actions, + or for rendering configuration and script templates before actual values are finalized. + + + These variables are placed in front of the environment variables declared in the Pod if used as + environment variables. + + + Variable values can be sourced from: + + + - ConfigMap: Select and extract a value from a specific key within a ConfigMap. + - Secret: Select and extract a value from a specific key within a Secret. + - HostNetwork: Retrieves values (including ports) from host-network resources. + - Service: Retrieves values (including address, port, NodePort) from a selected Service. + Intended to obtain the address of a ComponentService within the same Cluster. + - Credential: Retrieves account name and password from a SystemAccount variable. + - ServiceRef: Retrieves address, port, account name and password from a selected ServiceRefDeclaration. + Designed to obtain the address bound to a ServiceRef, such as a ClusterService or + ComponentService of another cluster or an external service. + - Component: Retrieves values from a selected Component, including replicas and instance name list. + + + This field is immutable. + items: + description: EnvVar represents a variable present in the env of + Pod/Action or the template of config/script. + properties: + expression: + description: |- + A Go template expression that will be applied to the resolved value of the var. + + + The expression will only be evaluated if the var is successfully resolved to a non-credential value. + + + The resolved value can be accessed by its name within the expression, system vars and other user-defined + non-credential vars can be used within the expression in the same way. + Notice that, when accessing vars by its name, you should replace all the "-" in the name with "_", because of + that "-" is not a valid identifier in Go. + + + All expressions are evaluated in the order the vars are defined. If a var depends on any vars that also + have expressions defined, be careful about the evaluation order as it may use intermediate values. + + + The result of evaluation will be used as the final value of the var. If the expression fails to evaluate, + the resolving of var will also be considered failed. + type: string + name: + description: Name of the variable. Must be a C_IDENTIFIER. + type: string + value: + description: |- + Variable references `$(VAR_NAME)` are expanded using the previously defined variables in the current context. + + + If a variable cannot be resolved, the reference in the input string will be unchanged. + Double `$$` are reduced to a single `$`, which allows for escaping the `$(VAR_NAME)` syntax: i.e. + + + - `$$(VAR_NAME)` will produce the string literal `$(VAR_NAME)`. + + + Escaped references will never be expanded, regardless of whether the variable exists or not. + Defaults to "". + type: string + valueFrom: + description: Source for the variable's value. Cannot be used + if value is not empty. + properties: + clusterVarRef: + description: Selects a defined var of a Cluster. + properties: + clusterName: + description: Reference to the name of the Cluster object. + enum: + - Required + - Optional + type: string + clusterUID: + description: Reference to the UID of the Cluster object. + enum: + - Required + - Optional + type: string + namespace: + description: Reference to the namespace of the Cluster + object. + enum: + - Required + - Optional + type: string + type: object + componentVarRef: + description: Selects a defined var of a Component. + properties: + compDef: + description: |- + CompDef specifies the definition used by the component that the referent object resident in. + If not specified, the component itself will be used. + type: string + componentName: + description: Reference to the name of the Component + object. + enum: + - Required + - Optional + type: string + multipleClusterObjectOption: + description: |- + This option defines the behavior when multiple component objects match the specified @CompDef. + If not provided, an error will be raised when handling multiple matches. + properties: + combinedOption: + description: |- + Define the options for handling combined variables. + Valid only when the strategy is set to "combined". + properties: + flattenFormat: + description: 'The flatten format, default is: + $(comp-name-1):value,$(comp-name-2):value.' + properties: + delimiter: + default: ',' + description: Pair delimiter. + type: string + keyValueDelimiter: + default: ':' + description: Key-value delimiter. + type: string + required: + - delimiter + - keyValueDelimiter + type: object + newVarSuffix: + description: |- + If set, the existing variable will be kept, and a new variable will be defined with the specified suffix + in pattern: $(var.name)_$(suffix). + The new variable will be auto-created and placed behind the existing one. + If not set, the existing variable will be reused with the value format defined below. + type: string + valueFormat: + default: Flatten + description: The format of the value that the + operator will use to compose values from multiple + components. + type: string + type: object + strategy: + description: Define the strategy for handling multiple + cluster objects. + enum: + - individual + - combined + type: string + required: + - strategy + type: object + name: + description: Name of the referent object. + type: string + optional: + description: Specify whether the object must be defined. + type: boolean + podFQDNs: + description: |- + Reference to the pod FQDN list of the component. + The value will be presented in the following format: FQDN1,FQDN2,... + enum: + - Required + - Optional + type: string + podFQDNsForRole: + description: |- + Reference to the pod FQDN list of the component that have a specific role. + The value will be presented in the following format: FQDN1,FQDN2,... + properties: + option: + description: VarOption defines whether a variable + is required or optional. + enum: + - Required + - Optional + type: string + role: + type: string + type: object + podNames: + description: |- + Reference to the pod name list of the component. + and the value will be presented in the following format: name1,name2,... + enum: + - Required + - Optional + type: string + podNamesForRole: + description: |- + Reference to the pod name list of the component that have a specific role. + The value will be presented in the following format: name1,name2,... + properties: + option: + description: VarOption defines whether a variable + is required or optional. + enum: + - Required + - Optional + type: string + role: + type: string + type: object + replicas: + description: Reference to the replicas of the component. + enum: + - Required + - Optional + type: string + shortName: + description: Reference to the short name of the Component + object. + enum: + - Required + - Optional + type: string + type: object + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + credentialVarRef: + description: Selects a defined var of a Credential (SystemAccount). + properties: + compDef: + description: |- + CompDef specifies the definition used by the component that the referent object resident in. + If not specified, the component itself will be used. + type: string + multipleClusterObjectOption: + description: |- + This option defines the behavior when multiple component objects match the specified @CompDef. + If not provided, an error will be raised when handling multiple matches. + properties: + combinedOption: + description: |- + Define the options for handling combined variables. + Valid only when the strategy is set to "combined". + properties: + flattenFormat: + description: 'The flatten format, default is: + $(comp-name-1):value,$(comp-name-2):value.' + properties: + delimiter: + default: ',' + description: Pair delimiter. + type: string + keyValueDelimiter: + default: ':' + description: Key-value delimiter. + type: string + required: + - delimiter + - keyValueDelimiter + type: object + newVarSuffix: + description: |- + If set, the existing variable will be kept, and a new variable will be defined with the specified suffix + in pattern: $(var.name)_$(suffix). + The new variable will be auto-created and placed behind the existing one. + If not set, the existing variable will be reused with the value format defined below. + type: string + valueFormat: + default: Flatten + description: The format of the value that the + operator will use to compose values from multiple + components. + type: string + type: object + strategy: + description: Define the strategy for handling multiple + cluster objects. + enum: + - individual + - combined + type: string + required: + - strategy + type: object + name: + description: Name of the referent object. + type: string + optional: + description: Specify whether the object must be defined. + type: boolean + password: + description: VarOption defines whether a variable is + required or optional. + enum: + - Required + - Optional + type: string + username: + description: VarOption defines whether a variable is + required or optional. + enum: + - Required + - Optional + type: string + type: object + hostNetworkVarRef: + description: Selects a defined var of host-network resources. + properties: + compDef: + description: |- + CompDef specifies the definition used by the component that the referent object resident in. + If not specified, the component itself will be used. + type: string + container: + description: ContainerVars defines the vars that can + be referenced from a Container. + properties: + name: + description: The name of the container. + type: string + port: + description: Container port to reference. + properties: + name: + type: string + option: + description: VarOption defines whether a variable + is required or optional. + enum: + - Required + - Optional + type: string + type: object + required: + - name + type: object + multipleClusterObjectOption: + description: |- + This option defines the behavior when multiple component objects match the specified @CompDef. + If not provided, an error will be raised when handling multiple matches. + properties: + combinedOption: + description: |- + Define the options for handling combined variables. + Valid only when the strategy is set to "combined". + properties: + flattenFormat: + description: 'The flatten format, default is: + $(comp-name-1):value,$(comp-name-2):value.' + properties: + delimiter: + default: ',' + description: Pair delimiter. + type: string + keyValueDelimiter: + default: ':' + description: Key-value delimiter. + type: string + required: + - delimiter + - keyValueDelimiter + type: object + newVarSuffix: + description: |- + If set, the existing variable will be kept, and a new variable will be defined with the specified suffix + in pattern: $(var.name)_$(suffix). + The new variable will be auto-created and placed behind the existing one. + If not set, the existing variable will be reused with the value format defined below. + type: string + valueFormat: + default: Flatten + description: The format of the value that the + operator will use to compose values from multiple + components. + type: string + type: object + strategy: + description: Define the strategy for handling multiple + cluster objects. + enum: + - individual + - combined + type: string + required: + - strategy + type: object + name: + description: Name of the referent object. + type: string + optional: + description: Specify whether the object must be defined. + type: boolean + type: object + secretKeyRef: + description: Selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must + be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + serviceRefVarRef: + description: Selects a defined var of a ServiceRef. + properties: + compDef: + description: |- + CompDef specifies the definition used by the component that the referent object resident in. + If not specified, the component itself will be used. + type: string + endpoint: + description: VarOption defines whether a variable is + required or optional. + enum: + - Required + - Optional + type: string + host: + description: VarOption defines whether a variable is + required or optional. + enum: + - Required + - Optional + type: string + multipleClusterObjectOption: + description: |- + This option defines the behavior when multiple component objects match the specified @CompDef. + If not provided, an error will be raised when handling multiple matches. + properties: + combinedOption: + description: |- + Define the options for handling combined variables. + Valid only when the strategy is set to "combined". + properties: + flattenFormat: + description: 'The flatten format, default is: + $(comp-name-1):value,$(comp-name-2):value.' + properties: + delimiter: + default: ',' + description: Pair delimiter. + type: string + keyValueDelimiter: + default: ':' + description: Key-value delimiter. + type: string + required: + - delimiter + - keyValueDelimiter + type: object + newVarSuffix: + description: |- + If set, the existing variable will be kept, and a new variable will be defined with the specified suffix + in pattern: $(var.name)_$(suffix). + The new variable will be auto-created and placed behind the existing one. + If not set, the existing variable will be reused with the value format defined below. + type: string + valueFormat: + default: Flatten + description: The format of the value that the + operator will use to compose values from multiple + components. + type: string + type: object + strategy: + description: Define the strategy for handling multiple + cluster objects. + enum: + - individual + - combined + type: string + required: + - strategy + type: object + name: + description: Name of the referent object. + type: string + optional: + description: Specify whether the object must be defined. + type: boolean + password: + description: VarOption defines whether a variable is + required or optional. + enum: + - Required + - Optional + type: string + port: + description: VarOption defines whether a variable is + required or optional. + enum: + - Required + - Optional + type: string + username: + description: VarOption defines whether a variable is + required or optional. + enum: + - Required + - Optional + type: string + type: object + serviceVarRef: + description: Selects a defined var of a Service. + properties: + compDef: + description: |- + CompDef specifies the definition used by the component that the referent object resident in. + If not specified, the component itself will be used. + type: string + host: + description: VarOption defines whether a variable is + required or optional. + enum: + - Required + - Optional + type: string + loadBalancer: + description: |- + LoadBalancer represents the LoadBalancer ingress point of the service. + + + If multiple ingress points are available, the first one will be used automatically, choosing between IP and Hostname. + enum: + - Required + - Optional + type: string + multipleClusterObjectOption: + description: |- + This option defines the behavior when multiple component objects match the specified @CompDef. + If not provided, an error will be raised when handling multiple matches. + properties: + combinedOption: + description: |- + Define the options for handling combined variables. + Valid only when the strategy is set to "combined". + properties: + flattenFormat: + description: 'The flatten format, default is: + $(comp-name-1):value,$(comp-name-2):value.' + properties: + delimiter: + default: ',' + description: Pair delimiter. + type: string + keyValueDelimiter: + default: ':' + description: Key-value delimiter. + type: string + required: + - delimiter + - keyValueDelimiter + type: object + newVarSuffix: + description: |- + If set, the existing variable will be kept, and a new variable will be defined with the specified suffix + in pattern: $(var.name)_$(suffix). + The new variable will be auto-created and placed behind the existing one. + If not set, the existing variable will be reused with the value format defined below. + type: string + valueFormat: + default: Flatten + description: The format of the value that the + operator will use to compose values from multiple + components. + type: string + type: object + strategy: + description: Define the strategy for handling multiple + cluster objects. + enum: + - individual + - combined + type: string + required: + - strategy + type: object + name: + description: Name of the referent object. + type: string + optional: + description: Specify whether the object must be defined. + type: boolean + port: + description: |- + Port references a port or node-port defined in the service. + + + If the referenced service is a pod-service, there will be multiple service objects matched, + and the value will be presented in the following format: service1.name:port1,service2.name:port2... + properties: + name: + type: string + option: + description: VarOption defines whether a variable + is required or optional. + enum: + - Required + - Optional + type: string + type: object + serviceType: + description: ServiceType references the type of the + service. + enum: + - Required + - Optional + type: string + type: object + type: object + required: + - name + type: object + type: array + volumes: + description: |- + Defines the volumes used by the Component and some static attributes of the volumes. + After defining the volumes here, user can reference them in the + `cluster.spec.componentSpecs[*].volumeClaimTemplates` field to configure dynamic properties such as + volume capacity and storage class. + + + This field allows you to specify the following: + + + - Snapshot behavior: Determines whether a snapshot of the volume should be taken when performing + a snapshot backup of the Component. + - Disk high watermark: Sets the high watermark for the volume's disk usage. + When the disk usage reaches the specified threshold, it triggers an alert or action. + + + By configuring these volume behaviors, you can control how the volumes are managed and monitored within the Component. + + + This field is immutable. + items: + properties: + highWatermark: + default: 0 + description: |- + Sets the critical threshold for volume space utilization as a percentage (0-100). + + + Exceeding this percentage triggers the system to switch the volume to read-only mode as specified in + `componentDefinition.spec.lifecycleActions.readOnly`. + This precaution helps prevent space depletion while maintaining read-only access. + If the space utilization later falls below this threshold, the system reverts the volume to read-write mode + as defined in `componentDefinition.spec.lifecycleActions.readWrite`, restoring full functionality. + + + Note: This field cannot be updated. + maximum: 100 + minimum: 0 + type: integer + name: + description: |- + Specifies the name of the volume. + It must be a DNS_LABEL and unique within the pod. + More info can be found at: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + Note: This field cannot be updated. + type: string + needSnapshot: + default: false + description: |- + Specifies whether the creation of a snapshot of this volume is necessary when performing a backup of the Component. + + + Note: This field cannot be updated. + type: boolean + required: + - name + type: object + type: array + required: + - runtime type: object status: - description: ComponentDefinitionStatus defines the observed state of ComponentDefinition + description: ComponentDefinitionStatus defines the observed state of ComponentDefinition. + properties: + message: + description: Provides additional information about the current phase. + type: string + observedGeneration: + description: Refers to the most recent generation that has been observed + for the ComponentDefinition. + format: int64 + type: integer + phase: + description: |- + Represents the current status of the ComponentDefinition. Valid values include ``, `Available`, and `Unavailable`. + When the status is `Available`, the ComponentDefinition is ready and can be utilized by related objects. + enum: + - Available + - Unavailable + type: string type: object type: object served: true diff --git a/deploy/helm/crds/apps.kubeblocks.io_components.yaml b/deploy/helm/crds/apps.kubeblocks.io_components.yaml index 1aade3253e2..eec88d35964 100644 --- a/deploy/helm/crds/apps.kubeblocks.io_components.yaml +++ b/deploy/helm/crds/apps.kubeblocks.io_components.yaml @@ -75,13 +75,7434 @@ spec: spec: description: ComponentSpec defines the desired state of Component properties: - foo: - description: Foo is an example field of Component. Edit component_types.go - to remove/update + annotations: + additionalProperties: + type: string + description: Specifies Annotations to override or add for underlying + Pods. + type: object + compDef: + description: Specifies the name of the referenced ComponentDefinition. + maxLength: 64 type: string + configs: + description: Specifies the configuration content of a config template. + items: + description: ClusterComponentConfig represents a config with its + source bound. + properties: + configMap: + description: ConfigMap source for the config. + properties: + defaultMode: + description: |- + defaultMode is optional: mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + items: + description: |- + items if unspecified, each key-value pair in the Data field of the referenced + ConfigMap will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the ConfigMap, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + 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 + optional: + description: optional specify whether the ConfigMap or its + keys must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + name: + description: The name of the config. + type: string + type: object + type: array + disableExporter: + description: |- + Determines whether metrics exporter information is annotated on the Component's headless Service. + + + If set to true, the following annotations will not be patched into the Service: + + + - "monitor.kubeblocks.io/path" + - "monitor.kubeblocks.io/port" + - "monitor.kubeblocks.io/scheme" + + + These annotations allow the Prometheus installed by KubeBlocks to discover and scrape metrics from the exporter. + type: boolean + enabledLogs: + description: |- + Specifies which types of logs should be collected for the Cluster. + The log types are defined in the `componentDefinition.spec.logConfigs` field with the LogConfig entries. + + + The elements in the `enabledLogs` array correspond to the names of the LogConfig entries. + For example, if the `componentDefinition.spec.logConfigs` defines LogConfig entries with + names "slow_query_log" and "error_log", + you can enable the collection of these logs by including their names in the `enabledLogs` array: + ```yaml + enabledLogs: + - slow_query_log + - error_log + ``` + items: + type: string + type: array + x-kubernetes-list-type: set + env: + description: List of environment variables to add. + items: + description: EnvVar represents an environment variable present in + a Container. + properties: + name: + description: Name of the environment variable. Must be a C_IDENTIFIER. + type: string + value: + description: |- + Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in the container and + any service environment variables. If a variable cannot be resolved, + the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless of whether the variable + exists or not. + Defaults to "". + type: string + valueFrom: + description: Source for the environment variable's value. Cannot + be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the FieldPath is + written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the specified + API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the exposed + resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in the pod's namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must + be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + instances: + description: |- + Allows for the customization of configuration values for each instance within a Component. + An Instance represent a single replica (Pod and associated K8s resources like PVCs, Services, and ConfigMaps). + While instances typically share a common configuration as defined in the ClusterComponentSpec, + they can require unique settings in various scenarios: + + + For example: + - A database Component might require different resource allocations for primary and secondary instances, + with primaries needing more resources. + - During a rolling upgrade, a Component may first update the image for one or a few instances, + and then update the remaining instances after verifying that the updated instances are functioning correctly. + + + InstanceTemplate allows for specifying these unique configurations per instance. + Each instance's name is constructed using the pattern: $(component.name)-$(template.name)-$(ordinal), + starting with an ordinal of 0. + It is crucial to maintain unique names for each InstanceTemplate to avoid conflicts. + + + The sum of replicas across all InstanceTemplates should not exceed the total number of Replicas specified for the Component. + Any remaining replicas will be generated using the default template and will follow the default naming rules. + items: + description: InstanceTemplate allows customization of individual + replica configurations in a Component. + properties: + annotations: + additionalProperties: + type: string + description: |- + Specifies a map of key-value pairs to be merged into the Pod's existing annotations. + Existing keys will have their values overwritten, while new keys will be added to the annotations. + type: object + env: + description: |- + Defines Env to override. + Add new or override existing envs. + items: + description: EnvVar represents an environment variable present + in a Container. + properties: + name: + description: Name of the environment variable. Must be + a C_IDENTIFIER. + type: string + value: + description: |- + Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in the container and + any service environment variables. If a variable cannot be resolved, + the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless of whether the variable + exists or not. + Defaults to "". + type: string + valueFrom: + description: Source for the environment variable's value. + Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap or + its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the + specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the + exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in the pod's + namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its + key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + image: + description: Specifies an override for the first container's + image in the Pod. + type: string + labels: + additionalProperties: + type: string + description: |- + Specifies a map of key-value pairs that will be merged into the Pod's existing labels. + Values for existing keys will be overwritten, and new keys will be added. + type: object + name: + description: |- + Name specifies the unique name of the instance Pod created using this InstanceTemplate. + This name is constructed by concatenating the Component's name, the template's name, and the instance's ordinal + using the pattern: $(cluster.name)-$(component.name)-$(template.name)-$(ordinal). Ordinals start from 0. + The specified name overrides any default naming conventions or patterns. + maxLength: 54 + pattern: ^[a-z0-9]([a-z0-9\.\-]*[a-z0-9])?$ + type: string + replicas: + default: 1 + description: |- + Specifies the number of instances (Pods) to create from this InstanceTemplate. + This field allows setting how many replicated instances of the Component, + with the specific overrides in the InstanceTemplate, are created. + The default value is 1. A value of 0 disables instance creation. + format: int32 + minimum: 0 + type: integer + resources: + description: |- + Specifies an override for the resource requirements of the first container in the Pod. + This field allows for customizing resource allocation (CPU, memory, etc.) for the container. + properties: + claims: + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + + + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + + + This field is immutable. It can only be set for containers. + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + schedulingPolicy: + description: Specifies the scheduling policy for the Component. + properties: + affinity: + description: Specifies a group of affinity scheduling rules + of the Cluster, including NodeAffinity, PodAffinity, and + PodAntiAffinity. + properties: + nodeAffinity: + description: Describes node affinity scheduling rules + for the pod. + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node matches the corresponding matchExpressions; the + node(s) with the highest sum are the most preferred. + items: + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). + properties: + preference: + description: A node selector term, associated + with the corresponding weight. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that + the selector applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that + the selector applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + weight: + description: Weight associated with matching + the corresponding nodeSelectorTerm, in the + range 1-100. + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. + properties: + nodeSelectorTerms: + description: Required. A list of node selector + terms. The terms are ORed. + items: + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that + the selector applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that + the selector applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + type: array + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + description: Describes pod affinity scheduling rules + (e.g. co-locate this pod in the same node, zone, etc. + as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched + WeightedPodAffinityTerm fields are added per-node + to find the most preferred node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, + associated with the corresponding weight. + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a + list of label selector requirements. + The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. + Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a + list of label selector requirements. + The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: |- + weight associated with matching the corresponding podAffinityTerm, + in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. + items: + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. + Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + description: Describes pod anti-affinity scheduling + rules (e.g. avoid putting this pod in the same node, + zone, etc. as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the anti-affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched + WeightedPodAffinityTerm fields are added per-node + to find the most preferred node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, + associated with the corresponding weight. + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a + list of label selector requirements. + The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. + Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a + list of label selector requirements. + The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: |- + weight associated with matching the corresponding podAffinityTerm, + in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the anti-affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the anti-affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. + items: + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. + Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + nodeName: + description: |- + NodeName is a request to schedule this Pod onto a specific node. If it is non-empty, + the scheduler simply schedules this Pod onto that node, assuming that it fits resource + requirements. + type: string + nodeSelector: + additionalProperties: + type: string + description: |- + NodeSelector is a selector which must be true for the Pod to fit on a node. + Selector which must match a node's labels for the Pod to be scheduled on that node. + More info: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ + type: object + x-kubernetes-map-type: atomic + schedulerName: + description: |- + If specified, the Pod will be dispatched by specified scheduler. + If not specified, the Pod will be dispatched by default scheduler. + type: string + tolerations: + description: |- + Allows Pods to be scheduled onto nodes with matching taints. + Each toleration in the array allows the Pod to tolerate node taints based on + specified `key`, `value`, `effect`, and `operator`. + + + - The `key`, `value`, and `effect` identify the taint that the toleration matches. + - The `operator` determines how the toleration matches the taint. + + + Pods with matching tolerations are allowed to be scheduled on tainted nodes, typically reserved for specific purposes. + items: + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . + properties: + effect: + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. + type: string + operator: + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. + type: string + tolerationSeconds: + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. + format: int64 + type: integer + value: + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. + type: string + type: object + type: array + topologySpreadConstraints: + description: |- + TopologySpreadConstraints describes how a group of Pods ought to spread across topology + domains. Scheduler will schedule Pods in a way which abides by the constraints. + All topologySpreadConstraints are ANDed. + items: + description: TopologySpreadConstraint specifies how to + spread matching pods among the given topology. + properties: + labelSelector: + description: |- + LabelSelector is used to find matching pods. + Pods that match this label selector are counted to determine the number of pods + in their corresponding topology domain. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select the pods over which + spreading will be calculated. The keys are used to lookup values from the + incoming pod labels, those key-value labels are ANDed with labelSelector + to select the group of existing pods over which spreading will be calculated + for the incoming pod. The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + MatchLabelKeys cannot be set when LabelSelector isn't set. + Keys that don't exist in the incoming pod labels will + be ignored. A null or empty list means only match against labelSelector. + + + This is a beta field and requires the MatchLabelKeysInPodTopologySpread feature gate to be enabled (enabled by default). + items: + type: string + type: array + x-kubernetes-list-type: atomic + maxSkew: + description: |- + MaxSkew describes the degree to which pods may be unevenly distributed. + When `whenUnsatisfiable=DoNotSchedule`, it is the maximum permitted difference + between the number of matching pods in the target topology and the global minimum. + The global minimum is the minimum number of matching pods in an eligible domain + or zero if the number of eligible domains is less than MinDomains. + For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same + labelSelector spread as 2/2/1: + In this case, the global minimum is 1. + | zone1 | zone2 | zone3 | + | P P | P P | P | + - if MaxSkew is 1, incoming pod can only be scheduled to zone3 to become 2/2/2; + scheduling it onto zone1(zone2) would make the ActualSkew(3-1) on zone1(zone2) + violate MaxSkew(1). + - if MaxSkew is 2, incoming pod can be scheduled onto any zone. + When `whenUnsatisfiable=ScheduleAnyway`, it is used to give higher precedence + to topologies that satisfy it. + It's a required field. Default value is 1 and 0 is not allowed. + format: int32 + type: integer + minDomains: + description: |- + MinDomains indicates a minimum number of eligible domains. + When the number of eligible domains with matching topology keys is less than minDomains, + Pod Topology Spread treats "global minimum" as 0, and then the calculation of Skew is performed. + And when the number of eligible domains with matching topology keys equals or greater than minDomains, + this value has no effect on scheduling. + As a result, when the number of eligible domains is less than minDomains, + scheduler won't schedule more than maxSkew Pods to those domains. + If value is nil, the constraint behaves as if MinDomains is equal to 1. + Valid values are integers greater than 0. + When value is not nil, WhenUnsatisfiable must be DoNotSchedule. + + + For example, in a 3-zone cluster, MaxSkew is set to 2, MinDomains is set to 5 and pods with the same + labelSelector spread as 2/2/2: + | zone1 | zone2 | zone3 | + | P P | P P | P P | + The number of domains is less than 5(MinDomains), so "global minimum" is treated as 0. + In this situation, new pod with the same labelSelector cannot be scheduled, + because computed skew will be 3(3 - 0) if new Pod is scheduled to any of the three zones, + it will violate MaxSkew. + + + This is a beta field and requires the MinDomainsInPodTopologySpread feature gate to be enabled (enabled by default). + format: int32 + type: integer + nodeAffinityPolicy: + description: |- + NodeAffinityPolicy indicates how we will treat Pod's nodeAffinity/nodeSelector + when calculating pod topology spread skew. Options are: + - Honor: only nodes matching nodeAffinity/nodeSelector are included in the calculations. + - Ignore: nodeAffinity/nodeSelector are ignored. All nodes are included in the calculations. + + + If this value is nil, the behavior is equivalent to the Honor policy. + This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag. + type: string + nodeTaintsPolicy: + description: |- + NodeTaintsPolicy indicates how we will treat node taints when calculating + pod topology spread skew. Options are: + - Honor: nodes without taints, along with tainted nodes for which the incoming pod + has a toleration, are included. + - Ignore: node taints are ignored. All nodes are included. + + + If this value is nil, the behavior is equivalent to the Ignore policy. + This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag. + type: string + topologyKey: + description: |- + TopologyKey is the key of node labels. Nodes that have a label with this key + and identical values are considered to be in the same topology. + We consider each as a "bucket", and try to put balanced number + of pods into each bucket. + We define a domain as a particular instance of a topology. + Also, we define an eligible domain as a domain whose nodes meet the requirements of + nodeAffinityPolicy and nodeTaintsPolicy. + e.g. If TopologyKey is "kubernetes.io/hostname", each Node is a domain of that topology. + And, if TopologyKey is "topology.kubernetes.io/zone", each zone is a domain of that topology. + It's a required field. + type: string + whenUnsatisfiable: + description: |- + WhenUnsatisfiable indicates how to deal with a pod if it doesn't satisfy + the spread constraint. + - DoNotSchedule (default) tells the scheduler not to schedule it. + - ScheduleAnyway tells the scheduler to schedule the pod in any location, + but giving higher precedence to topologies that would help reduce the + skew. + A constraint is considered "Unsatisfiable" for an incoming pod + if and only if every possible node assignment for that pod would violate + "MaxSkew" on some topology. + For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same + labelSelector spread as 3/1/1: + | zone1 | zone2 | zone3 | + | P P P | P | P | + If WhenUnsatisfiable is set to DoNotSchedule, incoming pod can only be scheduled + to zone2(zone3) to become 3/2/1(3/1/2) as ActualSkew(2-1) on zone2(zone3) satisfies + MaxSkew(1). In other words, the cluster can still be imbalanced, but scheduler + won't make it *more* imbalanced. + It's a required field. + type: string + required: + - maxSkew + - topologyKey + - whenUnsatisfiable + type: object + type: array + type: object + volumeClaimTemplates: + description: |- + Defines VolumeClaimTemplates to override. + Add new or override existing volume claim templates. + items: + properties: + name: + description: |- + Refers to the name of a volumeMount defined in either: + + + - `componentDefinition.spec.runtime.containers[*].volumeMounts` + - `clusterDefinition.spec.componentDefs[*].podSpec.containers[*].volumeMounts` (deprecated) + + + The value of `name` must match the `name` field of a volumeMount specified in the corresponding `volumeMounts` array. + type: string + spec: + description: |- + Defines the desired characteristics of a PersistentVolumeClaim that will be created for the volume + with the mount name specified in the `name` field. + + + When a Pod is created for this ClusterComponent, a new PVC will be created based on the specification + defined in the `spec` field. The PVC will be associated with the volume mount specified by the `name` field. + properties: + accessModes: + description: |- + Contains the desired access modes the volume should have. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1. + items: + type: string + type: array + x-kubernetes-preserve-unknown-fields: true + resources: + description: |- + Represents the minimum resources the volume should have. + If the RecoverVolumeExpansionFailure feature is enabled, users are allowed to specify resource requirements that + are lower than the previous value but must still be higher than the capacity recorded in the status field of the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources. + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + x-kubernetes-preserve-unknown-fields: true + storageClassName: + description: |- + The name of the StorageClass required by the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1. + type: string + volumeMode: + description: Defines what type of volume is required + by the claim, either Block or Filesystem. + type: string + type: object + required: + - name + type: object + type: array + volumeMounts: + description: |- + Defines VolumeMounts to override. + Add new or override existing volume mounts of the first container in the Pod. + items: + description: VolumeMount describes a mounting of a Volume + within a container. + properties: + mountPath: + description: |- + Path within the container at which the volume should be mounted. Must + not contain ':'. + type: string + mountPropagation: + description: |- + mountPropagation determines how mounts are propagated from the host + to container and the other way around. + When not set, MountPropagationNone is used. + This field is beta in 1.10. + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: |- + Mounted read-only if true, read-write otherwise (false or unspecified). + Defaults to false. + type: boolean + subPath: + description: |- + Path within the volume from which the container's volume should be mounted. + Defaults to "" (volume's root). + type: string + subPathExpr: + description: |- + Expanded path within the volume from which the container's volume should be mounted. + Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment. + Defaults to "" (volume's root). + SubPathExpr and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + volumes: + description: |- + Defines Volumes to override. + Add new or override existing volumes. + items: + description: Volume represents a named volume in a pod that + may be accessed by any container in the pod. + properties: + awsElasticBlockStore: + description: |- + awsElasticBlockStore represents an AWS Disk resource that is attached to a + kubelet's host machine and then exposed to the pod. + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + properties: + fsType: + description: |- + fsType is the filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + partition: + description: |- + partition is the partition in the volume that you want to mount. + If omitted, the default is to mount by volume name. + Examples: For volume /dev/sda1, you specify the partition as "1". + Similarly, the volume partition for /dev/sda is "0" (or you can leave the property empty). + format: int32 + type: integer + readOnly: + description: |- + readOnly value true will force the readOnly setting in VolumeMounts. + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + type: boolean + volumeID: + description: |- + volumeID is unique ID of the persistent disk resource in AWS (Amazon EBS volume). + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + type: string + required: + - volumeID + type: object + azureDisk: + description: azureDisk represents an Azure Data Disk mount + on the host and bind mount to the pod. + properties: + cachingMode: + description: 'cachingMode is the Host Caching mode: + None, Read Only, Read Write.' + type: string + diskName: + description: diskName is the Name of the data disk + in the blob storage + type: string + diskURI: + description: diskURI is the URI of data disk in the + blob storage + type: string + fsType: + description: |- + fsType is Filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + kind: + description: 'kind expected values are Shared: multiple + blob disks per storage account Dedicated: single + blob disk per storage account Managed: azure managed + data disk (only in managed availability set). defaults + to shared' + type: string + readOnly: + description: |- + readOnly Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + description: azureFile represents an Azure File Service + mount on the host and bind mount to the pod. + properties: + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretName: + description: secretName is the name of secret that + contains Azure Storage Account Name and Key + type: string + shareName: + description: shareName is the azure share Name + type: string + required: + - secretName + - shareName + type: object + cephfs: + description: cephFS represents a Ceph FS mount on the + host that shares a pod's lifetime + properties: + monitors: + description: |- + monitors is Required: Monitors is a collection of Ceph monitors + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + items: + type: string + type: array + path: + description: 'path is Optional: Used as the mounted + root, rather than the full Ceph tree, default is + /' + type: string + readOnly: + description: |- + readOnly is Optional: Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + type: boolean + secretFile: + description: |- + secretFile is Optional: SecretFile is the path to key ring for User, default is /etc/ceph/user.secret + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + type: string + secretRef: + description: |- + secretRef is Optional: SecretRef is reference to the authentication secret for User, default is empty. + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + 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 + user: + description: |- + user is optional: User is the rados user name, default is admin + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + type: string + required: + - monitors + type: object + cinder: + description: |- + cinder represents a cinder volume attached and mounted on kubelets host machine. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + type: string + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + type: boolean + secretRef: + description: |- + secretRef is optional: points to a secret object containing parameters used to connect + to OpenStack. + 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 + volumeID: + description: |- + volumeID used to identify the volume in cinder. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + type: string + required: + - volumeID + type: object + configMap: + description: configMap represents a configMap that should + populate this volume + properties: + defaultMode: + description: |- + defaultMode is optional: mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + items: + description: |- + items if unspecified, each key-value pair in the Data field of the referenced + ConfigMap will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the ConfigMap, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within + a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + 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 + optional: + description: optional specify whether the ConfigMap + or its keys must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + csi: + description: csi (Container Storage Interface) represents + ephemeral storage that is handled by certain external + CSI drivers (Beta feature). + properties: + driver: + description: |- + driver is the name of the CSI driver that handles this volume. + Consult with your admin for the correct name as registered in the cluster. + type: string + fsType: + description: |- + fsType to mount. Ex. "ext4", "xfs", "ntfs". + If not provided, the empty value is passed to the associated CSI driver + which will determine the default filesystem to apply. + type: string + nodePublishSecretRef: + description: |- + nodePublishSecretRef is a reference to the secret object containing + sensitive information to pass to the CSI driver to complete the CSI + NodePublishVolume and NodeUnpublishVolume calls. + This field is optional, and may be empty if no secret is required. If the + secret object contains more than one secret, all secret references are passed. + 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 + readOnly: + description: |- + readOnly specifies a read-only configuration for the volume. + Defaults to false (read/write). + type: boolean + volumeAttributes: + additionalProperties: + type: string + description: |- + volumeAttributes stores driver-specific properties that are passed to the CSI + driver. Consult your driver's documentation for supported values. + type: object + required: + - driver + type: object + downwardAPI: + description: downwardAPI represents downward API about + the pod that should populate this volume + properties: + defaultMode: + description: |- + Optional: mode bits to use on created files by default. Must be a + Optional: mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + items: + description: Items is a list of downward API volume + file + items: + description: DownwardAPIVolumeFile represents information + to create the file containing the pod field + properties: + fieldRef: + description: 'Required: Selects a field of the + pod: only annotations, labels, name and namespace + are supported.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select + in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + description: |- + Optional: mode bits used to set permissions on this file, must be an octal value + between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: 'Required: Path is the relative + path name of the file to be created. Must + not be absolute or contain the ''..'' path. + Must be utf-8 encoded. The first item of the + relative path must not start with ''..''' + type: string + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported. + properties: + containerName: + description: 'Container name: required for + volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format + of the exposed resources, defaults to + "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + type: object + emptyDir: + description: |- + emptyDir represents a temporary directory that shares a pod's lifetime. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir + properties: + medium: + description: |- + medium represents what type of storage medium should back this directory. + The default is "" which means to use the node's default medium. + Must be an empty string (default) or Memory. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + description: |- + sizeLimit is the total amount of local storage required for this EmptyDir volume. + The size limit is also applicable for memory medium. + The maximum usage on memory medium EmptyDir would be the minimum value between + the SizeLimit specified here and the sum of memory limits of all containers in a pod. + The default is nil which means that the limit is undefined. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + description: |- + ephemeral represents a volume that is handled by a cluster storage driver. + The volume's lifecycle is tied to the pod that defines it - it will be created before the pod starts, + and deleted when the pod is removed. + + + Use this if: + a) the volume is only needed while the pod runs, + b) features of normal volumes like restoring from snapshot or capacity + tracking are needed, + c) the storage driver is specified through a storage class, and + d) the storage driver supports dynamic volume provisioning through + a PersistentVolumeClaim (see EphemeralVolumeSource for more + information on the connection between this volume type + and PersistentVolumeClaim). + + + Use PersistentVolumeClaim or one of the vendor-specific + APIs for volumes that persist for longer than the lifecycle + of an individual pod. + + + Use CSI for light-weight local ephemeral volumes if the CSI driver is meant to + be used that way - see the documentation of the driver for + more information. + + + A pod can use both types of ephemeral volumes and + persistent volumes at the same time. + properties: + volumeClaimTemplate: + description: |- + Will be used to create a stand-alone PVC to provision the volume. + The pod in which this EphemeralVolumeSource is embedded will be the + owner of the PVC, i.e. the PVC will be deleted together with the + pod. The name of the PVC will be `-` where + `` is the name from the `PodSpec.Volumes` array + entry. Pod validation will reject the pod if the concatenated name + is not valid for a PVC (for example, too long). + + + An existing PVC with that name that is not owned by the pod + will *not* be used for the pod to avoid using an unrelated + volume by mistake. Starting the pod is then blocked until + the unrelated PVC is removed. If such a pre-created PVC is + meant to be used by the pod, the PVC has to updated with an + owner reference to the pod once the pod exists. Normally + this should not be necessary, but it may be useful when + manually reconstructing a broken cluster. + + + This field is read-only and no changes will be made by Kubernetes + to the PVC after it has been created. + + + Required, must not be nil. + properties: + metadata: + description: |- + May contain labels and annotations that will be copied into the PVC + when creating it. No other fields are allowed and will be rejected during + validation. + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + description: |- + The specification for the PersistentVolumeClaim. The entire content is + copied unchanged into the PVC that gets created from this + template. The same fields as in a PersistentVolumeClaim + are also valid here. + properties: + accessModes: + description: |- + accessModes contains the desired access modes the volume should have. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1 + items: + type: string + type: array + dataSource: + description: |- + dataSource field can be used to specify either: + * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) + * An existing PVC (PersistentVolumeClaim) + If the provisioner or an external controller can support the specified data source, + it will create a new volume based on the contents of the specified data source. + When the AnyVolumeDataSource feature gate is enabled, dataSource contents will be copied to dataSourceRef, + and dataSourceRef contents will be copied to dataSource when dataSourceRef.namespace is not specified. + If the namespace is specified, then dataSourceRef will not be copied to dataSource. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource + being referenced + type: string + name: + description: Name is the name of resource + being referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + description: |- + dataSourceRef specifies the object from which to populate the volume with data, if a non-empty + volume is desired. This may be any object from a non-empty API group (non + core object) or a PersistentVolumeClaim object. + When this field is specified, volume binding will only succeed if the type of + the specified object matches some installed volume populator or dynamic + provisioner. + This field will replace the functionality of the dataSource field and as such + if both fields are non-empty, they must have the same value. For backwards + compatibility, when namespace isn't specified in dataSourceRef, + both fields (dataSource and dataSourceRef) will be set to the same + value automatically if one of them is empty and the other is non-empty. + When namespace is specified in dataSourceRef, + dataSource isn't set to the same value and must be empty. + There are three important differences between dataSource and dataSourceRef: + * While dataSource only allows two specific types of objects, dataSourceRef + allows any non-core object, as well as PersistentVolumeClaim objects. + * While dataSource ignores disallowed values (dropping them), dataSourceRef + preserves all values, and generates an error if a disallowed value is + specified. + * While dataSource only allows local objects, dataSourceRef allows objects + in any namespaces. + (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled. + (Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource + being referenced + type: string + name: + description: Name is the name of resource + being referenced + type: string + namespace: + description: |- + Namespace is the namespace of resource being referenced + Note that when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details. + (Alpha) This field requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + type: string + required: + - kind + - name + type: object + resources: + description: |- + resources represents the minimum resources the volume should have. + If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements + that are lower than previous value but must still be higher than capacity recorded in the + status field of the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + selector: + description: selector is a label query over + volumes to consider for binding. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + description: |- + storageClassName is the name of the StorageClass required by the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1 + type: string + volumeAttributesClassName: + description: |- + volumeAttributesClassName may be used to set the VolumeAttributesClass used by this claim. + If specified, the CSI driver will create or update the volume with the attributes defined + in the corresponding VolumeAttributesClass. This has a different purpose than storageClassName, + it can be changed after the claim is created. An empty string value means that no VolumeAttributesClass + will be applied to the claim but it's not allowed to reset this field to empty string once it is set. + If unspecified and the PersistentVolumeClaim is unbound, the default VolumeAttributesClass + will be set by the persistentvolume controller if it exists. + If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be + set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource + exists. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#volumeattributesclass + (Alpha) Using this field requires the VolumeAttributesClass feature gate to be enabled. + type: string + volumeMode: + description: |- + volumeMode defines what type of volume is required by the claim. + Value of Filesystem is implied when not included in claim spec. + type: string + volumeName: + description: volumeName is the binding reference + to the PersistentVolume backing this claim. + type: string + type: object + required: + - spec + type: object + type: object + fc: + description: fc represents a Fibre Channel resource that + is attached to a kubelet's host machine and then exposed + to the pod. + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + lun: + description: 'lun is Optional: FC target lun number' + format: int32 + type: integer + readOnly: + description: |- + readOnly is Optional: Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + targetWWNs: + description: 'targetWWNs is Optional: FC target worldwide + names (WWNs)' + items: + type: string + type: array + wwids: + description: |- + wwids Optional: FC volume world wide identifiers (wwids) + Either wwids or combination of targetWWNs and lun must be set, but not both simultaneously. + items: + type: string + type: array + type: object + flexVolume: + description: |- + flexVolume represents a generic volume resource that is + provisioned/attached using an exec based plugin. + properties: + driver: + description: driver is the name of the driver to use + for this volume. + type: string + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". The default filesystem depends on FlexVolume script. + type: string + options: + additionalProperties: + type: string + description: 'options is Optional: this field holds + extra command options if any.' + type: object + readOnly: + description: |- + readOnly is Optional: defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: |- + secretRef is Optional: secretRef is reference to the secret object containing + sensitive information to pass to the plugin scripts. This may be + empty if no secret object is specified. If the secret object + contains more than one secret, all secrets are passed to the plugin + scripts. + 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 + required: + - driver + type: object + flocker: + description: flocker represents a Flocker volume attached + to a kubelet's host machine. This depends on the Flocker + control service being running + properties: + datasetName: + description: |- + datasetName is Name of the dataset stored as metadata -> name on the dataset for Flocker + should be considered as deprecated + type: string + datasetUUID: + description: datasetUUID is the UUID of the dataset. + This is unique identifier of a Flocker dataset + type: string + type: object + gcePersistentDisk: + description: |- + gcePersistentDisk represents a GCE Disk resource that is attached to a + kubelet's host machine and then exposed to the pod. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + properties: + fsType: + description: |- + fsType is filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + partition: + description: |- + partition is the partition in the volume that you want to mount. + If omitted, the default is to mount by volume name. + Examples: For volume /dev/sda1, you specify the partition as "1". + Similarly, the volume partition for /dev/sda is "0" (or you can leave the property empty). + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + format: int32 + type: integer + pdName: + description: |- + pdName is unique name of the PD resource in GCE. Used to identify the disk in GCE. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + type: string + readOnly: + description: |- + readOnly here will force the ReadOnly setting in VolumeMounts. + Defaults to false. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + type: boolean + required: + - pdName + type: object + gitRepo: + description: |- + gitRepo represents a git repository at a particular revision. + DEPRECATED: GitRepo is deprecated. To provision a container with a git repo, mount an + EmptyDir into an InitContainer that clones the repo using git, then mount the EmptyDir + into the Pod's container. + properties: + directory: + description: |- + directory is the target directory name. + Must not contain or start with '..'. If '.' is supplied, the volume directory will be the + git repository. Otherwise, if specified, the volume will contain the git repository in + the subdirectory with the given name. + type: string + repository: + description: repository is the URL + type: string + revision: + description: revision is the commit hash for the specified + revision. + type: string + required: + - repository + type: object + glusterfs: + description: |- + glusterfs represents a Glusterfs mount on the host that shares a pod's lifetime. + More info: https://examples.k8s.io/volumes/glusterfs/README.md + properties: + endpoints: + description: |- + endpoints is the endpoint name that details Glusterfs topology. + More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod + type: string + path: + description: |- + path is the Glusterfs volume path. + More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod + type: string + readOnly: + description: |- + readOnly here will force the Glusterfs volume to be mounted with read-only permissions. + Defaults to false. + More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod + type: boolean + required: + - endpoints + - path + type: object + hostPath: + description: |- + hostPath represents a pre-existing file or directory on the host + machine that is directly exposed to the container. This is generally + used for system agents or other privileged things that are allowed + to see the host machine. Most containers will NOT need this. + More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + --- + TODO(jonesdl) We need to restrict who can use host directory mounts and who can/can not + mount host directories as read/write. + properties: + path: + description: |- + path of the directory on the host. + If the path is a symlink, it will follow the link to the real path. + More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + type: string + type: + description: |- + type for HostPath Volume + Defaults to "" + More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + type: string + required: + - path + type: object + iscsi: + description: |- + iscsi represents an ISCSI Disk resource that is attached to a + kubelet's host machine and then exposed to the pod. + More info: https://examples.k8s.io/volumes/iscsi/README.md + properties: + chapAuthDiscovery: + description: chapAuthDiscovery defines whether support + iSCSI Discovery CHAP authentication + type: boolean + chapAuthSession: + description: chapAuthSession defines whether support + iSCSI Session CHAP authentication + type: boolean + fsType: + description: |- + fsType is the filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#iscsi + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + initiatorName: + description: |- + initiatorName is the custom iSCSI Initiator Name. + If initiatorName is specified with iscsiInterface simultaneously, new iSCSI interface + : will be created for the connection. + type: string + iqn: + description: iqn is the target iSCSI Qualified Name. + type: string + iscsiInterface: + description: |- + iscsiInterface is the interface Name that uses an iSCSI transport. + Defaults to 'default' (tcp). + type: string + lun: + description: lun represents iSCSI Target Lun number. + format: int32 + type: integer + portals: + description: |- + portals is the iSCSI Target Portal List. The portal is either an IP or ip_addr:port if the port + is other than default (typically TCP ports 860 and 3260). + items: + type: string + type: array + readOnly: + description: |- + readOnly here will force the ReadOnly setting in VolumeMounts. + Defaults to false. + type: boolean + secretRef: + description: secretRef is the CHAP Secret for iSCSI + target and initiator authentication + 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 + targetPortal: + description: |- + targetPortal is iSCSI Target Portal. The Portal is either an IP or ip_addr:port if the port + is other than default (typically TCP ports 860 and 3260). + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + description: |- + name of the volume. + Must be a DNS_LABEL and unique within the pod. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + nfs: + description: |- + nfs represents an NFS mount on the host that shares a pod's lifetime + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + properties: + path: + description: |- + path that is exported by the NFS server. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + type: string + readOnly: + description: |- + readOnly here will force the NFS export to be mounted with read-only permissions. + Defaults to false. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + type: boolean + server: + description: |- + server is the hostname or IP address of the NFS server. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + description: |- + persistentVolumeClaimVolumeSource represents a reference to a + PersistentVolumeClaim in the same namespace. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims + properties: + claimName: + description: |- + claimName is the name of a PersistentVolumeClaim in the same namespace as the pod using this volume. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims + type: string + readOnly: + description: |- + readOnly Will force the ReadOnly setting in VolumeMounts. + Default false. + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + description: photonPersistentDisk represents a PhotonController + persistent disk attached and mounted on kubelets host + machine + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + pdID: + description: pdID is the ID that identifies Photon + Controller persistent disk + type: string + required: + - pdID + type: object + portworxVolume: + description: portworxVolume represents a portworx volume + attached and mounted on kubelets host machine + properties: + fsType: + description: |- + fSType represents the filesystem type to mount + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs". Implicitly inferred to be "ext4" if unspecified. + type: string + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + volumeID: + description: volumeID uniquely identifies a Portworx + volume + type: string + required: + - volumeID + type: object + projected: + description: projected items for all in one resources + secrets, configmaps, and downward API + properties: + defaultMode: + description: |- + defaultMode are the mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + sources: + description: sources is the list of volume projections + items: + description: Projection that may be projected along + with other supported volume types + properties: + clusterTrustBundle: + description: |- + ClusterTrustBundle allows a pod to access the `.spec.trustBundle` field + of ClusterTrustBundle objects in an auto-updating file. + + + Alpha, gated by the ClusterTrustBundleProjection feature gate. + + + ClusterTrustBundle objects can either be selected by name, or by the + combination of signer name and a label selector. + + + Kubelet performs aggressive normalization of the PEM contents written + into the pod filesystem. Esoteric PEM features such as inter-block + comments and block headers are stripped. Certificates are deduplicated. + The ordering of certificates within the file is arbitrary, and Kubelet + may change the order over time. + properties: + labelSelector: + description: |- + Select all ClusterTrustBundles that match this label selector. Only has + effect if signerName is set. Mutually-exclusive with name. If unset, + interpreted as "match nothing". If set but empty, interpreted as "match + everything". + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + name: + description: |- + Select a single ClusterTrustBundle by object name. Mutually-exclusive + with signerName and labelSelector. + type: string + optional: + description: |- + If true, don't block pod startup if the referenced ClusterTrustBundle(s) + aren't available. If using name, then the named ClusterTrustBundle is + allowed not to exist. If using signerName, then the combination of + signerName and labelSelector is allowed to match zero + ClusterTrustBundles. + type: boolean + path: + description: Relative path from the volume + root to write the bundle. + type: string + signerName: + description: |- + Select all ClusterTrustBundles that match this signer name. + Mutually-exclusive with name. The contents of all selected + ClusterTrustBundles will be unified and deduplicated. + type: string + required: + - path + type: object + configMap: + description: configMap information about the + configMap data to project + properties: + items: + description: |- + items if unspecified, each key-value pair in the Data field of the referenced + ConfigMap will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the ConfigMap, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path + within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + 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 + optional: + description: optional specify whether the + ConfigMap or its keys must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + downwardAPI: + description: downwardAPI information about the + downwardAPI data to project + properties: + items: + description: Items is a list of DownwardAPIVolume + file + items: + description: DownwardAPIVolumeFile represents + information to create the file containing + the pod field + properties: + fieldRef: + description: 'Required: Selects a + field of the pod: only annotations, + labels, name and namespace are supported.' + properties: + apiVersion: + description: Version of the schema + the FieldPath is written in + terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field + to select in the specified API + version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + description: |- + Optional: mode bits used to set permissions on this file, must be an octal value + between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: 'Required: Path is the + relative path name of the file to + be created. Must not be absolute + or contain the ''..'' path. Must + be utf-8 encoded. The first item + of the relative path must not start + with ''..''' + type: string + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported. + properties: + containerName: + description: 'Container name: + required for volumes, optional + for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output + format of the exposed resources, + defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource + to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + type: object + secret: + description: secret information about the secret + data to project + properties: + items: + description: |- + items if unspecified, each key-value pair in the Data field of the referenced + Secret will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the Secret, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path + within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + 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 + optional: + description: optional field specify whether + the Secret or its key must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + serviceAccountToken: + description: serviceAccountToken is information + about the serviceAccountToken data to project + properties: + audience: + description: |- + audience is the intended audience of the token. A recipient of a token + must identify itself with an identifier specified in the audience of the + token, and otherwise should reject the token. The audience defaults to the + identifier of the apiserver. + type: string + expirationSeconds: + description: |- + expirationSeconds is the requested duration of validity of the service + account token. As the token approaches expiration, the kubelet volume + plugin will proactively rotate the service account token. The kubelet will + start trying to rotate the token if the token is older than 80 percent of + its time to live or if the token is older than 24 hours.Defaults to 1 hour + and must be at least 10 minutes. + format: int64 + type: integer + path: + description: |- + path is the path relative to the mount point of the file to project the + token into. + type: string + required: + - path + type: object + type: object + type: array + type: object + quobyte: + description: quobyte represents a Quobyte mount on the + host that shares a pod's lifetime + properties: + group: + description: |- + group to map volume access to + Default is no group + type: string + readOnly: + description: |- + readOnly here will force the Quobyte volume to be mounted with read-only permissions. + Defaults to false. + type: boolean + registry: + description: |- + registry represents a single or multiple Quobyte Registry services + specified as a string as host:port pair (multiple entries are separated with commas) + which acts as the central registry for volumes + type: string + tenant: + description: |- + tenant owning the given Quobyte volume in the Backend + Used with dynamically provisioned Quobyte volumes, value is set by the plugin + type: string + user: + description: |- + user to map volume access to + Defaults to serivceaccount user + type: string + volume: + description: volume is a string that references an + already created Quobyte volume by name. + type: string + required: + - registry + - volume + type: object + rbd: + description: |- + rbd represents a Rados Block Device mount on the host that shares a pod's lifetime. + More info: https://examples.k8s.io/volumes/rbd/README.md + properties: + fsType: + description: |- + fsType is the filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#rbd + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + image: + description: |- + image is the rados image name. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + keyring: + description: |- + keyring is the path to key ring for RBDUser. + Default is /etc/ceph/keyring. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + monitors: + description: |- + monitors is a collection of Ceph monitors. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + items: + type: string + type: array + pool: + description: |- + pool is the rados pool name. + Default is rbd. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + readOnly: + description: |- + readOnly here will force the ReadOnly setting in VolumeMounts. + Defaults to false. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: boolean + secretRef: + description: |- + secretRef is name of the authentication secret for RBDUser. If provided + overrides keyring. + Default is nil. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + 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 + user: + description: |- + user is the rados user name. + Default is admin. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + required: + - image + - monitors + type: object + scaleIO: + description: scaleIO represents a ScaleIO persistent volume + attached and mounted on Kubernetes nodes. + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". + Default is "xfs". + type: string + gateway: + description: gateway is the host address of the ScaleIO + API Gateway. + type: string + protectionDomain: + description: protectionDomain is the name of the ScaleIO + Protection Domain for the configured storage. + type: string + readOnly: + description: |- + readOnly Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: |- + secretRef references to the secret for ScaleIO user and other + sensitive information. If this is not provided, Login operation will fail. + 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 + sslEnabled: + description: sslEnabled Flag enable/disable SSL communication + with Gateway, default false + type: boolean + storageMode: + description: |- + storageMode indicates whether the storage for a volume should be ThickProvisioned or ThinProvisioned. + Default is ThinProvisioned. + type: string + storagePool: + description: storagePool is the ScaleIO Storage Pool + associated with the protection domain. + type: string + system: + description: system is the name of the storage system + as configured in ScaleIO. + type: string + volumeName: + description: |- + volumeName is the name of a volume already created in the ScaleIO system + that is associated with this volume source. + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + description: |- + secret represents a secret that should populate this volume. + More info: https://kubernetes.io/docs/concepts/storage/volumes#secret + properties: + defaultMode: + description: |- + defaultMode is Optional: mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values + for mode bits. Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + items: + description: |- + items If unspecified, each key-value pair in the Data field of the referenced + Secret will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the Secret, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within + a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + optional: + description: optional field specify whether the Secret + or its keys must be defined + type: boolean + secretName: + description: |- + secretName is the name of the secret in the pod's namespace to use. + More info: https://kubernetes.io/docs/concepts/storage/volumes#secret + type: string + type: object + storageos: + description: storageOS represents a StorageOS volume attached + and mounted on Kubernetes nodes. + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: |- + secretRef specifies the secret to use for obtaining the StorageOS API + credentials. If not specified, default values will be attempted. + 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 + volumeName: + description: |- + volumeName is the human-readable name of the StorageOS volume. Volume + names are only unique within a namespace. + type: string + volumeNamespace: + description: |- + volumeNamespace specifies the scope of the volume within StorageOS. If no + namespace is specified then the Pod's namespace will be used. This allows the + Kubernetes name scoping to be mirrored within StorageOS for tighter integration. + Set VolumeName to any name to override the default behaviour. + Set to "default" if you are not using namespaces within StorageOS. + Namespaces that do not pre-exist within StorageOS will be created. + type: string + type: object + vsphereVolume: + description: vsphereVolume represents a vSphere volume + attached and mounted on kubelets host machine + properties: + fsType: + description: |- + fsType is filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + storagePolicyID: + description: storagePolicyID is the storage Policy + Based Management (SPBM) profile ID associated with + the StoragePolicyName. + type: string + storagePolicyName: + description: storagePolicyName is the storage Policy + Based Management (SPBM) profile name. + type: string + volumePath: + description: volumePath is the path that identifies + vSphere volume vmdk + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + required: + - name + type: object + type: array + labels: + additionalProperties: + type: string + description: Specifies Labels to override or add for underlying Pods. + type: object + offlineInstances: + description: |- + Specifies the names of instances to be transitioned to offline status. + + + Marking an instance as offline results in the following: + + + 1. The associated Pod is stopped, and its PersistentVolumeClaim (PVC) is retained for potential + future reuse or data recovery, but it is no longer actively used. + 2. The ordinal number assigned to this instance is preserved, ensuring it remains unique + and avoiding conflicts with new instances. + + + Setting instances to offline allows for a controlled scale-in process, preserving their data and maintaining + ordinal consistency within the Cluster. + Note that offline instances and their associated resources, such as PVCs, are not automatically deleted. + The administrator must manually manage the cleanup and removal of these resources when they are no longer needed. + items: + type: string + type: array + parallelPodManagementConcurrency: + anyOf: + - type: integer + - type: string + description: |- + Controls the concurrency of pods during initial scale up, when replacing pods on nodes, + or when scaling down. It only used when `PodManagementPolicy` is set to `Parallel`. + The default Concurrency is 100%. + x-kubernetes-int-or-string: true + podUpdatePolicy: + description: |- + PodUpdatePolicy indicates how pods should be updated + + + - `StrictInPlace` indicates that only allows in-place upgrades. + Any attempt to modify other fields will be rejected. + - `PreferInPlace` indicates that we will first attempt an in-place upgrade of the Pod. + If that fails, it will fall back to the ReCreate, where pod will be recreated. + Default value is "PreferInPlace" + type: string + replicas: + default: 1 + description: Specifies the desired number of replicas in the Component + for enhancing availability and durability, or load balancing. + format: int32 + minimum: 0 + type: integer + resources: + description: |- + Specifies the resources required by the Component. + It allows defining the CPU, memory requirements and limits for the Component's containers. + properties: + claims: + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + + + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + + + This field is immutable. It can only be set for containers. + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + x-kubernetes-preserve-unknown-fields: true + runtimeClassName: + description: Defines runtimeClassName for all Pods managed by this + Component. + type: string + schedulingPolicy: + description: Specifies the scheduling policy for the Component. + properties: + affinity: + description: Specifies a group of affinity scheduling rules of + the Cluster, including NodeAffinity, PodAffinity, and PodAntiAffinity. + properties: + nodeAffinity: + description: Describes node affinity scheduling rules for + the pod. + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node matches the corresponding matchExpressions; the + node(s) with the highest sum are the most preferred. + items: + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). + properties: + preference: + description: A node selector term, associated with + the corresponding weight. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + weight: + description: Weight associated with matching the + corresponding nodeSelectorTerm, in the range 1-100. + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. + properties: + nodeSelectorTerms: + description: Required. A list of node selector terms. + The terms are ORed. + items: + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + type: array + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + description: Describes pod affinity scheduling rules (e.g. + co-locate this pod in the same node, zone, etc. as some + other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred + node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated + with the corresponding weight. + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. + Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: |- + weight associated with matching the corresponding podAffinityTerm, + in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. + items: + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. + Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + description: Describes pod anti-affinity scheduling rules + (e.g. avoid putting this pod in the same node, zone, etc. + as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the anti-affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred + node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated + with the corresponding weight. + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. + Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: |- + weight associated with matching the corresponding podAffinityTerm, + in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the anti-affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the anti-affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. + items: + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. + Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + nodeName: + description: |- + NodeName is a request to schedule this Pod onto a specific node. If it is non-empty, + the scheduler simply schedules this Pod onto that node, assuming that it fits resource + requirements. + type: string + nodeSelector: + additionalProperties: + type: string + description: |- + NodeSelector is a selector which must be true for the Pod to fit on a node. + Selector which must match a node's labels for the Pod to be scheduled on that node. + More info: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ + type: object + x-kubernetes-map-type: atomic + schedulerName: + description: |- + If specified, the Pod will be dispatched by specified scheduler. + If not specified, the Pod will be dispatched by default scheduler. + type: string + tolerations: + description: |- + Allows Pods to be scheduled onto nodes with matching taints. + Each toleration in the array allows the Pod to tolerate node taints based on + specified `key`, `value`, `effect`, and `operator`. + + + - The `key`, `value`, and `effect` identify the taint that the toleration matches. + - The `operator` determines how the toleration matches the taint. + + + Pods with matching tolerations are allowed to be scheduled on tainted nodes, typically reserved for specific purposes. + items: + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . + properties: + effect: + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. + type: string + operator: + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. + type: string + tolerationSeconds: + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. + format: int64 + type: integer + value: + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. + type: string + type: object + type: array + topologySpreadConstraints: + description: |- + TopologySpreadConstraints describes how a group of Pods ought to spread across topology + domains. Scheduler will schedule Pods in a way which abides by the constraints. + All topologySpreadConstraints are ANDed. + items: + description: TopologySpreadConstraint specifies how to spread + matching pods among the given topology. + properties: + labelSelector: + description: |- + LabelSelector is used to find matching pods. + Pods that match this label selector are counted to determine the number of pods + in their corresponding topology domain. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select the pods over which + spreading will be calculated. The keys are used to lookup values from the + incoming pod labels, those key-value labels are ANDed with labelSelector + to select the group of existing pods over which spreading will be calculated + for the incoming pod. The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + MatchLabelKeys cannot be set when LabelSelector isn't set. + Keys that don't exist in the incoming pod labels will + be ignored. A null or empty list means only match against labelSelector. + + + This is a beta field and requires the MatchLabelKeysInPodTopologySpread feature gate to be enabled (enabled by default). + items: + type: string + type: array + x-kubernetes-list-type: atomic + maxSkew: + description: |- + MaxSkew describes the degree to which pods may be unevenly distributed. + When `whenUnsatisfiable=DoNotSchedule`, it is the maximum permitted difference + between the number of matching pods in the target topology and the global minimum. + The global minimum is the minimum number of matching pods in an eligible domain + or zero if the number of eligible domains is less than MinDomains. + For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same + labelSelector spread as 2/2/1: + In this case, the global minimum is 1. + | zone1 | zone2 | zone3 | + | P P | P P | P | + - if MaxSkew is 1, incoming pod can only be scheduled to zone3 to become 2/2/2; + scheduling it onto zone1(zone2) would make the ActualSkew(3-1) on zone1(zone2) + violate MaxSkew(1). + - if MaxSkew is 2, incoming pod can be scheduled onto any zone. + When `whenUnsatisfiable=ScheduleAnyway`, it is used to give higher precedence + to topologies that satisfy it. + It's a required field. Default value is 1 and 0 is not allowed. + format: int32 + type: integer + minDomains: + description: |- + MinDomains indicates a minimum number of eligible domains. + When the number of eligible domains with matching topology keys is less than minDomains, + Pod Topology Spread treats "global minimum" as 0, and then the calculation of Skew is performed. + And when the number of eligible domains with matching topology keys equals or greater than minDomains, + this value has no effect on scheduling. + As a result, when the number of eligible domains is less than minDomains, + scheduler won't schedule more than maxSkew Pods to those domains. + If value is nil, the constraint behaves as if MinDomains is equal to 1. + Valid values are integers greater than 0. + When value is not nil, WhenUnsatisfiable must be DoNotSchedule. + + + For example, in a 3-zone cluster, MaxSkew is set to 2, MinDomains is set to 5 and pods with the same + labelSelector spread as 2/2/2: + | zone1 | zone2 | zone3 | + | P P | P P | P P | + The number of domains is less than 5(MinDomains), so "global minimum" is treated as 0. + In this situation, new pod with the same labelSelector cannot be scheduled, + because computed skew will be 3(3 - 0) if new Pod is scheduled to any of the three zones, + it will violate MaxSkew. + + + This is a beta field and requires the MinDomainsInPodTopologySpread feature gate to be enabled (enabled by default). + format: int32 + type: integer + nodeAffinityPolicy: + description: |- + NodeAffinityPolicy indicates how we will treat Pod's nodeAffinity/nodeSelector + when calculating pod topology spread skew. Options are: + - Honor: only nodes matching nodeAffinity/nodeSelector are included in the calculations. + - Ignore: nodeAffinity/nodeSelector are ignored. All nodes are included in the calculations. + + + If this value is nil, the behavior is equivalent to the Honor policy. + This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag. + type: string + nodeTaintsPolicy: + description: |- + NodeTaintsPolicy indicates how we will treat node taints when calculating + pod topology spread skew. Options are: + - Honor: nodes without taints, along with tainted nodes for which the incoming pod + has a toleration, are included. + - Ignore: node taints are ignored. All nodes are included. + + + If this value is nil, the behavior is equivalent to the Ignore policy. + This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag. + type: string + topologyKey: + description: |- + TopologyKey is the key of node labels. Nodes that have a label with this key + and identical values are considered to be in the same topology. + We consider each as a "bucket", and try to put balanced number + of pods into each bucket. + We define a domain as a particular instance of a topology. + Also, we define an eligible domain as a domain whose nodes meet the requirements of + nodeAffinityPolicy and nodeTaintsPolicy. + e.g. If TopologyKey is "kubernetes.io/hostname", each Node is a domain of that topology. + And, if TopologyKey is "topology.kubernetes.io/zone", each zone is a domain of that topology. + It's a required field. + type: string + whenUnsatisfiable: + description: |- + WhenUnsatisfiable indicates how to deal with a pod if it doesn't satisfy + the spread constraint. + - DoNotSchedule (default) tells the scheduler not to schedule it. + - ScheduleAnyway tells the scheduler to schedule the pod in any location, + but giving higher precedence to topologies that would help reduce the + skew. + A constraint is considered "Unsatisfiable" for an incoming pod + if and only if every possible node assignment for that pod would violate + "MaxSkew" on some topology. + For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same + labelSelector spread as 3/1/1: + | zone1 | zone2 | zone3 | + | P P P | P | P | + If WhenUnsatisfiable is set to DoNotSchedule, incoming pod can only be scheduled + to zone2(zone3) to become 3/2/1(3/1/2) as ActualSkew(2-1) on zone2(zone3) satisfies + MaxSkew(1). In other words, the cluster can still be imbalanced, but scheduler + won't make it *more* imbalanced. + It's a required field. + type: string + required: + - maxSkew + - topologyKey + - whenUnsatisfiable + type: object + type: array + type: object + serviceAccountName: + description: |- + Specifies the name of the ServiceAccount required by the running Component. + This ServiceAccount is used to grant necessary permissions for the Component's Pods to interact + with other Kubernetes resources, such as modifying Pod labels or sending events. + + + Defaults: + If not specified, KubeBlocks automatically assigns a default ServiceAccount named "kb-{cluster.name}", + bound to a default role defined during KubeBlocks installation. + + + Future Changes: + Future versions might change the default ServiceAccount creation strategy to one per Component, + potentially revising the naming to "kb-{cluster.name}-{component.name}". + + + Users can override the automatic ServiceAccount assignment by explicitly setting the name of + an existed ServiceAccount in this field. + type: string + serviceRefs: + description: |- + Defines a list of ServiceRef for a Component, enabling access to both external services and + Services provided by other Clusters. + + + Types of services: + + + - External services: Not managed by KubeBlocks or managed by a different KubeBlocks operator; + Require a ServiceDescriptor for connection details. + - Services provided by a Cluster: Managed by the same KubeBlocks operator; + identified using Cluster, Component and Service names. + + + ServiceRefs with identical `serviceRef.name` in the same Cluster are considered the same. + + + Example: + ```yaml + serviceRefs: + - name: "redis-sentinel" + serviceDescriptor: + name: "external-redis-sentinel" + - name: "postgres-cluster" + clusterServiceSelector: + cluster: "my-postgres-cluster" + service: + component: "postgresql" + ``` + The example above includes ServiceRefs to an external Redis Sentinel service and a PostgreSQL Cluster. + items: + properties: + cluster: + description: |- + Specifies the name of the KubeBlocks Cluster being referenced. + This is used when services from another KubeBlocks Cluster are consumed. + + + By default, the referenced KubeBlocks Cluster's `clusterDefinition.spec.connectionCredential` + will be utilized to bind to the current Component. This credential should include: + `endpoint`, `port`, `username`, and `password`. + + + Note: + + + - The `ServiceKind` and `ServiceVersion` specified in the service reference within the + ClusterDefinition are not validated when using this approach. + - If both `cluster` and `serviceDescriptor` are present, `cluster` will take precedence. + + + Deprecated since v0.9 since `clusterDefinition.spec.connectionCredential` is deprecated, + use `clusterServiceSelector` instead. + This field is maintained for backward compatibility and its use is discouraged. + Existing usage should be updated to the current preferred approach to avoid compatibility issues in future releases. + type: string + clusterServiceSelector: + description: |- + References a service provided by another KubeBlocks Cluster. + It specifies the ClusterService and the account credentials needed for access. + properties: + cluster: + description: The name of the Cluster being referenced. + type: string + credential: + description: |- + Specifies the SystemAccount to authenticate and establish a connection with the referenced Cluster. + The SystemAccount should be defined in `componentDefinition.spec.systemAccounts` + of the Component providing the service in the referenced Cluster. + properties: + component: + description: The name of the Component where the credential + resides in. + type: string + name: + description: The name of the credential (SystemAccount) + to reference. + type: string + required: + - component + - name + type: object + service: + description: Identifies a ClusterService from the list of + Services defined in `cluster.spec.services` of the referenced + Cluster. + properties: + component: + description: |- + The name of the Component where the Service resides in. + + + It is required when referencing a Component's Service. + type: string + port: + description: |- + The port name of the Service to be referenced. + + + If there is a non-zero node-port exist for the matched Service port, the node-port will be selected first. + + + If the referenced Service is of pod-service type (a Service per Pod), there will be multiple Service objects matched, + and the resolved value will be presented in the following format: service1.name:port1,service2.name:port2... + type: string + service: + description: |- + The name of the Service to be referenced. + + + Leave it empty to reference the default Service. Set it to "headless" to reference the default headless Service. + + + If the referenced Service is of pod-service type (a Service per Pod), there will be multiple Service objects matched, + and the resolved value will be presented in the following format: service1.name,service2.name... + type: string + required: + - service + type: object + required: + - cluster + type: object + name: + description: |- + Specifies the identifier of the service reference declaration. + It corresponds to the serviceRefDeclaration name defined in either: + + + - `componentDefinition.spec.serviceRefDeclarations[*].name` + - `clusterDefinition.spec.componentDefs[*].serviceRefDeclarations[*].name` (deprecated) + type: string + namespace: + description: |- + Specifies the namespace of the referenced Cluster or the namespace of the referenced ServiceDescriptor object. + If not provided, the referenced Cluster and ServiceDescriptor will be searched in the namespace of the current + Cluster by default. + type: string + serviceDescriptor: + description: |- + Specifies the name of the ServiceDescriptor object that describes a service provided by external sources. + + + When referencing a service provided by external sources, a ServiceDescriptor object is required to establish + the service binding. + The `serviceDescriptor.spec.serviceKind` and `serviceDescriptor.spec.serviceVersion` should match the serviceKind + and serviceVersion declared in the definition. + + + If both `cluster` and `serviceDescriptor` are specified, the `cluster` takes precedence. + type: string + required: + - name + type: object + type: array + serviceVersion: + description: |- + ServiceVersion specifies the version of the Service expected to be provisioned by this Component. + The version should follow the syntax and semantics of the "Semantic Versioning" specification (http://semver.org/). + maxLength: 32 + type: string + services: + description: |- + Overrides Services defined in referenced ComponentDefinition and exposes endpoints that can be accessed + by clients. + items: + description: |- + ComponentService defines a service that would be exposed as an inter-component service within a Cluster. + A Service defined in the ComponentService is expected to be accessed by other Components within the same Cluster. + + + When a Component needs to use a ComponentService provided by another Component within the same Cluster, + it can declare a variable in the `componentDefinition.spec.vars` section and bind it to the specific exposed address + of the ComponentService using the `serviceVarRef` field. + properties: + annotations: + additionalProperties: + type: string + description: |- + If ServiceType is LoadBalancer, cloud provider related parameters can be put here + More info: https://kubernetes.io/docs/concepts/services-networking/service/#loadbalancer. + type: object + disableAutoProvision: + description: |- + Indicates whether the automatic provisioning of the service should be disabled. + + + If set to true, the service will not be automatically created at the component provisioning. + Instead, you can enable the creation of this service by specifying it explicitly in the cluster API. + type: boolean + name: + description: |- + Name defines the name of the service. + otherwise, it indicates the name of the service. + Others can refer to this service by its name. (e.g., connection credential) + Cannot be updated. + maxLength: 25 + type: string + podService: + default: false + description: |- + Indicates whether to create a corresponding Service for each Pod of the selected Component. + When set to true, a set of Services will be automatically generated for each Pod, + and the `roleSelector` field will be ignored. + + + The names of the generated Services will follow the same suffix naming pattern: `$(serviceName)-$(podOrdinal)`. + The total number of generated Services will be equal to the number of replicas specified for the Component. + + + Example usage: + + + ```yaml + name: my-service + serviceName: my-service + podService: true + disableAutoProvision: true + spec: + type: NodePort + ports: + - name: http + port: 80 + targetPort: 8080 + ``` + + + In this example, if the Component has 3 replicas, three Services will be generated: + - my-service-0: Points to the first Pod (podOrdinal: 0) + - my-service-1: Points to the second Pod (podOrdinal: 1) + - my-service-2: Points to the third Pod (podOrdinal: 2) + + + Each generated Service will have the specified spec configuration and will target its respective Pod. + + + This feature is useful when you need to expose each Pod of a Component individually, allowing external access + to specific instances of the Component. + type: boolean + roleSelector: + description: "Extends the above `serviceSpec.selector` by allowing + you to specify defined role as selector for the service.\nWhen + `roleSelector` is set, it adds a label selector \"kubeblocks.io/role: + {roleSelector}\"\nto the `serviceSpec.selector`.\nExample + usage:\n\n\n\t roleSelector: \"leader\"\n\n\nIn this example, + setting `roleSelector` to \"leader\" will add a label selector\n\"kubeblocks.io/role: + leader\" to the `serviceSpec.selector`.\nThis means that the + service will select and route traffic to Pods with the label\n\"kubeblocks.io/role\" + set to \"leader\".\n\n\nNote that if `podService` sets to + true, RoleSelector will be ignored.\nThe `podService` flag + takes precedence over `roleSelector` and generates a service + for each Pod." + type: string + serviceName: + description: |- + ServiceName defines the name of the underlying service object. + If not specified, the default service name with different patterns will be used: + + + - CLUSTER_NAME: for cluster-level services + - CLUSTER_NAME-COMPONENT_NAME: for component-level services + + + Only one default service name is allowed. + Cannot be updated. + maxLength: 25 + pattern: ^[a-z]([a-z0-9\-]*[a-z0-9])?$ + type: string + spec: + description: |- + Spec defines the behavior of a service. + https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status + properties: + allocateLoadBalancerNodePorts: + description: |- + allocateLoadBalancerNodePorts defines if NodePorts will be automatically + allocated for services with type LoadBalancer. Default is "true". It + may be set to "false" if the cluster load-balancer does not rely on + NodePorts. If the caller requests specific NodePorts (by specifying a + value), those requests will be respected, regardless of this field. + This field may only be set for services with type LoadBalancer and will + be cleared if the type is changed to any other type. + type: boolean + clusterIP: + description: |- + clusterIP is the IP address of the service and is usually assigned + randomly. If an address is specified manually, is in-range (as per + system configuration), and is not in use, it will be allocated to the + service; otherwise creation of the service will fail. This field may not + be changed through updates unless the type field is also being changed + to ExternalName (which requires this field to be blank) or the type + field is being changed from ExternalName (in which case this field may + optionally be specified, as describe above). Valid values are "None", + empty string (""), or a valid IP address. Setting this to "None" makes a + "headless service" (no virtual IP), which is useful when direct endpoint + connections are preferred and proxying is not required. Only applies to + types ClusterIP, NodePort, and LoadBalancer. If this field is specified + when creating a Service of type ExternalName, creation will fail. This + field will be wiped when updating a Service to type ExternalName. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + type: string + clusterIPs: + description: |- + ClusterIPs is a list of IP addresses assigned to this service, and are + usually assigned randomly. If an address is specified manually, is + in-range (as per system configuration), and is not in use, it will be + allocated to the service; otherwise creation of the service will fail. + This field may not be changed through updates unless the type field is + also being changed to ExternalName (which requires this field to be + empty) or the type field is being changed from ExternalName (in which + case this field may optionally be specified, as describe above). Valid + values are "None", empty string (""), or a valid IP address. Setting + this to "None" makes a "headless service" (no virtual IP), which is + useful when direct endpoint connections are preferred and proxying is + not required. Only applies to types ClusterIP, NodePort, and + LoadBalancer. If this field is specified when creating a Service of type + ExternalName, creation will fail. This field will be wiped when updating + a Service to type ExternalName. If this field is not specified, it will + be initialized from the clusterIP field. If this field is specified, + clients must ensure that clusterIPs[0] and clusterIP have the same + value. + + + This field may hold a maximum of two entries (dual-stack IPs, in either order). + These IPs must correspond to the values of the ipFamilies field. Both + clusterIPs and ipFamilies are governed by the ipFamilyPolicy field. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalIPs: + description: |- + externalIPs is a list of IP addresses for which nodes in the cluster + will also accept traffic for this service. These IPs are not managed by + Kubernetes. The user is responsible for ensuring that traffic arrives + at a node with this IP. A common example is external load-balancers + that are not part of the Kubernetes system. + items: + type: string + type: array + externalName: + description: |- + externalName is the external reference that discovery mechanisms will + return as an alias for this service (e.g. a DNS CNAME record). No + proxying will be involved. Must be a lowercase RFC-1123 hostname + (https://tools.ietf.org/html/rfc1123) and requires `type` to be "ExternalName". + type: string + externalTrafficPolicy: + description: |- + externalTrafficPolicy describes how nodes distribute service traffic they + receive on one of the Service's "externally-facing" addresses (NodePorts, + ExternalIPs, and LoadBalancer IPs). If set to "Local", the proxy will configure + the service in a way that assumes that external load balancers will take care + of balancing the service traffic between nodes, and so each node will deliver + traffic only to the node-local endpoints of the service, without masquerading + the client source IP. (Traffic mistakenly sent to a node with no endpoints will + be dropped.) The default value, "Cluster", uses the standard behavior of + routing to all endpoints evenly (possibly modified by topology and other + features). Note that traffic sent to an External IP or LoadBalancer IP from + within the cluster will always get "Cluster" semantics, but clients sending to + a NodePort from within the cluster may need to take traffic policy into account + when picking a node. + type: string + healthCheckNodePort: + description: |- + healthCheckNodePort specifies the healthcheck nodePort for the service. + This only applies when type is set to LoadBalancer and + externalTrafficPolicy is set to Local. If a value is specified, is + in-range, and is not in use, it will be used. If not specified, a value + will be automatically allocated. External systems (e.g. load-balancers) + can use this port to determine if a given node holds endpoints for this + service or not. If this field is specified when creating a Service + which does not need it, creation will fail. This field will be wiped + when updating a Service to no longer need it (e.g. changing type). + This field cannot be updated once set. + format: int32 + type: integer + internalTrafficPolicy: + description: |- + InternalTrafficPolicy describes how nodes distribute service traffic they + receive on the ClusterIP. If set to "Local", the proxy will assume that pods + only want to talk to endpoints of the service on the same node as the pod, + dropping the traffic if there are no local endpoints. The default value, + "Cluster", uses the standard behavior of routing to all endpoints evenly + (possibly modified by topology and other features). + type: string + ipFamilies: + description: |- + IPFamilies is a list of IP families (e.g. IPv4, IPv6) assigned to this + service. This field is usually assigned automatically based on cluster + configuration and the ipFamilyPolicy field. If this field is specified + manually, the requested family is available in the cluster, + and ipFamilyPolicy allows it, it will be used; otherwise creation of + the service will fail. This field is conditionally mutable: it allows + for adding or removing a secondary IP family, but it does not allow + changing the primary IP family of the Service. Valid values are "IPv4" + and "IPv6". This field only applies to Services of types ClusterIP, + NodePort, and LoadBalancer, and does apply to "headless" services. + This field will be wiped when updating a Service to type ExternalName. + + + This field may hold a maximum of two entries (dual-stack families, in + either order). These families must correspond to the values of the + clusterIPs field, if specified. Both clusterIPs and ipFamilies are + governed by the ipFamilyPolicy field. + items: + description: |- + IPFamily represents the IP Family (IPv4 or IPv6). This type is used + to express the family of an IP expressed by a type (e.g. service.spec.ipFamilies). + type: string + type: array + x-kubernetes-list-type: atomic + ipFamilyPolicy: + description: |- + IPFamilyPolicy represents the dual-stack-ness requested or required by + this Service. If there is no value provided, then this field will be set + to SingleStack. Services can be "SingleStack" (a single IP family), + "PreferDualStack" (two IP families on dual-stack configured clusters or + a single IP family on single-stack clusters), or "RequireDualStack" + (two IP families on dual-stack configured clusters, otherwise fail). The + ipFamilies and clusterIPs fields depend on the value of this field. This + field will be wiped when updating a service to type ExternalName. + type: string + loadBalancerClass: + description: |- + loadBalancerClass is the class of the load balancer implementation this Service belongs to. + If specified, the value of this field must be a label-style identifier, with an optional prefix, + e.g. "internal-vip" or "example.com/internal-vip". Unprefixed names are reserved for end-users. + This field can only be set when the Service type is 'LoadBalancer'. If not set, the default load + balancer implementation is used, today this is typically done through the cloud provider integration, + but should apply for any default implementation. If set, it is assumed that a load balancer + implementation is watching for Services with a matching class. Any default load balancer + implementation (e.g. cloud providers) should ignore Services that set this field. + This field can only be set when creating or updating a Service to type 'LoadBalancer'. + Once set, it can not be changed. This field will be wiped when a service is updated to a non 'LoadBalancer' type. + type: string + loadBalancerIP: + description: |- + Only applies to Service Type: LoadBalancer. + This feature depends on whether the underlying cloud-provider supports specifying + the loadBalancerIP when a load balancer is created. + This field will be ignored if the cloud-provider does not support the feature. + Deprecated: This field was under-specified and its meaning varies across implementations. + Using it is non-portable and it may not support dual-stack. + Users are encouraged to use implementation-specific annotations when available. + type: string + loadBalancerSourceRanges: + description: |- + If specified and supported by the platform, this will restrict traffic through the cloud-provider + load-balancer will be restricted to the specified client IPs. This field will be ignored if the + cloud-provider does not support the feature." + More info: https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/ + items: + type: string + type: array + ports: + description: |- + The list of ports that are exposed by this service. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + items: + description: ServicePort contains information on service's + port. + properties: + appProtocol: + description: |- + The application protocol for this port. + This is used as a hint for implementations to offer richer behavior for protocols that they understand. + This field follows standard Kubernetes label syntax. + Valid values are either: + + + * Un-prefixed protocol names - reserved for IANA standard service names (as per + RFC-6335 and https://www.iana.org/assignments/service-names). + + + * Kubernetes-defined prefixed names: + * 'kubernetes.io/h2c' - HTTP/2 prior knowledge over cleartext as described in https://www.rfc-editor.org/rfc/rfc9113.html#name-starting-http-2-with-prior- + * 'kubernetes.io/ws' - WebSocket over cleartext as described in https://www.rfc-editor.org/rfc/rfc6455 + * 'kubernetes.io/wss' - WebSocket over TLS as described in https://www.rfc-editor.org/rfc/rfc6455 + + + * Other protocols should use implementation-defined prefixed names such as + mycompany.com/my-custom-protocol. + type: string + name: + description: |- + The name of this port within the service. This must be a DNS_LABEL. + All ports within a ServiceSpec must have unique names. When considering + the endpoints for a Service, this must match the 'name' field in the + EndpointPort. + Optional if only one ServicePort is defined on this service. + type: string + nodePort: + description: |- + The port on each node on which this service is exposed when type is + NodePort or LoadBalancer. Usually assigned by the system. If a value is + specified, in-range, and not in use it will be used, otherwise the + operation will fail. If not specified, a port will be allocated if this + Service requires one. If this field is specified when creating a + Service which does not need it, creation will fail. This field will be + wiped when updating a Service to no longer need it (e.g. changing type + from NodePort to ClusterIP). + More info: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport + format: int32 + type: integer + port: + description: The port that will be exposed by this + service. + format: int32 + type: integer + protocol: + default: TCP + description: |- + The IP protocol for this port. Supports "TCP", "UDP", and "SCTP". + Default is TCP. + type: string + targetPort: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the pods targeted by the service. + Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + If this is a string, it will be looked up as a named port in the + target Pod's container ports. If this is not specified, the value + of the 'port' field is used (an identity map). + This field is ignored for services with clusterIP=None, and should be + omitted or set equal to the 'port' field. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#defining-a-service + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-map-keys: + - port + - protocol + x-kubernetes-list-type: map + publishNotReadyAddresses: + description: |- + publishNotReadyAddresses indicates that any agent which deals with endpoints for this + Service should disregard any indications of ready/not-ready. + The primary use case for setting this field is for a StatefulSet's Headless Service to + propagate SRV DNS records for its Pods for the purpose of peer discovery. + The Kubernetes controllers that generate Endpoints and EndpointSlice resources for + Services interpret this to mean that all endpoints are considered "ready" even if the + Pods themselves are not. Agents which consume only Kubernetes generated endpoints + through the Endpoints or EndpointSlice resources can safely assume this behavior. + type: boolean + selector: + additionalProperties: + type: string + description: |- + Route service traffic to pods with label keys and values matching this + selector. If empty or not present, the service is assumed to have an + external process managing its endpoints, which Kubernetes will not + modify. Only applies to types ClusterIP, NodePort, and LoadBalancer. + Ignored if type is ExternalName. + More info: https://kubernetes.io/docs/concepts/services-networking/service/ + type: object + x-kubernetes-map-type: atomic + sessionAffinity: + description: |- + Supports "ClientIP" and "None". Used to maintain session affinity. + Enable client IP based session affinity. + Must be ClientIP or None. + Defaults to None. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + type: string + sessionAffinityConfig: + description: sessionAffinityConfig contains the configurations + of session affinity. + properties: + clientIP: + description: clientIP contains the configurations of + Client IP based session affinity. + properties: + timeoutSeconds: + description: |- + timeoutSeconds specifies the seconds of ClientIP type session sticky time. + The value must be >0 && <=86400(for 1 day) if ServiceAffinity == "ClientIP". + Default value is 10800(for 3 hours). + format: int32 + type: integer + type: object + type: object + type: + description: |- + type determines how the Service is exposed. Defaults to ClusterIP. Valid + options are ExternalName, ClusterIP, NodePort, and LoadBalancer. + "ClusterIP" allocates a cluster-internal IP address for load-balancing + to endpoints. Endpoints are determined by the selector or if that is not + specified, by manual construction of an Endpoints object or + EndpointSlice objects. If clusterIP is "None", no virtual IP is + allocated and the endpoints are published as a set of endpoints rather + than a virtual IP. + "NodePort" builds on ClusterIP and allocates a port on every node which + routes to the same endpoints as the clusterIP. + "LoadBalancer" builds on NodePort and creates an external load-balancer + (if supported in the current cloud) which routes to the same endpoints + as the clusterIP. + "ExternalName" aliases this service to the specified externalName. + Several other fields do not apply to ExternalName services. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types + type: string + type: object + required: + - name + type: object + type: array + stop: + description: |- + Stop the Component. + If set, all the computing resources will be released. + type: boolean + systemAccounts: + description: Overrides system accounts defined in referenced ComponentDefinition. + items: + properties: + name: + description: The name of the system account. + type: string + passwordConfig: + description: |- + Specifies the policy for generating the account's password. + + + This field is immutable once set. + properties: + length: + default: 16 + description: The length of the password. + format: int32 + maximum: 32 + minimum: 8 + type: integer + letterCase: + default: MixedCases + description: The case of the letters in the password. + enum: + - LowerCases + - UpperCases + - MixedCases + type: string + numDigits: + default: 4 + description: The number of digits in the password. + format: int32 + maximum: 8 + minimum: 0 + type: integer + numSymbols: + default: 0 + description: The number of symbols in the password. + format: int32 + maximum: 8 + minimum: 0 + type: integer + seed: + description: |- + Seed to generate the account's password. + Cannot be updated. + type: string + type: object + secretRef: + description: |- + Refers to the secret from which data will be copied to create the new account. + + + This field is immutable once set. + properties: + name: + description: The unique identifier of the secret. + type: string + namespace: + description: The namespace where the secret is located. + type: string + required: + - name + - namespace + type: object + required: + - name + type: object + type: array + tlsConfig: + description: "Specifies the TLS configuration for the Component, including:\n\n\n- + A boolean flag that indicates whether the Component should use Transport + Layer Security (TLS) for secure communication.\n- An optional field + that specifies the configuration for the TLS certificates issuer + when TLS is enabled.\n It allows defining the issuer name and the + reference to the secret containing the TLS certificates and key.\n\t + The secret should contain the CA certificate, TLS certificate, and + private key in the specified keys." + properties: + enable: + default: false + description: |- + A boolean flag that indicates whether the Component should use Transport Layer Security (TLS) + for secure communication. + When set to true, the Component will be configured to use TLS encryption for its network connections. + This ensures that the data transmitted between the Component and its clients or other Components is encrypted + and protected from unauthorized access. + If TLS is enabled, the Component may require additional configuration, + such as specifying TLS certificates and keys, to properly set up the secure communication channel. + type: boolean + issuer: + description: |- + Specifies the configuration for the TLS certificates issuer. + It allows defining the issuer name and the reference to the secret containing the TLS certificates and key. + The secret should contain the CA certificate, TLS certificate, and private key in the specified keys. + Required when TLS is enabled. + properties: + name: + allOf: + - enum: + - KubeBlocks + - UserProvided + - enum: + - KubeBlocks + - UserProvided + default: KubeBlocks + description: |- + The issuer for TLS certificates. + It only allows two enum values: `KubeBlocks` and `UserProvided`. + + + - `KubeBlocks` indicates that the self-signed TLS certificates generated by the KubeBlocks Operator will be used. + - `UserProvided` means that the user is responsible for providing their own CA, Cert, and Key. + In this case, the user-provided CA certificate, server certificate, and private key will be used + for TLS communication. + type: string + secretRef: + description: |- + SecretRef is the reference to the secret that contains user-provided certificates. + It is required when the issuer is set to `UserProvided`. + properties: + ca: + description: Key of CA cert in Secret + type: string + cert: + description: Key of Cert in Secret + type: string + key: + description: Key of TLS private key in Secret + type: string + name: + description: Name of the Secret that contains user-provided + certificates. + type: string + required: + - ca + - cert + - key + - name + type: object + required: + - name + type: object + type: object + volumeClaimTemplates: + description: |- + Specifies a list of PersistentVolumeClaim templates that define the storage requirements for the Component. + Each template specifies the desired characteristics of a persistent volume, such as storage class, + size, and access modes. + These templates are used to dynamically provision persistent volumes for the Component. + items: + properties: + name: + description: |- + Refers to the name of a volumeMount defined in either: + + + - `componentDefinition.spec.runtime.containers[*].volumeMounts` + - `clusterDefinition.spec.componentDefs[*].podSpec.containers[*].volumeMounts` (deprecated) + + + The value of `name` must match the `name` field of a volumeMount specified in the corresponding `volumeMounts` array. + type: string + spec: + description: |- + Defines the desired characteristics of a PersistentVolumeClaim that will be created for the volume + with the mount name specified in the `name` field. + + + When a Pod is created for this ClusterComponent, a new PVC will be created based on the specification + defined in the `spec` field. The PVC will be associated with the volume mount specified by the `name` field. + properties: + accessModes: + description: |- + Contains the desired access modes the volume should have. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1. + items: + type: string + type: array + x-kubernetes-preserve-unknown-fields: true + resources: + description: |- + Represents the minimum resources the volume should have. + If the RecoverVolumeExpansionFailure feature is enabled, users are allowed to specify resource requirements that + are lower than the previous value but must still be higher than the capacity recorded in the status field of the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources. + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + x-kubernetes-preserve-unknown-fields: true + storageClassName: + description: |- + The name of the StorageClass required by the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1. + type: string + volumeMode: + description: Defines what type of volume is required by + the claim, either Block or Filesystem. + type: string + type: object + required: + - name + type: object + type: array + volumes: + description: List of volumes to override. + items: + description: Volume represents a named volume in a pod that may + be accessed by any container in the pod. + properties: + awsElasticBlockStore: + description: |- + awsElasticBlockStore represents an AWS Disk resource that is attached to a + kubelet's host machine and then exposed to the pod. + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + properties: + fsType: + description: |- + fsType is the filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + partition: + description: |- + partition is the partition in the volume that you want to mount. + If omitted, the default is to mount by volume name. + Examples: For volume /dev/sda1, you specify the partition as "1". + Similarly, the volume partition for /dev/sda is "0" (or you can leave the property empty). + format: int32 + type: integer + readOnly: + description: |- + readOnly value true will force the readOnly setting in VolumeMounts. + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + type: boolean + volumeID: + description: |- + volumeID is unique ID of the persistent disk resource in AWS (Amazon EBS volume). + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + type: string + required: + - volumeID + type: object + azureDisk: + description: azureDisk represents an Azure Data Disk mount on + the host and bind mount to the pod. + properties: + cachingMode: + description: 'cachingMode is the Host Caching mode: None, + Read Only, Read Write.' + type: string + diskName: + description: diskName is the Name of the data disk in the + blob storage + type: string + diskURI: + description: diskURI is the URI of data disk in the blob + storage + type: string + fsType: + description: |- + fsType is Filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + kind: + description: 'kind expected values are Shared: multiple + blob disks per storage account Dedicated: single blob + disk per storage account Managed: azure managed data + disk (only in managed availability set). defaults to shared' + type: string + readOnly: + description: |- + readOnly Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + description: azureFile represents an Azure File Service mount + on the host and bind mount to the pod. + properties: + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretName: + description: secretName is the name of secret that contains + Azure Storage Account Name and Key + type: string + shareName: + description: shareName is the azure share Name + type: string + required: + - secretName + - shareName + type: object + cephfs: + description: cephFS represents a Ceph FS mount on the host that + shares a pod's lifetime + properties: + monitors: + description: |- + monitors is Required: Monitors is a collection of Ceph monitors + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + items: + type: string + type: array + path: + description: 'path is Optional: Used as the mounted root, + rather than the full Ceph tree, default is /' + type: string + readOnly: + description: |- + readOnly is Optional: Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + type: boolean + secretFile: + description: |- + secretFile is Optional: SecretFile is the path to key ring for User, default is /etc/ceph/user.secret + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + type: string + secretRef: + description: |- + secretRef is Optional: SecretRef is reference to the authentication secret for User, default is empty. + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + 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 + user: + description: |- + user is optional: User is the rados user name, default is admin + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + type: string + required: + - monitors + type: object + cinder: + description: |- + cinder represents a cinder volume attached and mounted on kubelets host machine. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + type: string + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + type: boolean + secretRef: + description: |- + secretRef is optional: points to a secret object containing parameters used to connect + to OpenStack. + 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 + volumeID: + description: |- + volumeID used to identify the volume in cinder. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + type: string + required: + - volumeID + type: object + configMap: + description: configMap represents a configMap that should populate + this volume + properties: + defaultMode: + description: |- + defaultMode is optional: mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + items: + description: |- + items if unspecified, each key-value pair in the Data field of the referenced + ConfigMap will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the ConfigMap, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + 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 + optional: + description: optional specify whether the ConfigMap or its + keys must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + csi: + description: csi (Container Storage Interface) represents ephemeral + storage that is handled by certain external CSI drivers (Beta + feature). + properties: + driver: + description: |- + driver is the name of the CSI driver that handles this volume. + Consult with your admin for the correct name as registered in the cluster. + type: string + fsType: + description: |- + fsType to mount. Ex. "ext4", "xfs", "ntfs". + If not provided, the empty value is passed to the associated CSI driver + which will determine the default filesystem to apply. + type: string + nodePublishSecretRef: + description: |- + nodePublishSecretRef is a reference to the secret object containing + sensitive information to pass to the CSI driver to complete the CSI + NodePublishVolume and NodeUnpublishVolume calls. + This field is optional, and may be empty if no secret is required. If the + secret object contains more than one secret, all secret references are passed. + 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 + readOnly: + description: |- + readOnly specifies a read-only configuration for the volume. + Defaults to false (read/write). + type: boolean + volumeAttributes: + additionalProperties: + type: string + description: |- + volumeAttributes stores driver-specific properties that are passed to the CSI + driver. Consult your driver's documentation for supported values. + type: object + required: + - driver + type: object + downwardAPI: + description: downwardAPI represents downward API about the pod + that should populate this volume + properties: + defaultMode: + description: |- + Optional: mode bits to use on created files by default. Must be a + Optional: mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + items: + description: Items is a list of downward API volume file + items: + description: DownwardAPIVolumeFile represents information + to create the file containing the pod field + properties: + fieldRef: + description: 'Required: Selects a field of the pod: + only annotations, labels, name and namespace are + supported.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the + specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + description: |- + Optional: mode bits used to set permissions on this file, must be an octal value + between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: 'Required: Path is the relative path + name of the file to be created. Must not be absolute + or contain the ''..'' path. Must be utf-8 encoded. + The first item of the relative path must not start + with ''..''' + type: string + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported. + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the + exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + type: object + emptyDir: + description: |- + emptyDir represents a temporary directory that shares a pod's lifetime. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir + properties: + medium: + description: |- + medium represents what type of storage medium should back this directory. + The default is "" which means to use the node's default medium. + Must be an empty string (default) or Memory. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + description: |- + sizeLimit is the total amount of local storage required for this EmptyDir volume. + The size limit is also applicable for memory medium. + The maximum usage on memory medium EmptyDir would be the minimum value between + the SizeLimit specified here and the sum of memory limits of all containers in a pod. + The default is nil which means that the limit is undefined. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + description: |- + ephemeral represents a volume that is handled by a cluster storage driver. + The volume's lifecycle is tied to the pod that defines it - it will be created before the pod starts, + and deleted when the pod is removed. + + + Use this if: + a) the volume is only needed while the pod runs, + b) features of normal volumes like restoring from snapshot or capacity + tracking are needed, + c) the storage driver is specified through a storage class, and + d) the storage driver supports dynamic volume provisioning through + a PersistentVolumeClaim (see EphemeralVolumeSource for more + information on the connection between this volume type + and PersistentVolumeClaim). + + + Use PersistentVolumeClaim or one of the vendor-specific + APIs for volumes that persist for longer than the lifecycle + of an individual pod. + + + Use CSI for light-weight local ephemeral volumes if the CSI driver is meant to + be used that way - see the documentation of the driver for + more information. + + + A pod can use both types of ephemeral volumes and + persistent volumes at the same time. + properties: + volumeClaimTemplate: + description: |- + Will be used to create a stand-alone PVC to provision the volume. + The pod in which this EphemeralVolumeSource is embedded will be the + owner of the PVC, i.e. the PVC will be deleted together with the + pod. The name of the PVC will be `-` where + `` is the name from the `PodSpec.Volumes` array + entry. Pod validation will reject the pod if the concatenated name + is not valid for a PVC (for example, too long). + + + An existing PVC with that name that is not owned by the pod + will *not* be used for the pod to avoid using an unrelated + volume by mistake. Starting the pod is then blocked until + the unrelated PVC is removed. If such a pre-created PVC is + meant to be used by the pod, the PVC has to updated with an + owner reference to the pod once the pod exists. Normally + this should not be necessary, but it may be useful when + manually reconstructing a broken cluster. + + + This field is read-only and no changes will be made by Kubernetes + to the PVC after it has been created. + + + Required, must not be nil. + properties: + metadata: + description: |- + May contain labels and annotations that will be copied into the PVC + when creating it. No other fields are allowed and will be rejected during + validation. + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + description: |- + The specification for the PersistentVolumeClaim. The entire content is + copied unchanged into the PVC that gets created from this + template. The same fields as in a PersistentVolumeClaim + are also valid here. + properties: + accessModes: + description: |- + accessModes contains the desired access modes the volume should have. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1 + items: + type: string + type: array + dataSource: + description: |- + dataSource field can be used to specify either: + * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) + * An existing PVC (PersistentVolumeClaim) + If the provisioner or an external controller can support the specified data source, + it will create a new volume based on the contents of the specified data source. + When the AnyVolumeDataSource feature gate is enabled, dataSource contents will be copied to dataSourceRef, + and dataSourceRef contents will be copied to dataSource when dataSourceRef.namespace is not specified. + If the namespace is specified, then dataSourceRef will not be copied to dataSource. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being + referenced + type: string + name: + description: Name is the name of resource being + referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + description: |- + dataSourceRef specifies the object from which to populate the volume with data, if a non-empty + volume is desired. This may be any object from a non-empty API group (non + core object) or a PersistentVolumeClaim object. + When this field is specified, volume binding will only succeed if the type of + the specified object matches some installed volume populator or dynamic + provisioner. + This field will replace the functionality of the dataSource field and as such + if both fields are non-empty, they must have the same value. For backwards + compatibility, when namespace isn't specified in dataSourceRef, + both fields (dataSource and dataSourceRef) will be set to the same + value automatically if one of them is empty and the other is non-empty. + When namespace is specified in dataSourceRef, + dataSource isn't set to the same value and must be empty. + There are three important differences between dataSource and dataSourceRef: + * While dataSource only allows two specific types of objects, dataSourceRef + allows any non-core object, as well as PersistentVolumeClaim objects. + * While dataSource ignores disallowed values (dropping them), dataSourceRef + preserves all values, and generates an error if a disallowed value is + specified. + * While dataSource only allows local objects, dataSourceRef allows objects + in any namespaces. + (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled. + (Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being + referenced + type: string + name: + description: Name is the name of resource being + referenced + type: string + namespace: + description: |- + Namespace is the namespace of resource being referenced + Note that when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details. + (Alpha) This field requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + type: string + required: + - kind + - name + type: object + resources: + description: |- + resources represents the minimum resources the volume should have. + If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements + that are lower than previous value but must still be higher than capacity recorded in the + status field of the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + selector: + description: selector is a label query over volumes + to consider for binding. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + description: |- + storageClassName is the name of the StorageClass required by the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1 + type: string + volumeAttributesClassName: + description: |- + volumeAttributesClassName may be used to set the VolumeAttributesClass used by this claim. + If specified, the CSI driver will create or update the volume with the attributes defined + in the corresponding VolumeAttributesClass. This has a different purpose than storageClassName, + it can be changed after the claim is created. An empty string value means that no VolumeAttributesClass + will be applied to the claim but it's not allowed to reset this field to empty string once it is set. + If unspecified and the PersistentVolumeClaim is unbound, the default VolumeAttributesClass + will be set by the persistentvolume controller if it exists. + If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be + set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource + exists. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#volumeattributesclass + (Alpha) Using this field requires the VolumeAttributesClass feature gate to be enabled. + type: string + volumeMode: + description: |- + volumeMode defines what type of volume is required by the claim. + Value of Filesystem is implied when not included in claim spec. + type: string + volumeName: + description: volumeName is the binding reference + to the PersistentVolume backing this claim. + type: string + type: object + required: + - spec + type: object + type: object + fc: + description: fc represents a Fibre Channel resource that is + attached to a kubelet's host machine and then exposed to the + pod. + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + lun: + description: 'lun is Optional: FC target lun number' + format: int32 + type: integer + readOnly: + description: |- + readOnly is Optional: Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + targetWWNs: + description: 'targetWWNs is Optional: FC target worldwide + names (WWNs)' + items: + type: string + type: array + wwids: + description: |- + wwids Optional: FC volume world wide identifiers (wwids) + Either wwids or combination of targetWWNs and lun must be set, but not both simultaneously. + items: + type: string + type: array + type: object + flexVolume: + description: |- + flexVolume represents a generic volume resource that is + provisioned/attached using an exec based plugin. + properties: + driver: + description: driver is the name of the driver to use for + this volume. + type: string + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". The default filesystem depends on FlexVolume script. + type: string + options: + additionalProperties: + type: string + description: 'options is Optional: this field holds extra + command options if any.' + type: object + readOnly: + description: |- + readOnly is Optional: defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: |- + secretRef is Optional: secretRef is reference to the secret object containing + sensitive information to pass to the plugin scripts. This may be + empty if no secret object is specified. If the secret object + contains more than one secret, all secrets are passed to the plugin + scripts. + 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 + required: + - driver + type: object + flocker: + description: flocker represents a Flocker volume attached to + a kubelet's host machine. This depends on the Flocker control + service being running + properties: + datasetName: + description: |- + datasetName is Name of the dataset stored as metadata -> name on the dataset for Flocker + should be considered as deprecated + type: string + datasetUUID: + description: datasetUUID is the UUID of the dataset. This + is unique identifier of a Flocker dataset + type: string + type: object + gcePersistentDisk: + description: |- + gcePersistentDisk represents a GCE Disk resource that is attached to a + kubelet's host machine and then exposed to the pod. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + properties: + fsType: + description: |- + fsType is filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + partition: + description: |- + partition is the partition in the volume that you want to mount. + If omitted, the default is to mount by volume name. + Examples: For volume /dev/sda1, you specify the partition as "1". + Similarly, the volume partition for /dev/sda is "0" (or you can leave the property empty). + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + format: int32 + type: integer + pdName: + description: |- + pdName is unique name of the PD resource in GCE. Used to identify the disk in GCE. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + type: string + readOnly: + description: |- + readOnly here will force the ReadOnly setting in VolumeMounts. + Defaults to false. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + type: boolean + required: + - pdName + type: object + gitRepo: + description: |- + gitRepo represents a git repository at a particular revision. + DEPRECATED: GitRepo is deprecated. To provision a container with a git repo, mount an + EmptyDir into an InitContainer that clones the repo using git, then mount the EmptyDir + into the Pod's container. + properties: + directory: + description: |- + directory is the target directory name. + Must not contain or start with '..'. If '.' is supplied, the volume directory will be the + git repository. Otherwise, if specified, the volume will contain the git repository in + the subdirectory with the given name. + type: string + repository: + description: repository is the URL + type: string + revision: + description: revision is the commit hash for the specified + revision. + type: string + required: + - repository + type: object + glusterfs: + description: |- + glusterfs represents a Glusterfs mount on the host that shares a pod's lifetime. + More info: https://examples.k8s.io/volumes/glusterfs/README.md + properties: + endpoints: + description: |- + endpoints is the endpoint name that details Glusterfs topology. + More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod + type: string + path: + description: |- + path is the Glusterfs volume path. + More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod + type: string + readOnly: + description: |- + readOnly here will force the Glusterfs volume to be mounted with read-only permissions. + Defaults to false. + More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod + type: boolean + required: + - endpoints + - path + type: object + hostPath: + description: |- + hostPath represents a pre-existing file or directory on the host + machine that is directly exposed to the container. This is generally + used for system agents or other privileged things that are allowed + to see the host machine. Most containers will NOT need this. + More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + --- + TODO(jonesdl) We need to restrict who can use host directory mounts and who can/can not + mount host directories as read/write. + properties: + path: + description: |- + path of the directory on the host. + If the path is a symlink, it will follow the link to the real path. + More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + type: string + type: + description: |- + type for HostPath Volume + Defaults to "" + More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + type: string + required: + - path + type: object + iscsi: + description: |- + iscsi represents an ISCSI Disk resource that is attached to a + kubelet's host machine and then exposed to the pod. + More info: https://examples.k8s.io/volumes/iscsi/README.md + properties: + chapAuthDiscovery: + description: chapAuthDiscovery defines whether support iSCSI + Discovery CHAP authentication + type: boolean + chapAuthSession: + description: chapAuthSession defines whether support iSCSI + Session CHAP authentication + type: boolean + fsType: + description: |- + fsType is the filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#iscsi + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + initiatorName: + description: |- + initiatorName is the custom iSCSI Initiator Name. + If initiatorName is specified with iscsiInterface simultaneously, new iSCSI interface + : will be created for the connection. + type: string + iqn: + description: iqn is the target iSCSI Qualified Name. + type: string + iscsiInterface: + description: |- + iscsiInterface is the interface Name that uses an iSCSI transport. + Defaults to 'default' (tcp). + type: string + lun: + description: lun represents iSCSI Target Lun number. + format: int32 + type: integer + portals: + description: |- + portals is the iSCSI Target Portal List. The portal is either an IP or ip_addr:port if the port + is other than default (typically TCP ports 860 and 3260). + items: + type: string + type: array + readOnly: + description: |- + readOnly here will force the ReadOnly setting in VolumeMounts. + Defaults to false. + type: boolean + secretRef: + description: secretRef is the CHAP Secret for iSCSI target + and initiator authentication + 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 + targetPortal: + description: |- + targetPortal is iSCSI Target Portal. The Portal is either an IP or ip_addr:port if the port + is other than default (typically TCP ports 860 and 3260). + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + description: |- + name of the volume. + Must be a DNS_LABEL and unique within the pod. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + nfs: + description: |- + nfs represents an NFS mount on the host that shares a pod's lifetime + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + properties: + path: + description: |- + path that is exported by the NFS server. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + type: string + readOnly: + description: |- + readOnly here will force the NFS export to be mounted with read-only permissions. + Defaults to false. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + type: boolean + server: + description: |- + server is the hostname or IP address of the NFS server. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + description: |- + persistentVolumeClaimVolumeSource represents a reference to a + PersistentVolumeClaim in the same namespace. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims + properties: + claimName: + description: |- + claimName is the name of a PersistentVolumeClaim in the same namespace as the pod using this volume. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims + type: string + readOnly: + description: |- + readOnly Will force the ReadOnly setting in VolumeMounts. + Default false. + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + description: photonPersistentDisk represents a PhotonController + persistent disk attached and mounted on kubelets host machine + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + pdID: + description: pdID is the ID that identifies Photon Controller + persistent disk + type: string + required: + - pdID + type: object + portworxVolume: + description: portworxVolume represents a portworx volume attached + and mounted on kubelets host machine + properties: + fsType: + description: |- + fSType represents the filesystem type to mount + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs". Implicitly inferred to be "ext4" if unspecified. + type: string + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + volumeID: + description: volumeID uniquely identifies a Portworx volume + type: string + required: + - volumeID + type: object + projected: + description: projected items for all in one resources secrets, + configmaps, and downward API + properties: + defaultMode: + description: |- + defaultMode are the mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + sources: + description: sources is the list of volume projections + items: + description: Projection that may be projected along with + other supported volume types + properties: + clusterTrustBundle: + description: |- + ClusterTrustBundle allows a pod to access the `.spec.trustBundle` field + of ClusterTrustBundle objects in an auto-updating file. + + + Alpha, gated by the ClusterTrustBundleProjection feature gate. + + + ClusterTrustBundle objects can either be selected by name, or by the + combination of signer name and a label selector. + + + Kubelet performs aggressive normalization of the PEM contents written + into the pod filesystem. Esoteric PEM features such as inter-block + comments and block headers are stripped. Certificates are deduplicated. + The ordering of certificates within the file is arbitrary, and Kubelet + may change the order over time. + properties: + labelSelector: + description: |- + Select all ClusterTrustBundles that match this label selector. Only has + effect if signerName is set. Mutually-exclusive with name. If unset, + interpreted as "match nothing". If set but empty, interpreted as "match + everything". + properties: + matchExpressions: + description: matchExpressions is a list of + label selector requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + name: + description: |- + Select a single ClusterTrustBundle by object name. Mutually-exclusive + with signerName and labelSelector. + type: string + optional: + description: |- + If true, don't block pod startup if the referenced ClusterTrustBundle(s) + aren't available. If using name, then the named ClusterTrustBundle is + allowed not to exist. If using signerName, then the combination of + signerName and labelSelector is allowed to match zero + ClusterTrustBundles. + type: boolean + path: + description: Relative path from the volume root + to write the bundle. + type: string + signerName: + description: |- + Select all ClusterTrustBundles that match this signer name. + Mutually-exclusive with name. The contents of all selected + ClusterTrustBundles will be unified and deduplicated. + type: string + required: + - path + type: object + configMap: + description: configMap information about the configMap + data to project + properties: + items: + description: |- + items if unspecified, each key-value pair in the Data field of the referenced + ConfigMap will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the ConfigMap, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within + a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + 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 + optional: + description: optional specify whether the ConfigMap + or its keys must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + downwardAPI: + description: downwardAPI information about the downwardAPI + data to project + properties: + items: + description: Items is a list of DownwardAPIVolume + file + items: + description: DownwardAPIVolumeFile represents + information to create the file containing + the pod field + properties: + fieldRef: + description: 'Required: Selects a field + of the pod: only annotations, labels, + name and namespace are supported.' + properties: + apiVersion: + description: Version of the schema the + FieldPath is written in terms of, + defaults to "v1". + type: string + fieldPath: + description: Path of the field to select + in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + description: |- + Optional: mode bits used to set permissions on this file, must be an octal value + between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: 'Required: Path is the relative + path name of the file to be created. Must + not be absolute or contain the ''..'' + path. Must be utf-8 encoded. The first + item of the relative path must not start + with ''..''' + type: string + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported. + properties: + containerName: + description: 'Container name: required + for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format + of the exposed resources, defaults + to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to + select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + type: object + secret: + description: secret information about the secret data + to project + properties: + items: + description: |- + items if unspecified, each key-value pair in the Data field of the referenced + Secret will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the Secret, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within + a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + 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 + optional: + description: optional field specify whether the + Secret or its key must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + serviceAccountToken: + description: serviceAccountToken is information about + the serviceAccountToken data to project + properties: + audience: + description: |- + audience is the intended audience of the token. A recipient of a token + must identify itself with an identifier specified in the audience of the + token, and otherwise should reject the token. The audience defaults to the + identifier of the apiserver. + type: string + expirationSeconds: + description: |- + expirationSeconds is the requested duration of validity of the service + account token. As the token approaches expiration, the kubelet volume + plugin will proactively rotate the service account token. The kubelet will + start trying to rotate the token if the token is older than 80 percent of + its time to live or if the token is older than 24 hours.Defaults to 1 hour + and must be at least 10 minutes. + format: int64 + type: integer + path: + description: |- + path is the path relative to the mount point of the file to project the + token into. + type: string + required: + - path + type: object + type: object + type: array + type: object + quobyte: + description: quobyte represents a Quobyte mount on the host + that shares a pod's lifetime + properties: + group: + description: |- + group to map volume access to + Default is no group + type: string + readOnly: + description: |- + readOnly here will force the Quobyte volume to be mounted with read-only permissions. + Defaults to false. + type: boolean + registry: + description: |- + registry represents a single or multiple Quobyte Registry services + specified as a string as host:port pair (multiple entries are separated with commas) + which acts as the central registry for volumes + type: string + tenant: + description: |- + tenant owning the given Quobyte volume in the Backend + Used with dynamically provisioned Quobyte volumes, value is set by the plugin + type: string + user: + description: |- + user to map volume access to + Defaults to serivceaccount user + type: string + volume: + description: volume is a string that references an already + created Quobyte volume by name. + type: string + required: + - registry + - volume + type: object + rbd: + description: |- + rbd represents a Rados Block Device mount on the host that shares a pod's lifetime. + More info: https://examples.k8s.io/volumes/rbd/README.md + properties: + fsType: + description: |- + fsType is the filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#rbd + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + image: + description: |- + image is the rados image name. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + keyring: + description: |- + keyring is the path to key ring for RBDUser. + Default is /etc/ceph/keyring. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + monitors: + description: |- + monitors is a collection of Ceph monitors. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + items: + type: string + type: array + pool: + description: |- + pool is the rados pool name. + Default is rbd. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + readOnly: + description: |- + readOnly here will force the ReadOnly setting in VolumeMounts. + Defaults to false. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: boolean + secretRef: + description: |- + secretRef is name of the authentication secret for RBDUser. If provided + overrides keyring. + Default is nil. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + 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 + user: + description: |- + user is the rados user name. + Default is admin. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + required: + - image + - monitors + type: object + scaleIO: + description: scaleIO represents a ScaleIO persistent volume + attached and mounted on Kubernetes nodes. + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". + Default is "xfs". + type: string + gateway: + description: gateway is the host address of the ScaleIO + API Gateway. + type: string + protectionDomain: + description: protectionDomain is the name of the ScaleIO + Protection Domain for the configured storage. + type: string + readOnly: + description: |- + readOnly Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: |- + secretRef references to the secret for ScaleIO user and other + sensitive information. If this is not provided, Login operation will fail. + 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 + sslEnabled: + description: sslEnabled Flag enable/disable SSL communication + with Gateway, default false + type: boolean + storageMode: + description: |- + storageMode indicates whether the storage for a volume should be ThickProvisioned or ThinProvisioned. + Default is ThinProvisioned. + type: string + storagePool: + description: storagePool is the ScaleIO Storage Pool associated + with the protection domain. + type: string + system: + description: system is the name of the storage system as + configured in ScaleIO. + type: string + volumeName: + description: |- + volumeName is the name of a volume already created in the ScaleIO system + that is associated with this volume source. + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + description: |- + secret represents a secret that should populate this volume. + More info: https://kubernetes.io/docs/concepts/storage/volumes#secret + properties: + defaultMode: + description: |- + defaultMode is Optional: mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values + for mode bits. Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + items: + description: |- + items If unspecified, each key-value pair in the Data field of the referenced + Secret will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the Secret, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + optional: + description: optional field specify whether the Secret or + its keys must be defined + type: boolean + secretName: + description: |- + secretName is the name of the secret in the pod's namespace to use. + More info: https://kubernetes.io/docs/concepts/storage/volumes#secret + type: string + type: object + storageos: + description: storageOS represents a StorageOS volume attached + and mounted on Kubernetes nodes. + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: |- + secretRef specifies the secret to use for obtaining the StorageOS API + credentials. If not specified, default values will be attempted. + 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 + volumeName: + description: |- + volumeName is the human-readable name of the StorageOS volume. Volume + names are only unique within a namespace. + type: string + volumeNamespace: + description: |- + volumeNamespace specifies the scope of the volume within StorageOS. If no + namespace is specified then the Pod's namespace will be used. This allows the + Kubernetes name scoping to be mirrored within StorageOS for tighter integration. + Set VolumeName to any name to override the default behaviour. + Set to "default" if you are not using namespaces within StorageOS. + Namespaces that do not pre-exist within StorageOS will be created. + type: string + type: object + vsphereVolume: + description: vsphereVolume represents a vSphere volume attached + and mounted on kubelets host machine + properties: + fsType: + description: |- + fsType is filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + storagePolicyID: + description: storagePolicyID is the storage Policy Based + Management (SPBM) profile ID associated with the StoragePolicyName. + type: string + storagePolicyName: + description: storagePolicyName is the storage Policy Based + Management (SPBM) profile name. + type: string + volumePath: + description: volumePath is the path that identifies vSphere + volume vmdk + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + required: + - compDef + - replicas type: object status: - description: ComponentStatus defines the observed state of Component + description: ComponentStatus represents the observed state of a Component + within the Cluster. + properties: + conditions: + description: |- + Represents a list of detailed status of the Component object. + Each condition in the list provides real-time information about certain aspect of the Component object. + + + This field is crucial for administrators and developers to monitor and respond to changes within the Component. + It provides a history of state transitions and a snapshot of the current state that can be used for + automated logic or direct inspection. + items: + description: "Condition contains details for one aspect of the current + state of this API Resource.\n---\nThis struct is intended for + direct use as an array at the field path .status.conditions. For + example,\n\n\n\ttype FooStatus struct{\n\t // Represents the + observations of a foo's current state.\n\t // Known .status.conditions.type + are: \"Available\", \"Progressing\", and \"Degraded\"\n\t // + +patchMergeKey=type\n\t // +patchStrategy=merge\n\t // +listType=map\n\t + \ // +listMapKey=type\n\t Conditions []metav1.Condition `json:\"conditions,omitempty\" + patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t + \ // other fields\n\t}" + 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 + message: + additionalProperties: + type: string + description: |- + A map that stores detailed message about the Component. + Each entry in the map provides insights into specific elements of the Component, such as Pods or workloads. + + + Keys in this map are formatted as `ObjectKind/Name`, where `ObjectKind` could be a type like Pod, + and `Name` is the specific name of the object. + type: object + observedGeneration: + description: Specifies the most recent generation observed for this + Component object. + format: int64 + type: integer + phase: + description: |- + Indicates the current phase of the Component, with each phase indicating specific conditions: + + + - Creating: The initial phase for new Components, transitioning from 'empty'(""). + - Running: All Pods in a Running state. + - Updating: The Component is currently being updated, with no failed Pods present. + - Abnormal: Some Pods have failed, indicating a potentially unstable state. + However, the cluster remains available as long as a quorum of members is functioning. + - Failed: A significant number of Pods or critical Pods have failed + The cluster may be non-functional or may offer only limited services (e.g, read-only). + - Stopping: All Pods are being terminated, with current replica count at zero. + - Stopped: All associated Pods have been successfully deleted. + - Deleting: The Component is being deleted. + enum: + - Creating + - Running + - Updating + - Stopping + - Stopped + - Deleting + - Failed + - Abnormal + type: string type: object type: object served: true diff --git a/deploy/helm/crds/apps.kubeblocks.io_servicedescriptors.yaml b/deploy/helm/crds/apps.kubeblocks.io_servicedescriptors.yaml index 3b84dcb3e59..99d33d9eaff 100644 --- a/deploy/helm/crds/apps.kubeblocks.io_servicedescriptors.yaml +++ b/deploy/helm/crds/apps.kubeblocks.io_servicedescriptors.yaml @@ -11,6 +11,7 @@ spec: names: categories: - kubeblocks + - all kind: ServiceDescriptor listKind: ServiceDescriptorList plural: servicedescriptors diff --git a/docs/developer_docs/api-reference/cluster.md b/docs/developer_docs/api-reference/cluster.md index 3bbe9637eee..bf7da55424e 100644 --- a/docs/developer_docs/api-reference/cluster.md +++ b/docs/developer_docs/api-reference/cluster.md @@ -300,117 +300,7025 @@ ComponentSpec -
-foo
+compDef
string
-

Foo is an example field of Component. Edit component_types.go to remove/update

+

Specifies the name of the referenced ComponentDefinition.

+ + +serviceVersion
+ +string + + + +(Optional) +

ServiceVersion specifies the version of the Service expected to be provisioned by this Component. +The version should follow the syntax and semantics of the “Semantic Versioning” specification (http://semver.org/).

-status
+serviceRefs
- -ComponentStatus + +[]ServiceRef - - - - -

ComponentDefinition -

-
-

ComponentDefinition serves as a reusable blueprint for creating Components, -encapsulating essential static settings such as Component description, -Pod templates, configuration file templates, scripts, parameter lists, -injected environment variables and their sources, and event handlers. -ComponentDefinition works in conjunction with dynamic settings from the ClusterComponentSpec, -to instantiate Components during Cluster creation.

-

Key aspects that can be defined in a ComponentDefinition include:

+(Optional) +

Defines a list of ServiceRef for a Component, enabling access to both external services and +Services provided by other Clusters.

+

Types of services:

    -
  • PodSpec template: Specifies the PodSpec template used by the Component.
  • -
  • Configuration templates: Specify the configuration file templates required by the Component.
  • -
  • Scripts: Provide the necessary scripts for Component management and operations.
  • -
  • Storage volumes: Specify the storage volumes and their configurations for the Component.
  • -
  • Pod roles: Outlines various roles of Pods within the Component along with their capabilities.
  • -
  • Exposed Kubernetes Services: Specify the Services that need to be exposed by the Component.
  • -
  • System accounts: Define the system accounts required for the Component.
  • -
  • Monitoring and logging: Configure the exporter and logging settings for the Component.
  • +
  • External services: Not managed by KubeBlocks or managed by a different KubeBlocks operator; +Require a ServiceDescriptor for connection details.
  • +
  • Services provided by a Cluster: Managed by the same KubeBlocks operator; +identified using Cluster, Component and Service names.
-

ComponentDefinitions also enable defining reactive behaviors of the Component in response to events, -such as member join/leave, Component addition/deletion, role changes, switch over, and more. -This allows for automatic event handling, thus encapsulating complex behaviors within the Component.

-

Referencing a ComponentDefinition when creating individual Components ensures inheritance of predefined configurations, -promoting reusability and consistency across different deployments and cluster topologies.

-
- - +

ServiceRefs with identical serviceRef.name in the same Cluster are considered the same.

+

Example:

+
serviceRefs:
+  - name: "redis-sentinel"
+    serviceDescriptor:
+      name: "external-redis-sentinel"
+  - name: "postgres-cluster"
+    clusterServiceSelector:
+      cluster: "my-postgres-cluster"
+      service:
+        component: "postgresql"
+
+

The example above includes ServiceRefs to an external Redis Sentinel service and a PostgreSQL Cluster.

+ + - - + + - - +annotations
+ +map[string]string + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription +labels
+ +map[string]string + +
+(Optional) +

Specifies Labels to override or add for underlying Pods.

+
-apiVersion
-string
-apps.kubeblocks.io/v1 +(Optional) +

Specifies Annotations to override or add for underlying Pods.

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

List of environment variables to add.

+
+resources
+ + +Kubernetes core/v1.ResourceRequirements + + +
+(Optional) +

Specifies the resources required by the Component. +It allows defining the CPU, memory requirements and limits for the Component’s containers.

+
+volumeClaimTemplates
+ + +[]ClusterComponentVolumeClaimTemplate + + +
+(Optional) +

Specifies a list of PersistentVolumeClaim templates that define the storage requirements for the Component. +Each template specifies the desired characteristics of a persistent volume, such as storage class, +size, and access modes. +These templates are used to dynamically provision persistent volumes for the Component.

+
+volumes
+ + +[]Kubernetes core/v1.Volume + + +
+(Optional) +

List of volumes to override.

+
+services
+ + +[]ComponentService + + +
+(Optional) +

Overrides Services defined in referenced ComponentDefinition and exposes endpoints that can be accessed +by clients.

+
+systemAccounts
+ + +[]ComponentSystemAccount + + +
+(Optional) +

Overrides system accounts defined in referenced ComponentDefinition.

+
+replicas
+ +int32 + +
+

Specifies the desired number of replicas in the Component for enhancing availability and durability, or load balancing.

+
+configs
+ + +[]ClusterComponentConfig + + +
+(Optional) +

Specifies the configuration content of a config template.

+
+enabledLogs
+ +[]string + +
+(Optional) +

Specifies which types of logs should be collected for the Cluster. +The log types are defined in the componentDefinition.spec.logConfigs field with the LogConfig entries.

+

The elements in the enabledLogs array correspond to the names of the LogConfig entries. +For example, if the componentDefinition.spec.logConfigs defines LogConfig entries with +names “slow_query_log” and “error_log”, +you can enable the collection of these logs by including their names in the enabledLogs array:

+
enabledLogs:
+- slow_query_log
+- error_log
+
+
+serviceAccountName
+ string + +
+(Optional) +

Specifies the name of the ServiceAccount required by the running Component. +This ServiceAccount is used to grant necessary permissions for the Component’s Pods to interact +with other Kubernetes resources, such as modifying Pod labels or sending events.

+

Defaults: +If not specified, KubeBlocks automatically assigns a default ServiceAccount named “kb-{cluster.name}”, +bound to a default role defined during KubeBlocks installation.

+

Future Changes: +Future versions might change the default ServiceAccount creation strategy to one per Component, +potentially revising the naming to “kb-{cluster.name}-{component.name}”.

+

Users can override the automatic ServiceAccount assignment by explicitly setting the name of +an existed ServiceAccount in this field.

+
+parallelPodManagementConcurrency
+ + +Kubernetes api utils intstr.IntOrString + + +
+(Optional) +

Controls the concurrency of pods during initial scale up, when replacing pods on nodes, +or when scaling down. It only used when PodManagementPolicy is set to Parallel. +The default Concurrency is 100%.

+
+podUpdatePolicy
+ + +PodUpdatePolicyType + + +
+(Optional) +

PodUpdatePolicy indicates how pods should be updated

+
    +
  • StrictInPlace indicates that only allows in-place upgrades. +Any attempt to modify other fields will be rejected.
  • +
  • PreferInPlace indicates that we will first attempt an in-place upgrade of the Pod. +If that fails, it will fall back to the ReCreate, where pod will be recreated. +Default value is “PreferInPlace”
  • +
+
+schedulingPolicy
+ + +SchedulingPolicy + + +
+(Optional) +

Specifies the scheduling policy for the Component.

+
+tlsConfig
+ + +TLSConfig + + +
+(Optional) +

Specifies the TLS configuration for the Component, including:

+
    +
  • A boolean flag that indicates whether the Component should use Transport Layer Security (TLS) for secure communication.
  • +
  • An optional field that specifies the configuration for the TLS certificates issuer when TLS is enabled. +It allows defining the issuer name and the reference to the secret containing the TLS certificates and key. +The secret should contain the CA certificate, TLS certificate, and private key in the specified keys.
  • +
+
+instances
+ + +[]InstanceTemplate + + +
+(Optional) +

Allows for the customization of configuration values for each instance within a Component. +An Instance represent a single replica (Pod and associated K8s resources like PVCs, Services, and ConfigMaps). +While instances typically share a common configuration as defined in the ClusterComponentSpec, +they can require unique settings in various scenarios:

+

For example: +- A database Component might require different resource allocations for primary and secondary instances, + with primaries needing more resources. +- During a rolling upgrade, a Component may first update the image for one or a few instances, +and then update the remaining instances after verifying that the updated instances are functioning correctly.

+

InstanceTemplate allows for specifying these unique configurations per instance. +Each instance’s name is constructed using the pattern: $(component.name)-$(template.name)-$(ordinal), +starting with an ordinal of 0. +It is crucial to maintain unique names for each InstanceTemplate to avoid conflicts.

+

The sum of replicas across all InstanceTemplates should not exceed the total number of Replicas specified for the Component. +Any remaining replicas will be generated using the default template and will follow the default naming rules.

+
+offlineInstances
+ +[]string + +
+(Optional) +

Specifies the names of instances to be transitioned to offline status.

+

Marking an instance as offline results in the following:

+
    +
  1. The associated Pod is stopped, and its PersistentVolumeClaim (PVC) is retained for potential +future reuse or data recovery, but it is no longer actively used.
  2. +
  3. The ordinal number assigned to this instance is preserved, ensuring it remains unique +and avoiding conflicts with new instances.
  4. +
+

Setting instances to offline allows for a controlled scale-in process, preserving their data and maintaining +ordinal consistency within the Cluster. +Note that offline instances and their associated resources, such as PVCs, are not automatically deleted. +The administrator must manually manage the cleanup and removal of these resources when they are no longer needed.

+
+runtimeClassName
+ +string + +
+(Optional) +

Defines runtimeClassName for all Pods managed by this Component.

+
+disableExporter
+ +bool + +
+(Optional) +

Determines whether metrics exporter information is annotated on the Component’s headless Service.

+

If set to true, the following annotations will not be patched into the Service:

+
    +
  • “monitor.kubeblocks.io/path”
  • +
  • “monitor.kubeblocks.io/port”
  • +
  • “monitor.kubeblocks.io/scheme”
  • +
+

These annotations allow the Prometheus installed by KubeBlocks to discover and scrape metrics from the exporter.

+
+stop
+ +bool + +
+(Optional) +

Stop the Component. +If set, all the computing resources will be released.

+
+ + + + +status
+ + +ComponentStatus + + + + + + + + +

ComponentDefinition +

+
+

ComponentDefinition serves as a reusable blueprint for creating Components, +encapsulating essential static settings such as Component description, +Pod templates, configuration file templates, scripts, parameter lists, +injected environment variables and their sources, and event handlers. +ComponentDefinition works in conjunction with dynamic settings from the ClusterComponentSpec, +to instantiate Components during Cluster creation.

+

Key aspects that can be defined in a ComponentDefinition include:

+
    +
  • PodSpec template: Specifies the PodSpec template used by the Component.
  • +
  • Configuration templates: Specify the configuration file templates required by the Component.
  • +
  • Scripts: Provide the necessary scripts for Component management and operations.
  • +
  • Storage volumes: Specify the storage volumes and their configurations for the Component.
  • +
  • Pod roles: Outlines various roles of Pods within the Component along with their capabilities.
  • +
  • Exposed Kubernetes Services: Specify the Services that need to be exposed by the Component.
  • +
  • System accounts: Define the system accounts required for the Component.
  • +
  • Monitoring and logging: Configure the exporter and logging settings for the Component.
  • +
+

ComponentDefinitions also enable defining reactive behaviors of the Component in response to events, +such as member join/leave, Component addition/deletion, role changes, switch over, and more. +This allows for automatic event handling, thus encapsulating complex behaviors within the Component.

+

Referencing a ComponentDefinition when creating individual Components ensures inheritance of predefined configurations, +promoting reusability and consistency across different deployments and cluster topologies.

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+apiVersion
+string
+apps.kubeblocks.io/v1 +
+kind
+string +
ComponentDefinition
+metadata
+ + +Kubernetes meta/v1.ObjectMeta + + +
+Refer to the Kubernetes API documentation for the fields of the +metadata field. +
+spec
+ + +ComponentDefinitionSpec + + +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+provider
+ +string + +
+(Optional) +

Specifies the name of the Component provider, typically the vendor or developer name. +It identifies the entity responsible for creating and maintaining the Component.

+

When specifying the provider name, consider the following guidelines:

+
    +
  • Keep the name concise and relevant to the Component.
  • +
  • Use a consistent naming convention across Components from the same provider.
  • +
  • Avoid using trademarked or copyrighted names without proper permission.
  • +
+
+description
+ +string + +
+(Optional) +

Provides a brief and concise explanation of the Component’s purpose, functionality, and any relevant details. +It serves as a quick reference for users to understand the Component’s role and characteristics.

+
+serviceKind
+ +string + +
+(Optional) +

Defines the type of well-known service protocol that the Component provides. +It specifies the standard or widely recognized protocol used by the Component to offer its Services.

+

The serviceKind field allows users to quickly identify the type of Service provided by the Component +based on common protocols or service types. This information helps in understanding the compatibility, +interoperability, and usage of the Component within a system.

+

Some examples of well-known service protocols include:

+
    +
  • “MySQL”: Indicates that the Component provides a MySQL database service.
  • +
  • “PostgreSQL”: Indicates that the Component offers a PostgreSQL database service.
  • +
  • “Redis”: Signifies that the Component functions as a Redis key-value store.
  • +
  • “ETCD”: Denotes that the Component serves as an ETCD distributed key-value store.
  • +
+

The serviceKind value is case-insensitive, allowing for flexibility in specifying the protocol name.

+

When specifying the serviceKind, consider the following guidelines:

+
    +
  • Use well-established and widely recognized protocol names or service types.
  • +
  • Ensure that the serviceKind accurately represents the primary service type offered by the Component.
  • +
  • If the Component provides multiple services, choose the most prominent or commonly used protocol.
  • +
  • Limit the serviceKind to a maximum of 32 characters for conciseness and readability.
  • +
+

Note: The serviceKind field is optional and can be left empty if the Component does not fit into a well-known +service category or if the protocol is not widely recognized. It is primarily used to convey information about +the Component’s service type to users and facilitate discovery and integration.

+

The serviceKind field is immutable and cannot be updated.

+
+serviceVersion
+ +string + +
+(Optional) +

Specifies the version of the Service provided by the Component. +It follows the syntax and semantics of the “Semantic Versioning” specification (http://semver.org/).

+

The Semantic Versioning specification defines a version number format of X.Y.Z (MAJOR.MINOR.PATCH), where:

+
    +
  • X represents the major version and indicates incompatible API changes.
  • +
  • Y represents the minor version and indicates added functionality in a backward-compatible manner.
  • +
  • Z represents the patch version and indicates backward-compatible bug fixes.
  • +
+

Additional labels for pre-release and build metadata are available as extensions to the X.Y.Z format:

+
    +
  • Use pre-release labels (e.g., -alpha, -beta) for versions that are not yet stable or ready for production use.
  • +
  • Use build metadata (e.g., +build.1) for additional version information if needed.
  • +
+

Examples of valid ServiceVersion values:

+
    +
  • “1.0.0”
  • +
  • “2.3.1”
  • +
  • “3.0.0-alpha.1”
  • +
  • “4.5.2+build.1”
  • +
+

The serviceVersion field is immutable and cannot be updated.

+
+labels
+ +map[string]string + +
+(Optional) +

Specifies static labels that will be patched to all Kubernetes resources created for the Component.

+

Note: If a label key in the labels field conflicts with any system labels or user-specified labels, +it will be silently ignored to avoid overriding higher-priority labels.

+

This field is immutable.

+
+annotations
+ +map[string]string + +
+(Optional) +

Specifies static annotations that will be patched to all Kubernetes resources created for the Component.

+

Note: If an annotation key in the annotations field conflicts with any system annotations +or user-specified annotations, it will be silently ignored to avoid overriding higher-priority annotations.

+

This field is immutable.

+
+runtime
+ + +Kubernetes core/v1.PodSpec + + +
+

Specifies the PodSpec template used in the Component. +It includes the following elements:

+
    +
  • Init containers
  • +
  • Containers +
      +
    • Image
    • +
    • Commands
    • +
    • Args
    • +
    • Envs
    • +
    • Mounts
    • +
    • Ports
    • +
    • Security context
    • +
    • Probes
    • +
    • Lifecycle
    • +
  • +
  • Volumes
  • +
+

This field is intended to define static settings that remain consistent across all instantiated Components. +Dynamic settings such as CPU and memory resource limits, as well as scheduling settings (affinity, +toleration, priority), may vary among different instantiated Components. +They should be specified in the cluster.spec.componentSpecs (ClusterComponentSpec).

+

Specific instances of a Component may override settings defined here, such as using a different container image +or modifying environment variable values. +These instance-specific overrides can be specified in cluster.spec.componentSpecs[*].instances.

+

This field is immutable and cannot be updated once set.

+
+vars
+ + +[]EnvVar + + +
+(Optional) +

Defines variables which are determined after Cluster instantiation and reflect +dynamic or runtime attributes of instantiated Clusters. +These variables serve as placeholders for setting environment variables in Pods and Actions, +or for rendering configuration and script templates before actual values are finalized.

+

These variables are placed in front of the environment variables declared in the Pod if used as +environment variables.

+

Variable values can be sourced from:

+
    +
  • ConfigMap: Select and extract a value from a specific key within a ConfigMap.
  • +
  • Secret: Select and extract a value from a specific key within a Secret.
  • +
  • HostNetwork: Retrieves values (including ports) from host-network resources.
  • +
  • Service: Retrieves values (including address, port, NodePort) from a selected Service. +Intended to obtain the address of a ComponentService within the same Cluster.
  • +
  • Credential: Retrieves account name and password from a SystemAccount variable.
  • +
  • ServiceRef: Retrieves address, port, account name and password from a selected ServiceRefDeclaration. +Designed to obtain the address bound to a ServiceRef, such as a ClusterService or +ComponentService of another cluster or an external service.
  • +
  • Component: Retrieves values from a selected Component, including replicas and instance name list.
  • +
+

This field is immutable.

+
+volumes
+ + +[]ComponentVolume + + +
+(Optional) +

Defines the volumes used by the Component and some static attributes of the volumes. +After defining the volumes here, user can reference them in the +cluster.spec.componentSpecs[*].volumeClaimTemplates field to configure dynamic properties such as +volume capacity and storage class.

+

This field allows you to specify the following:

+
    +
  • Snapshot behavior: Determines whether a snapshot of the volume should be taken when performing +a snapshot backup of the Component.
  • +
  • Disk high watermark: Sets the high watermark for the volume’s disk usage. +When the disk usage reaches the specified threshold, it triggers an alert or action.
  • +
+

By configuring these volume behaviors, you can control how the volumes are managed and monitored within the Component.

+

This field is immutable.

+
+hostNetwork
+ + +HostNetwork + + +
+(Optional) +

Specifies the host network configuration for the Component.

+

When hostNetwork option is enabled, the Pods share the host’s network namespace and can directly access +the host’s network interfaces. +This means that if multiple Pods need to use the same port, they cannot run on the same host simultaneously +due to port conflicts.

+

The DNSPolicy field in the Pod spec determines how containers within the Pod perform DNS resolution. +When using hostNetwork, the operator will set the DNSPolicy to ‘ClusterFirstWithHostNet’. +With this policy, DNS queries will first go through the K8s cluster’s DNS service. +If the query fails, it will fall back to the host’s DNS settings.

+

If set, the DNS policy will be automatically set to “ClusterFirstWithHostNet”.

+

This field is immutable.

+
+services
+ + +[]ComponentService + + +
+(Optional) +

Defines additional Services to expose the Component’s endpoints.

+

A default headless Service, named {cluster.name}-{component.name}-headless, is automatically created +for internal Cluster communication.

+

This field enables customization of additional Services to expose the Component’s endpoints to +other Components within the same or different Clusters, and to external applications. +Each Service entry in this list can include properties such as ports, type, and selectors.

+
    +
  • For intra-Cluster access, Components can reference Services using variables declared in +componentDefinition.spec.vars[*].valueFrom.serviceVarRef.
  • +
  • For inter-Cluster access, reference Services use variables declared in +componentDefinition.spec.vars[*].valueFrom.serviceRefVarRef, +and bind Services at Cluster creation time with clusterComponentSpec.ServiceRef[*].clusterServiceSelector.
  • +
+

This field is immutable.

+
+configs
+ + +[]ComponentConfigSpec + + +
+(Optional) +

Specifies the configuration file templates and volume mount parameters used by the Component. +It also includes descriptions of the parameters in the ConfigMaps, such as value range limitations.

+

This field specifies a list of templates that will be rendered into Component containers’ configuration files. +Each template is represented as a ConfigMap and may contain multiple configuration files, +with each file being a key in the ConfigMap.

+

The rendered configuration files will be mounted into the Component’s containers +according to the specified volume mount parameters.

+

This field is immutable.

+
+logConfigs
+ + +[]LogConfig + + +
+(Optional) +

Defines the types of logs generated by instances of the Component and their corresponding file paths. +These logs can be collected for further analysis and monitoring.

+

The logConfigs field is an optional list of LogConfig objects, where each object represents +a specific log type and its configuration. +It allows you to specify multiple log types and their respective file paths for the Component.

+

Examples:

+
 logConfigs:
+ - filePathPattern: /data/mysql/log/mysqld-error.log
+   name: error
+ - filePathPattern: /data/mysql/log/mysqld.log
+   name: general
+ - filePathPattern: /data/mysql/log/mysqld-slowquery.log
+   name: slow
+
+

This field is immutable.

+
+scripts
+ + +[]ComponentTemplateSpec + + +
+(Optional) +

Specifies groups of scripts, each provided via a ConfigMap, to be mounted as volumes in the container. +These scripts can be executed during container startup or via specific actions.

+

Each script group is encapsulated in a ComponentTemplateSpec that includes:

+
    +
  • The ConfigMap containing the scripts.
  • +
  • The mount point where the scripts will be mounted inside the container.
  • +
+

This field is immutable.

+
+systemAccounts
+ + +[]SystemAccount + + +
+(Optional) +

An array of SystemAccount objects that define the system accounts needed +for the management operations of the Component.

+

Each SystemAccount includes:

+
    +
  • Account name.
  • +
  • The SQL statement template: Used to create the system account.
  • +
  • Password Source: Either generated based on certain rules or retrieved from a Secret.
  • +
+

Use cases for system accounts typically involve tasks like system initialization, backups, monitoring, +health checks, replication, and other system-level operations.

+

System accounts are distinct from user accounts, although both are database accounts.

+
    +
  • System Accounts: Created during Cluster setup by the KubeBlocks operator, +these accounts have higher privileges for system management and are fully managed +through a declarative API by the operator.
  • +
  • User Accounts: Managed by users or administrator. +User account permissions should follow the principle of least privilege, +granting only the necessary access rights to complete their required tasks.
  • +
+

This field is immutable.

+
+replicasLimit
+ + +ReplicasLimit + + +
+(Optional) +

Defines the upper limit of the number of replicas supported by the Component.

+

It defines the maximum number of replicas that can be created for the Component. +This field allows you to set a limit on the scalability of the Component, preventing it from exceeding a certain number of replicas.

+

This field is immutable.

+
+roles
+ + +[]ReplicaRole + + +
+(Optional) +

Enumerate all possible roles assigned to each replica of the Component, influencing its behavior.

+

A replica can have zero to multiple roles. +KubeBlocks operator determines the roles of each replica by invoking the lifecycleActions.roleProbe method. +This action returns a list of roles for each replica, and the returned roles must be predefined in the roles field.

+

The roles assigned to a replica can influence various aspects of the Component’s behavior, such as:

+
    +
  • Service selection: The Component’s exposed Services may target replicas based on their roles using roleSelector.
  • +
  • Update order: The roles can determine the order in which replicas are updated during a Component update. +For instance, replicas with a “follower” role can be updated first, while the replica with the “leader” +role is updated last. This helps minimize the number of leader changes during the update process.
  • +
+

This field is immutable.

+
+minReadySeconds
+ +int32 + +
+(Optional) +

minReadySeconds is the minimum duration in seconds that a new Pod should remain in the ready +state without any of its containers crashing to be considered available. +This ensures the Pod’s stability and readiness to serve requests.

+

A default value of 0 seconds means the Pod is considered available as soon as it enters the ready state.

+
+updateStrategy
+ + +UpdateStrategy + + +
+(Optional) +

Specifies the concurrency strategy for updating multiple instances of the Component. +Available strategies:

+
    +
  • Serial: Updates replicas one at a time, ensuring minimal downtime by waiting for each replica to become ready +before updating the next.
  • +
  • Parallel: Updates all replicas simultaneously, optimizing for speed but potentially reducing availability +during the update.
  • +
  • BestEffortParallel: Updates replicas concurrently with a limit on simultaneous updates to ensure a minimum +number of operational replicas for maintaining quorum. + For example, in a 5-replica component, updating a maximum of 2 replicas simultaneously keeps +at least 3 operational for quorum.
  • +
+

This field is immutable and defaults to ‘Serial’.

+
+podManagementPolicy
+ + +Kubernetes apps/v1.PodManagementPolicyType + + +
+(Optional) +

InstanceSet controls the creation of pods during initial scale up, replacement of pods on nodes, and scaling down.

+
    +
  • OrderedReady: Creates pods in increasing order (pod-0, then pod-1, etc). The controller waits until each pod +is ready before continuing. Pods are removed in reverse order when scaling down.
  • +
  • Parallel: Creates pods in parallel to match the desired scale without waiting. All pods are deleted at once +when scaling down.
  • +
+
+policyRules
+ + +[]Kubernetes rbac/v1.PolicyRule + + +
+(Optional) +

Defines the namespaced policy rules required by the Component.

+

The policyRules field is an array of rbacv1.PolicyRule objects that define the policy rules +needed by the Component to operate within a namespace. +These policy rules determine the permissions and verbs the Component is allowed to perform on +Kubernetes resources within the namespace.

+

The purpose of this field is to automatically generate the necessary RBAC roles +for the Component based on the specified policy rules. +This ensures that the Pods in the Component has appropriate permissions to function.

+

Note: This field is currently non-functional and is reserved for future implementation.

+

This field is immutable.

+
+lifecycleActions
+ + +ComponentLifecycleActions + + +
+(Optional) +

Defines a set of hooks and procedures that customize the behavior of a Component throughout its lifecycle. +Actions are triggered at specific lifecycle stages:

+
    +
  • postProvision: Defines the hook to be executed after the creation of a Component, +with preCondition specifying when the action should be fired relative to the Component’s lifecycle stages: +Immediately, RuntimeReady, ComponentReady, and ClusterReady.
  • +
  • preTerminate: Defines the hook to be executed before terminating a Component.
  • +
  • roleProbe: Defines the procedure which is invoked regularly to assess the role of replicas.
  • +
  • switchover: Defines the procedure for a controlled transition of leadership from the current leader to a new replica. +This approach aims to minimize downtime and maintain availability in systems with a leader-follower topology, +such as before planned maintenance or upgrades on the current leader node.
  • +
  • memberJoin: Defines the procedure to add a new replica to the replication group.
  • +
  • memberLeave: Defines the method to remove a replica from the replication group.
  • +
  • readOnly: Defines the procedure to switch a replica into the read-only state.
  • +
  • readWrite: transition a replica from the read-only state back to the read-write state.
  • +
  • dataDump: Defines the procedure to export the data from a replica.
  • +
  • dataLoad: Defines the procedure to import data into a replica.
  • +
  • reconfigure: Defines the procedure that update a replica with new configuration file.
  • +
  • accountProvision: Defines the procedure to generate a new database account.
  • +
+

This field is immutable.

+
+serviceRefDeclarations
+ + +[]ServiceRefDeclaration + + +
+(Optional) +

Lists external service dependencies of the Component, including services from other Clusters or outside the K8s environment.

+

This field is immutable.

+
+exporter
+ + +Exporter + + +
+(Optional) +

Defines the built-in metrics exporter container.

+
+
+status
+ + +ComponentDefinitionStatus + + +
+
+

ComponentVersion +

+
+

ComponentVersion is the Schema for the componentversions API

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+apiVersion
+string
+apps.kubeblocks.io/v1 +
+kind
+string +
ComponentVersion
+metadata
+ + +Kubernetes meta/v1.ObjectMeta + + +
+Refer to the Kubernetes API documentation for the fields of the +metadata field. +
+spec
+ + +ComponentVersionSpec + + +
+
+
+ + + + + + + + + +
+compatibilityRules
+ + +[]ComponentVersionCompatibilityRule + + +
+

CompatibilityRules defines compatibility rules between sets of component definitions and releases.

+
+releases
+ + +[]ComponentVersionRelease + + +
+

Releases represents different releases of component instances within this ComponentVersion.

+
+
+status
+ + +ComponentVersionStatus + + +
+
+

ServiceDescriptor +

+
+

ServiceDescriptor describes a service provided by external sources. +It contains the necessary details such as the service’s address and connection credentials. +To enable a Cluster to access this service, the ServiceDescriptor’s name should be specified +in the Cluster configuration under clusterComponent.serviceRefs[*].serviceDescriptor.

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+apiVersion
+string
+apps.kubeblocks.io/v1 +
+kind
+string +
ServiceDescriptor
+metadata
+ + +Kubernetes meta/v1.ObjectMeta + + +
+Refer to the Kubernetes API documentation for the fields of the +metadata field. +
+spec
+ + +ServiceDescriptorSpec + + +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+serviceKind
+ +string + +
+

Describes the type of database service provided by the external service. +For example, “mysql”, “redis”, “mongodb”. +This field categorizes databases by their functionality, protocol and compatibility, facilitating appropriate +service integration based on their unique capabilities.

+

This field is case-insensitive.

+

It also supports abbreviations for some well-known databases: +- “pg”, “pgsql”, “postgres”, “postgresql”: PostgreSQL service +- “zk”, “zookeeper”: ZooKeeper service +- “es”, “elasticsearch”: Elasticsearch service +- “mongo”, “mongodb”: MongoDB service +- “ch”, “clickhouse”: ClickHouse service

+
+serviceVersion
+ +string + +
+

Describes the version of the service provided by the external service. +This is crucial for ensuring compatibility between different components of the system, +as different versions of a service may have varying features.

+
+endpoint
+ + +CredentialVar + + +
+(Optional) +

Specifies the endpoint of the external service.

+

If the service is exposed via a cluster, the endpoint will be provided in the format of host:port.

+
+host
+ + +CredentialVar + + +
+(Optional) +

Specifies the service or IP address of the external service.

+
+port
+ + +CredentialVar + + +
+(Optional) +

Specifies the port of the external service.

+
+auth
+ + +ConnectionCredentialAuth + + +
+(Optional) +

Specifies the authentication credentials required for accessing an external service.

+
+
+status
+ + +ServiceDescriptorStatus + + +
+
+

Action +

+

+(Appears on:ComponentLifecycleActions, Probe) +

+
+

Action defines a customizable hook or procedure tailored for different database engines, +designed to be invoked at predetermined points within the lifecycle of a Component instance. +It provides a modular and extensible way to customize a Component’s behavior through the execution of defined actions.

+

Available Action triggers include:

+
    +
  • postProvision: Defines the hook to be executed after the creation of a Component, +with preCondition specifying when the action should be fired relative to the Component’s lifecycle stages: +Immediately, RuntimeReady, ComponentReady, and ClusterReady.
  • +
  • preTerminate: Defines the hook to be executed before terminating a Component.
  • +
  • roleProbe: Defines the procedure which is invoked regularly to assess the role of replicas.
  • +
  • switchover: Defines the procedure for a controlled transition of leadership from the current leader to a new replica. +This approach aims to minimize downtime and maintain availability in systems with a leader-follower topology, +such as during planned maintenance or upgrades on the current leader node.
  • +
  • memberJoin: Defines the procedure to add a new replica to the replication group.
  • +
  • memberLeave: Defines the method to remove a replica from the replication group.
  • +
  • readOnly: Defines the procedure to switch a replica into the read-only state.
  • +
  • readWrite: Defines the procedure to transition a replica from the read-only state back to the read-write state.
  • +
  • dataDump: Defines the procedure to export the data from a replica.
  • +
  • dataLoad: Defines the procedure to import data into a replica.
  • +
  • reconfigure: Defines the procedure that update a replica with new configuration.
  • +
  • accountProvision: Defines the procedure to generate a new database account.
  • +
+

Actions can be executed in different ways:

+
    +
  • ExecAction: Executes a command inside a container. +A set of predefined environment variables are available and can be leveraged within the exec.command +to access context information such as details about pods, components, the overall cluster state, +or database connection credentials. +These variables provide a dynamic and context-aware mechanism for script execution.
  • +
  • HTTPAction: Performs an HTTP request. +HTTPAction is to be implemented in future version.
  • +
  • GRPCAction: In future version, Actions will support initiating gRPC calls. +This allows developers to implement Actions using plugins written in programming language like Go, +providing greater flexibility and extensibility.
  • +
+

An action is considered successful on returning 0, or HTTP 200 for status HTTP(s) Actions. +Any other return value or HTTP status codes indicate failure, +and the action may be retried based on the configured retry policy.

+
    +
  • If an action exceeds the specified timeout duration, it will be terminated, and the action is considered failed.
  • +
  • If an action produces any data as output, it should be written to stdout, +or included in the HTTP response payload for HTTP(s) actions.
  • +
  • If an action encounters any errors, error messages should be written to stderr, +or detailed in the HTTP response with the appropriate non-200 status code.
  • +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+exec
+ + +ExecAction + + +
+(Optional) +

Defines the command to run.

+

This field cannot be updated.

+
+timeoutSeconds
+ +int32 + +
+(Optional) +

Specifies the maximum duration in seconds that the Action is allowed to run.

+

If the Action does not complete within this time frame, it will be terminated.

+

This field cannot be updated.

+
+retryPolicy
+ + +RetryPolicy + + +
+(Optional) +

Defines the strategy to be taken when retrying the Action after a failure.

+

It specifies the conditions under which the Action should be retried and the limits to apply, +such as the maximum number of retries and backoff strategy.

+

This field cannot be updated.

+
+preCondition
+ + +PreConditionType + + +
+(Optional) +

Specifies the state that the cluster must reach before the Action is executed. +Currently, this is only applicable to the postProvision action.

+

The conditions are as follows:

+
    +
  • Immediately: Executed right after the Component object is created. +The readiness of the Component and its resources is not guaranteed at this stage.
  • +
  • RuntimeReady: The Action is triggered after the Component object has been created and all associated +runtime resources (e.g. Pods) are in a ready state.
  • +
  • ComponentReady: The Action is triggered after the Component itself is in a ready state. +This process does not affect the readiness state of the Component or the Cluster.
  • +
  • ClusterReady: The Action is executed after the Cluster is in a ready state. +This execution does not alter the Component or the Cluster’s state of readiness.
  • +
+

This field cannot be updated.

+
+

ClusterComponentConfig +

+

+(Appears on:ComponentSpec) +

+
+

ClusterComponentConfig represents a config with its source bound.

+
+ + + + + + + + + + + + + + + + + +
FieldDescription
+name
+ +string + +
+(Optional) +

The name of the config.

+
+ClusterComponentConfigSource
+ + +ClusterComponentConfigSource + + +
+

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

+

The source of the config.

+
+

ClusterComponentConfigSource +

+

+(Appears on:ClusterComponentConfig) +

+
+

ClusterComponentConfigSource represents the source of a config.

+
+ + + + + + + + + + + + + +
FieldDescription
+configMap
+ + +Kubernetes core/v1.ConfigMapVolumeSource + + +
+(Optional) +

ConfigMap source for the config.

+
+

ClusterComponentPhase +(string alias)

+

+(Appears on:ComponentStatus) +

+
+

ClusterComponentPhase defines the phase of a cluster component as represented in cluster.status.components.phase field.

+
+ + + + + + + + + + + + + + + + + + + + + + + + +
ValueDescription

"Abnormal"

AbnormalClusterCompPhase indicates the component has more than zero replicas, but there are some failed pods. +The component is functioning, but it is in a fragile state.

+

"Creating"

CreatingClusterCompPhase indicates the component is being created.

+

"Deleting"

DeletingClusterCompPhase indicates the component is currently being deleted.

+

"Failed"

FailedClusterCompPhase indicates the component has more than zero replicas, but there are some failed pods. +The component is not functioning.

+

"Running"

RunningClusterCompPhase indicates the component has more than zero replicas, and all pods are up-to-date and +in a ‘Running’ state.

+

"Stopped"

StoppedClusterCompPhase indicates the component has zero replicas, and all pods have been deleted.

+

"Stopping"

StoppingClusterCompPhase indicates the component has zero replicas, and there are pods that are terminating.

+

"Updating"

UpdatingClusterCompPhase indicates the component has more than zero replicas, and there are no failed pods, +it is currently being updated.

+
+

ClusterComponentVolumeClaimTemplate +

+

+(Appears on:ComponentSpec, InstanceTemplate) +

+
+
+ + + + + + + + + + + + + + + + + +
FieldDescription
+name
+ +string + +
+

Refers to the name of a volumeMount defined in either:

+
    +
  • componentDefinition.spec.runtime.containers[*].volumeMounts
  • +
  • clusterDefinition.spec.componentDefs[*].podSpec.containers[*].volumeMounts (deprecated)
  • +
+

The value of name must match the name field of a volumeMount specified in the corresponding volumeMounts array.

+
+spec
+ + +PersistentVolumeClaimSpec + + +
+(Optional) +

Defines the desired characteristics of a PersistentVolumeClaim that will be created for the volume +with the mount name specified in the name field.

+

When a Pod is created for this ClusterComponent, a new PVC will be created based on the specification +defined in the spec field. The PVC will be associated with the volume mount specified by the name field.

+
+
+ + + + + + + + + + + + + + + + + +
+accessModes
+ + +[]Kubernetes core/v1.PersistentVolumeAccessMode + + +
+(Optional) +

Contains the desired access modes the volume should have. +More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1.

+
+resources
+ + +Kubernetes core/v1.VolumeResourceRequirements + + +
+(Optional) +

Represents the minimum resources the volume should have. +If the RecoverVolumeExpansionFailure feature is enabled, users are allowed to specify resource requirements that +are lower than the previous value but must still be higher than the capacity recorded in the status field of the claim. +More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources.

+
+storageClassName
+ +string + +
+(Optional) +

The name of the StorageClass required by the claim. +More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1.

+
+volumeMode
+ + +Kubernetes core/v1.PersistentVolumeMode + + +
+(Optional) +

Defines what type of volume is required by the claim, either Block or Filesystem.

+
+
+

ClusterDefinitionSpec +

+

+(Appears on:ClusterDefinition) +

+
+

ClusterDefinitionSpec defines the desired state of ClusterDefinition.

+
+ + + + + + + + + + + + + +
FieldDescription
+topologies
+ + +[]ClusterTopology + + +
+(Optional) +

Topologies defines all possible topologies within the cluster.

+
+

ClusterDefinitionStatus +

+

+(Appears on:ClusterDefinition) +

+
+

ClusterDefinitionStatus defines the observed state of ClusterDefinition

+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+observedGeneration
+ +int64 + +
+(Optional) +

Represents the most recent generation observed for this ClusterDefinition.

+
+phase
+ + +Phase + + +
+

Specifies the current phase of the ClusterDefinition. Valid values are empty, Available, Unavailable. +When Available, the ClusterDefinition is ready and can be referenced by related objects.

+
+message
+ +string + +
+(Optional) +

Provides additional information about the current phase.

+
+topologies
+ +string + +
+(Optional) +

Topologies this ClusterDefinition supported.

+
+

ClusterObjectReference +

+

+(Appears on:ComponentVarSelector, CredentialVarSelector, HostNetworkVarSelector, ServiceRefVarSelector, ServiceVarSelector) +

+
+

ClusterObjectReference defines information to let you locate the referenced object inside the same Cluster.

+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+compDef
+ +string + +
+(Optional) +

CompDef specifies the definition used by the component that the referent object resident in. +If not specified, the component itself will be used.

+
+name
+ +string + +
+(Optional) +

Name of the referent object.

+
+optional
+ +bool + +
+(Optional) +

Specify whether the object must be defined.

+
+multipleClusterObjectOption
+ + +MultipleClusterObjectOption + + +
+(Optional) +

This option defines the behavior when multiple component objects match the specified @CompDef. +If not provided, an error will be raised when handling multiple matches.

+
+

ClusterSpec +

+

+(Appears on:Cluster) +

+
+

ClusterSpec defines the desired state of Cluster

+
+ + + + + + + + + + + + + +
FieldDescription
+foo
+ +string + +
+

Foo is an example field of Cluster. Edit cluster_types.go to remove/update

+
+

ClusterStatus +

+

+(Appears on:Cluster) +

+
+

ClusterStatus defines the observed state of Cluster

+
+

ClusterTopology +

+

+(Appears on:ClusterDefinitionSpec) +

+
+

ClusterTopology represents the definition for a specific cluster topology.

+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+name
+ +string + +
+

Name is the unique identifier for the cluster topology. +Cannot be updated.

+
+components
+ + +[]ClusterTopologyComponent + + +
+

Components specifies the components in the topology.

+
+orders
+ + +ClusterTopologyOrders + + +
+(Optional) +

Specifies the sequence in which components within a cluster topology are +started, stopped, and upgraded. +This ordering is crucial for maintaining the correct dependencies and operational flow across components.

+
+default
+ +bool + +
+(Optional) +

Default indicates whether this topology serves as the default configuration. +When set to true, this topology is automatically used unless another is explicitly specified.

+
+

ClusterTopologyComponent +

+

+(Appears on:ClusterTopology) +

+
+

ClusterTopologyComponent defines a Component within a ClusterTopology.

+
+ + + + + + + + + + + + + + + + + +
FieldDescription
+name
+ +string + +
+

Defines the unique identifier of the component within the cluster topology. +It follows IANA Service naming rules and is used as part of the Service’s DNS name. +The name must start with a lowercase letter, can contain lowercase letters, numbers, +and hyphens, and must end with a lowercase letter or number.

+

Cannot be updated once set.

+
+compDef
+ +string + +
+

Specifies the name or prefix of the ComponentDefinition custom resource(CR) that +defines the Component’s characteristics and behavior.

+

When a prefix is used, the system selects the ComponentDefinition CR with the latest version that matches the prefix. +This approach allows:

+
    +
  1. Precise selection by providing the exact name of a ComponentDefinition CR.
  2. +
  3. Flexible and automatic selection of the most up-to-date ComponentDefinition CR by specifying a prefix.
  4. +
+

Once set, this field cannot be updated.

+
+

ClusterTopologyOrders +

+

+(Appears on:ClusterTopology) +

+
+

ClusterTopologyOrders manages the lifecycle of components within a cluster by defining their provisioning, +terminating, and updating sequences. +It organizes components into stages or groups, where each group indicates a set of components +that can be managed concurrently. +These groups are processed sequentially, allowing precise control based on component dependencies and requirements.

+
+ + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+provision
+ +[]string + +
+(Optional) +

Specifies the order for creating and initializing components. +This is designed for components that depend on one another. Components without dependencies can be grouped together.

+

Components that can be provisioned independently or have no dependencies can be listed together in the same stage, +separated by commas.

+
+terminate
+ +[]string + +
+(Optional) +

Outlines the order for stopping and deleting components. +This sequence is designed for components that require a graceful shutdown or have interdependencies.

+

Components that can be terminated independently or have no dependencies can be listed together in the same stage, +separated by commas.

+
+update
+ +[]string + +
+(Optional) +

Update determines the order for updating components’ specifications, such as image upgrades or resource scaling. +This sequence is designed for components that have dependencies or require specific update procedures.

+

Components that can be updated independently or have no dependencies can be listed together in the same stage, +separated by commas.

+
+

ClusterVarSelector +

+

+(Appears on:VarSource) +

+
+

ClusterVarSelector selects a var from a Cluster.

+
+ + + + + + + + + + + + + +
FieldDescription
+ClusterVars
+ + +ClusterVars + + +
+

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

+
+

ClusterVars +

+

+(Appears on:ClusterVarSelector) +

+
+
+ + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+namespace
+ + +VarOption + + +
+(Optional) +

Reference to the namespace of the Cluster object.

+
+clusterName
+ + +VarOption + + +
+(Optional) +

Reference to the name of the Cluster object.

+
+clusterUID
+ + +VarOption + + +
+(Optional) +

Reference to the UID of the Cluster object.

+
+

ComponentConfigSpec +

+

+(Appears on:ComponentDefinitionSpec) +

+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+ComponentTemplateSpec
+ + +ComponentTemplateSpec + + +
+

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

+
+keys
+ +[]string + +
+(Optional) +

Specifies the configuration files within the ConfigMap that support dynamic updates.

+

A configuration template (provided in the form of a ConfigMap) may contain templates for multiple +configuration files. +Each configuration file corresponds to a key in the ConfigMap. +Some of these configuration files may support dynamic modification and reloading without requiring +a pod restart.

+

If empty or omitted, all configuration files in the ConfigMap are assumed to support dynamic updates, +and ConfigConstraint applies to all keys.

+
+legacyRenderedConfigSpec
+ + +LegacyRenderedTemplateSpec + + +
+(Optional) +

Specifies the secondary rendered config spec for pod-specific customization.

+

The template is rendered inside the pod (by the “config-manager” sidecar container) and merged with the main +template’s render result to generate the final configuration file.

+

This field is intended to handle scenarios where different pods within the same Component have +varying configurations. It allows for pod-specific customization of the configuration.

+

Note: This field will be deprecated in future versions, and the functionality will be moved to +cluster.spec.componentSpecs[*].instances[*].

+
+constraintRef
+ +string + +
+(Optional) +

Specifies the name of the referenced configuration constraints object.

+
+asEnvFrom
+ +[]string + +
+(Optional) +

Specifies the containers to inject the ConfigMap parameters as environment variables.

+

This is useful when application images accept parameters through environment variables and +generate the final configuration file in the startup script based on these variables.

+

This field allows users to specify a list of container names, and KubeBlocks will inject the environment +variables converted from the ConfigMap into these designated containers. This provides a flexible way to +pass the configuration items from the ConfigMap to the container without modifying the image.

+

Deprecated: asEnvFrom has been deprecated since 0.9.0 and will be removed in 0.10.0. +Use injectEnvTo instead.

+
+injectEnvTo
+ +[]string + +
+(Optional) +

Specifies the containers to inject the ConfigMap parameters as environment variables.

+

This is useful when application images accept parameters through environment variables and +generate the final configuration file in the startup script based on these variables.

+

This field allows users to specify a list of container names, and KubeBlocks will inject the environment +variables converted from the ConfigMap into these designated containers. This provides a flexible way to +pass the configuration items from the ConfigMap to the container without modifying the image.

+
+reRenderResourceTypes
+ + +[]RerenderResourceType + + +
+(Optional) +

Specifies whether the configuration needs to be re-rendered after v-scale or h-scale operations to reflect changes.

+

In some scenarios, the configuration may need to be updated to reflect the changes in resource allocation +or cluster topology. Examples:

+
    +
  • Redis: adjust maxmemory after v-scale operation.
  • +
  • MySQL: increase max connections after v-scale operation.
  • +
  • Zookeeper: update zoo.cfg with new node addresses after h-scale operation.
  • +
+
+

ComponentDefinitionSpec +

+

+(Appears on:ComponentDefinition) +

+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+provider
+ +string + +
+(Optional) +

Specifies the name of the Component provider, typically the vendor or developer name. +It identifies the entity responsible for creating and maintaining the Component.

+

When specifying the provider name, consider the following guidelines:

+
    +
  • Keep the name concise and relevant to the Component.
  • +
  • Use a consistent naming convention across Components from the same provider.
  • +
  • Avoid using trademarked or copyrighted names without proper permission.
  • +
+
+description
+ +string + +
+(Optional) +

Provides a brief and concise explanation of the Component’s purpose, functionality, and any relevant details. +It serves as a quick reference for users to understand the Component’s role and characteristics.

+
+serviceKind
+ +string + +
+(Optional) +

Defines the type of well-known service protocol that the Component provides. +It specifies the standard or widely recognized protocol used by the Component to offer its Services.

+

The serviceKind field allows users to quickly identify the type of Service provided by the Component +based on common protocols or service types. This information helps in understanding the compatibility, +interoperability, and usage of the Component within a system.

+

Some examples of well-known service protocols include:

+
    +
  • “MySQL”: Indicates that the Component provides a MySQL database service.
  • +
  • “PostgreSQL”: Indicates that the Component offers a PostgreSQL database service.
  • +
  • “Redis”: Signifies that the Component functions as a Redis key-value store.
  • +
  • “ETCD”: Denotes that the Component serves as an ETCD distributed key-value store.
  • +
+

The serviceKind value is case-insensitive, allowing for flexibility in specifying the protocol name.

+

When specifying the serviceKind, consider the following guidelines:

+
    +
  • Use well-established and widely recognized protocol names or service types.
  • +
  • Ensure that the serviceKind accurately represents the primary service type offered by the Component.
  • +
  • If the Component provides multiple services, choose the most prominent or commonly used protocol.
  • +
  • Limit the serviceKind to a maximum of 32 characters for conciseness and readability.
  • +
+

Note: The serviceKind field is optional and can be left empty if the Component does not fit into a well-known +service category or if the protocol is not widely recognized. It is primarily used to convey information about +the Component’s service type to users and facilitate discovery and integration.

+

The serviceKind field is immutable and cannot be updated.

+
+serviceVersion
+ +string + +
+(Optional) +

Specifies the version of the Service provided by the Component. +It follows the syntax and semantics of the “Semantic Versioning” specification (http://semver.org/).

+

The Semantic Versioning specification defines a version number format of X.Y.Z (MAJOR.MINOR.PATCH), where:

+
    +
  • X represents the major version and indicates incompatible API changes.
  • +
  • Y represents the minor version and indicates added functionality in a backward-compatible manner.
  • +
  • Z represents the patch version and indicates backward-compatible bug fixes.
  • +
+

Additional labels for pre-release and build metadata are available as extensions to the X.Y.Z format:

+
    +
  • Use pre-release labels (e.g., -alpha, -beta) for versions that are not yet stable or ready for production use.
  • +
  • Use build metadata (e.g., +build.1) for additional version information if needed.
  • +
+

Examples of valid ServiceVersion values:

+
    +
  • “1.0.0”
  • +
  • “2.3.1”
  • +
  • “3.0.0-alpha.1”
  • +
  • “4.5.2+build.1”
  • +
+

The serviceVersion field is immutable and cannot be updated.

+
+labels
+ +map[string]string + +
+(Optional) +

Specifies static labels that will be patched to all Kubernetes resources created for the Component.

+

Note: If a label key in the labels field conflicts with any system labels or user-specified labels, +it will be silently ignored to avoid overriding higher-priority labels.

+

This field is immutable.

+
+annotations
+ +map[string]string + +
+(Optional) +

Specifies static annotations that will be patched to all Kubernetes resources created for the Component.

+

Note: If an annotation key in the annotations field conflicts with any system annotations +or user-specified annotations, it will be silently ignored to avoid overriding higher-priority annotations.

+

This field is immutable.

+
+runtime
+ + +Kubernetes core/v1.PodSpec + + +
+

Specifies the PodSpec template used in the Component. +It includes the following elements:

+
    +
  • Init containers
  • +
  • Containers +
      +
    • Image
    • +
    • Commands
    • +
    • Args
    • +
    • Envs
    • +
    • Mounts
    • +
    • Ports
    • +
    • Security context
    • +
    • Probes
    • +
    • Lifecycle
    • +
  • +
  • Volumes
  • +
+

This field is intended to define static settings that remain consistent across all instantiated Components. +Dynamic settings such as CPU and memory resource limits, as well as scheduling settings (affinity, +toleration, priority), may vary among different instantiated Components. +They should be specified in the cluster.spec.componentSpecs (ClusterComponentSpec).

+

Specific instances of a Component may override settings defined here, such as using a different container image +or modifying environment variable values. +These instance-specific overrides can be specified in cluster.spec.componentSpecs[*].instances.

+

This field is immutable and cannot be updated once set.

+
+vars
+ + +[]EnvVar + + +
+(Optional) +

Defines variables which are determined after Cluster instantiation and reflect +dynamic or runtime attributes of instantiated Clusters. +These variables serve as placeholders for setting environment variables in Pods and Actions, +or for rendering configuration and script templates before actual values are finalized.

+

These variables are placed in front of the environment variables declared in the Pod if used as +environment variables.

+

Variable values can be sourced from:

+
    +
  • ConfigMap: Select and extract a value from a specific key within a ConfigMap.
  • +
  • Secret: Select and extract a value from a specific key within a Secret.
  • +
  • HostNetwork: Retrieves values (including ports) from host-network resources.
  • +
  • Service: Retrieves values (including address, port, NodePort) from a selected Service. +Intended to obtain the address of a ComponentService within the same Cluster.
  • +
  • Credential: Retrieves account name and password from a SystemAccount variable.
  • +
  • ServiceRef: Retrieves address, port, account name and password from a selected ServiceRefDeclaration. +Designed to obtain the address bound to a ServiceRef, such as a ClusterService or +ComponentService of another cluster or an external service.
  • +
  • Component: Retrieves values from a selected Component, including replicas and instance name list.
  • +
+

This field is immutable.

+
+volumes
+ + +[]ComponentVolume + + +
+(Optional) +

Defines the volumes used by the Component and some static attributes of the volumes. +After defining the volumes here, user can reference them in the +cluster.spec.componentSpecs[*].volumeClaimTemplates field to configure dynamic properties such as +volume capacity and storage class.

+

This field allows you to specify the following:

+
    +
  • Snapshot behavior: Determines whether a snapshot of the volume should be taken when performing +a snapshot backup of the Component.
  • +
  • Disk high watermark: Sets the high watermark for the volume’s disk usage. +When the disk usage reaches the specified threshold, it triggers an alert or action.
  • +
+

By configuring these volume behaviors, you can control how the volumes are managed and monitored within the Component.

+

This field is immutable.

+
+hostNetwork
+ + +HostNetwork + + +
+(Optional) +

Specifies the host network configuration for the Component.

+

When hostNetwork option is enabled, the Pods share the host’s network namespace and can directly access +the host’s network interfaces. +This means that if multiple Pods need to use the same port, they cannot run on the same host simultaneously +due to port conflicts.

+

The DNSPolicy field in the Pod spec determines how containers within the Pod perform DNS resolution. +When using hostNetwork, the operator will set the DNSPolicy to ‘ClusterFirstWithHostNet’. +With this policy, DNS queries will first go through the K8s cluster’s DNS service. +If the query fails, it will fall back to the host’s DNS settings.

+

If set, the DNS policy will be automatically set to “ClusterFirstWithHostNet”.

+

This field is immutable.

+
+services
+ + +[]ComponentService + + +
+(Optional) +

Defines additional Services to expose the Component’s endpoints.

+

A default headless Service, named {cluster.name}-{component.name}-headless, is automatically created +for internal Cluster communication.

+

This field enables customization of additional Services to expose the Component’s endpoints to +other Components within the same or different Clusters, and to external applications. +Each Service entry in this list can include properties such as ports, type, and selectors.

+
    +
  • For intra-Cluster access, Components can reference Services using variables declared in +componentDefinition.spec.vars[*].valueFrom.serviceVarRef.
  • +
  • For inter-Cluster access, reference Services use variables declared in +componentDefinition.spec.vars[*].valueFrom.serviceRefVarRef, +and bind Services at Cluster creation time with clusterComponentSpec.ServiceRef[*].clusterServiceSelector.
  • +
+

This field is immutable.

+
+configs
+ + +[]ComponentConfigSpec + + +
+(Optional) +

Specifies the configuration file templates and volume mount parameters used by the Component. +It also includes descriptions of the parameters in the ConfigMaps, such as value range limitations.

+

This field specifies a list of templates that will be rendered into Component containers’ configuration files. +Each template is represented as a ConfigMap and may contain multiple configuration files, +with each file being a key in the ConfigMap.

+

The rendered configuration files will be mounted into the Component’s containers +according to the specified volume mount parameters.

+

This field is immutable.

+
+logConfigs
+ + +[]LogConfig + + +
+(Optional) +

Defines the types of logs generated by instances of the Component and their corresponding file paths. +These logs can be collected for further analysis and monitoring.

+

The logConfigs field is an optional list of LogConfig objects, where each object represents +a specific log type and its configuration. +It allows you to specify multiple log types and their respective file paths for the Component.

+

Examples:

+
 logConfigs:
+ - filePathPattern: /data/mysql/log/mysqld-error.log
+   name: error
+ - filePathPattern: /data/mysql/log/mysqld.log
+   name: general
+ - filePathPattern: /data/mysql/log/mysqld-slowquery.log
+   name: slow
+
+

This field is immutable.

+
+scripts
+ + +[]ComponentTemplateSpec + + +
+(Optional) +

Specifies groups of scripts, each provided via a ConfigMap, to be mounted as volumes in the container. +These scripts can be executed during container startup or via specific actions.

+

Each script group is encapsulated in a ComponentTemplateSpec that includes:

+
    +
  • The ConfigMap containing the scripts.
  • +
  • The mount point where the scripts will be mounted inside the container.
  • +
+

This field is immutable.

+
+systemAccounts
+ + +[]SystemAccount + + +
+(Optional) +

An array of SystemAccount objects that define the system accounts needed +for the management operations of the Component.

+

Each SystemAccount includes:

+
    +
  • Account name.
  • +
  • The SQL statement template: Used to create the system account.
  • +
  • Password Source: Either generated based on certain rules or retrieved from a Secret.
  • +
+

Use cases for system accounts typically involve tasks like system initialization, backups, monitoring, +health checks, replication, and other system-level operations.

+

System accounts are distinct from user accounts, although both are database accounts.

+
    +
  • System Accounts: Created during Cluster setup by the KubeBlocks operator, +these accounts have higher privileges for system management and are fully managed +through a declarative API by the operator.
  • +
  • User Accounts: Managed by users or administrator. +User account permissions should follow the principle of least privilege, +granting only the necessary access rights to complete their required tasks.
  • +
+

This field is immutable.

+
+replicasLimit
+ + +ReplicasLimit + + +
+(Optional) +

Defines the upper limit of the number of replicas supported by the Component.

+

It defines the maximum number of replicas that can be created for the Component. +This field allows you to set a limit on the scalability of the Component, preventing it from exceeding a certain number of replicas.

+

This field is immutable.

+
+roles
+ + +[]ReplicaRole + + +
+(Optional) +

Enumerate all possible roles assigned to each replica of the Component, influencing its behavior.

+

A replica can have zero to multiple roles. +KubeBlocks operator determines the roles of each replica by invoking the lifecycleActions.roleProbe method. +This action returns a list of roles for each replica, and the returned roles must be predefined in the roles field.

+

The roles assigned to a replica can influence various aspects of the Component’s behavior, such as:

+
    +
  • Service selection: The Component’s exposed Services may target replicas based on their roles using roleSelector.
  • +
  • Update order: The roles can determine the order in which replicas are updated during a Component update. +For instance, replicas with a “follower” role can be updated first, while the replica with the “leader” +role is updated last. This helps minimize the number of leader changes during the update process.
  • +
+

This field is immutable.

+
+minReadySeconds
+ +int32 + +
+(Optional) +

minReadySeconds is the minimum duration in seconds that a new Pod should remain in the ready +state without any of its containers crashing to be considered available. +This ensures the Pod’s stability and readiness to serve requests.

+

A default value of 0 seconds means the Pod is considered available as soon as it enters the ready state.

+
+updateStrategy
+ + +UpdateStrategy + + +
+(Optional) +

Specifies the concurrency strategy for updating multiple instances of the Component. +Available strategies:

+
    +
  • Serial: Updates replicas one at a time, ensuring minimal downtime by waiting for each replica to become ready +before updating the next.
  • +
  • Parallel: Updates all replicas simultaneously, optimizing for speed but potentially reducing availability +during the update.
  • +
  • BestEffortParallel: Updates replicas concurrently with a limit on simultaneous updates to ensure a minimum +number of operational replicas for maintaining quorum. + For example, in a 5-replica component, updating a maximum of 2 replicas simultaneously keeps +at least 3 operational for quorum.
  • +
+

This field is immutable and defaults to ‘Serial’.

+
+podManagementPolicy
+ + +Kubernetes apps/v1.PodManagementPolicyType + + +
+(Optional) +

InstanceSet controls the creation of pods during initial scale up, replacement of pods on nodes, and scaling down.

+
    +
  • OrderedReady: Creates pods in increasing order (pod-0, then pod-1, etc). The controller waits until each pod +is ready before continuing. Pods are removed in reverse order when scaling down.
  • +
  • Parallel: Creates pods in parallel to match the desired scale without waiting. All pods are deleted at once +when scaling down.
  • +
+
+policyRules
+ + +[]Kubernetes rbac/v1.PolicyRule + + +
+(Optional) +

Defines the namespaced policy rules required by the Component.

+

The policyRules field is an array of rbacv1.PolicyRule objects that define the policy rules +needed by the Component to operate within a namespace. +These policy rules determine the permissions and verbs the Component is allowed to perform on +Kubernetes resources within the namespace.

+

The purpose of this field is to automatically generate the necessary RBAC roles +for the Component based on the specified policy rules. +This ensures that the Pods in the Component has appropriate permissions to function.

+

Note: This field is currently non-functional and is reserved for future implementation.

+

This field is immutable.

+
+lifecycleActions
+ + +ComponentLifecycleActions + + +
+(Optional) +

Defines a set of hooks and procedures that customize the behavior of a Component throughout its lifecycle. +Actions are triggered at specific lifecycle stages:

+
    +
  • postProvision: Defines the hook to be executed after the creation of a Component, +with preCondition specifying when the action should be fired relative to the Component’s lifecycle stages: +Immediately, RuntimeReady, ComponentReady, and ClusterReady.
  • +
  • preTerminate: Defines the hook to be executed before terminating a Component.
  • +
  • roleProbe: Defines the procedure which is invoked regularly to assess the role of replicas.
  • +
  • switchover: Defines the procedure for a controlled transition of leadership from the current leader to a new replica. +This approach aims to minimize downtime and maintain availability in systems with a leader-follower topology, +such as before planned maintenance or upgrades on the current leader node.
  • +
  • memberJoin: Defines the procedure to add a new replica to the replication group.
  • +
  • memberLeave: Defines the method to remove a replica from the replication group.
  • +
  • readOnly: Defines the procedure to switch a replica into the read-only state.
  • +
  • readWrite: transition a replica from the read-only state back to the read-write state.
  • +
  • dataDump: Defines the procedure to export the data from a replica.
  • +
  • dataLoad: Defines the procedure to import data into a replica.
  • +
  • reconfigure: Defines the procedure that update a replica with new configuration file.
  • +
  • accountProvision: Defines the procedure to generate a new database account.
  • +
+

This field is immutable.

+
+serviceRefDeclarations
+ + +[]ServiceRefDeclaration + + +
+(Optional) +

Lists external service dependencies of the Component, including services from other Clusters or outside the K8s environment.

+

This field is immutable.

+
+exporter
+ + +Exporter + + +
+(Optional) +

Defines the built-in metrics exporter container.

+
+

ComponentDefinitionStatus +

+

+(Appears on:ComponentDefinition) +

+
+

ComponentDefinitionStatus defines the observed state of ComponentDefinition.

+
+ + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+observedGeneration
+ +int64 + +
+(Optional) +

Refers to the most recent generation that has been observed for the ComponentDefinition.

+
+phase
+ + +Phase + + +
+(Optional) +

Represents the current status of the ComponentDefinition. Valid values include `,Available, andUnavailable. +When the status isAvailable`, the ComponentDefinition is ready and can be utilized by related objects.

+
+message
+ +string + +
+(Optional) +

Provides additional information about the current phase.

+
+

ComponentLifecycleActions +

+

+(Appears on:ComponentDefinitionSpec) +

+
+

ComponentLifecycleActions defines a collection of Actions for customizing the behavior of a Component.

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+postProvision
+ + +Action + + +
+(Optional) +

Specifies the hook to be executed after a component’s creation.

+

By setting postProvision.customHandler.preCondition, you can determine the specific lifecycle stage +at which the action should trigger: Immediately, RuntimeReady, ComponentReady, and ClusterReady. +with ComponentReady being the default.

+

The PostProvision Action is intended to run only once.

+

Note: This field is immutable once it has been set.

+
+preTerminate
+ + +Action + + +
+(Optional) +

Specifies the hook to be executed prior to terminating a component.

+

The PreTerminate Action is intended to run only once.

+

This action is executed immediately when a scale-down operation for the Component is initiated. +The actual termination and cleanup of the Component and its associated resources will not proceed +until the PreTerminate action has completed successfully.

+

Note: This field is immutable once it has been set.

+
+roleProbe
+ + +Probe + + +
+(Optional) +

Defines the procedure which is invoked regularly to assess the role of replicas.

+

This action is periodically triggered at the specified interval to determine the role of each replica. +Upon successful execution, the action’s output designates the role of the replica, +which should match one of the predefined role names within componentDefinition.spec.roles. +The output is then compared with the previous successful execution result. +If a role change is detected, an event is generated to inform the controller, +which initiates an update of the replica’s role.

+

Defining a RoleProbe Action for a Component is required if roles are defined for the Component. +It ensures replicas are correctly labeled with their respective roles. +Without this, services that rely on roleSelectors might improperly direct traffic to wrong replicas.

+

The container executing this action has access to following variables:

+
    +
  • KB_POD_FQDN: The FQDN of the Pod whose role is being assessed.
  • +
+

Expected output of this action: +- On Success: The determined role of the replica, which must align with one of the roles specified + in the component definition. +- On Failure: An error message, if applicable, indicating why the action failed.

+

Note: This field is immutable once it has been set.

+
+switchover
+ + +Action + + +
+(Optional) +

Defines the procedure for a controlled transition of leadership from the current leader to a new replica. +This approach aims to minimize downtime and maintain availability in systems with a leader-follower topology, +during events such as planned maintenance or when performing stop, shutdown, restart, or upgrade operations +involving the current leader node.

+

The container executing this action has access to following variables:

+
    +
  • KB_SWITCHOVER_CANDIDATE_NAME: The name of the pod for the new leader candidate, which may not be specified (empty).
  • +
  • KB_SWITCHOVER_CANDIDATE_FQDN: The FQDN of the new leader candidate’s pod, which may not be specified (empty).
  • +
+

Note: This field is immutable once it has been set.

+
+memberJoin
+ + +Action + + +
+(Optional) +

Defines the procedure to add a new replica to the replication group.

+

This action is initiated after a replica pod becomes ready.

+

The role of the replica (e.g., primary, secondary) will be determined and assigned as part of the action command +implementation, or automatically by the database kernel or a sidecar utility like Patroni that implements +a consensus algorithm.

+

The container executing this action has access to following variables:

+
    +
  • KB_JOIN_MEMBER_POD_FQDN: The pod FQDN of the replica being added to the group.
  • +
  • KB_JOIN_MEMBER_POD_NAME: The pod name of the replica being added to the group.
  • +
+

Expected action output: +- On Failure: An error message detailing the reason for any failure encountered +during the addition of the new member.

+

For example, to add a new OBServer to an OceanBase Cluster in ‘zone1’, the following command may be used:

+
command:
+- bash
+- -c
+- |
+   CLIENT="mysql -u $SERVICE_USER -p$SERVICE_PASSWORD -P $SERVICE_PORT -h $SERVICE_HOST -e"
+	  $CLIENT "ALTER SYSTEM ADD SERVER '$KB_POD_FQDN:$SERVICE_PORT' ZONE 'zone1'"
+
+

Note: This field is immutable once it has been set.

+
+memberLeave
+ + +Action + + +
+(Optional) +

Defines the procedure to remove a replica from the replication group.

+

This action is initiated before remove a replica from the group. +The operator will wait for MemberLeave to complete successfully before releasing the replica and cleaning up +related Kubernetes resources.

+

The process typically includes updating configurations and informing other group members about the removal. +Data migration is generally not part of this action and should be handled separately if needed.

+

The container executing this action has access to following variables:

+
    +
  • KB_LEAVE_MEMBER_POD_FQDN: The pod name of the replica being removed from the group.
  • +
  • KB_LEAVE_MEMBER_POD_NAME: The pod name of the replica being removed from the group.
  • +
+

Expected action output: +- On Failure: An error message, if applicable, indicating why the action failed.

+

For example, to remove an OBServer from an OceanBase Cluster in ‘zone1’, the following command can be executed:

+
command:
+- bash
+- -c
+- |
+   CLIENT="mysql -u $SERVICE_USER -p$SERVICE_PASSWORD -P $SERVICE_PORT -h $SERVICE_HOST -e"
+	  $CLIENT "ALTER SYSTEM DELETE SERVER '$KB_POD_FQDN:$SERVICE_PORT' ZONE 'zone1'"
+
+

Note: This field is immutable once it has been set.

+
+readonly
+ + +Action + + +
+(Optional) +

Defines the procedure to switch a replica into the read-only state.

+

Use Case: +This action is invoked when the database’s volume capacity nears its upper limit and space is about to be exhausted.

+

The container executing this action has access to following environment variables:

+
    +
  • KB_POD_FQDN: The FQDN of the replica pod whose role is being checked.
  • +
+

Expected action output: +- On Failure: An error message, if applicable, indicating why the action failed.

+

Note: This field is immutable once it has been set.

+
+readwrite
+ + +Action + + +
+(Optional) +

Defines the procedure to transition a replica from the read-only state back to the read-write state.

+

Use Case: +This action is used to bring back a replica that was previously in a read-only state, +which restricted write operations, to its normal operational state where it can handle +both read and write operations.

+

The container executing this action has access to following environment variables:

+
    +
  • KB_POD_FQDN: The FQDN of the replica pod whose role is being checked.
  • +
+

Expected action output: +- On Failure: An error message, if applicable, indicating why the action failed.

+

Note: This field is immutable once it has been set.

+
+dataDump
+ + +Action + + +
+(Optional) +

Defines the procedure for exporting the data from a replica.

+

Use Case: +This action is intended for initializing a newly created replica with data. It involves exporting data +from an existing replica and importing it into the new, empty replica. This is essential for synchronizing +the state of replicas across the system.

+

Applicability: +Some database engines or associated sidecar applications (e.g., Patroni) may already provide this functionality. +In such cases, this action may not be required.

+

The output should be a valid data dump streamed to stdout. It must exclude any irrelevant information to ensure +that only the necessary data is exported for import into the new replica.

+

Note: This field is immutable once it has been set.

+
+dataLoad
+ + +Action + + +
+(Optional) +

Defines the procedure for importing data into a replica.

+

Use Case: +This action is intended for initializing a newly created replica with data. It involves exporting data +from an existing replica and importing it into the new, empty replica. This is essential for synchronizing +the state of replicas across the system.

+

Some database engines or associated sidecar applications (e.g., Patroni) may already provide this functionality. +In such cases, this action may not be required.

+

Data should be received through stdin. If any error occurs during the process, +the action must be able to guarantee idempotence to allow for retries from the beginning.

+

Note: This field is immutable once it has been set.

+
+reconfigure
+ + +Action + + +
+(Optional) +

Defines the procedure that update a replica with new configuration.

+

Note: This field is immutable once it has been set.

+

This Action is reserved for future versions.

+
+accountProvision
+ + +Action + + +
+(Optional) +

Defines the procedure to generate a new database account.

+

Use Case: +This action is designed to create system accounts that are utilized for replication, monitoring, backup, +and other administrative tasks.

+

The container executing this action has access to following variables:

+
    +
  • KB_ACCOUNT_NAME: The name of the system account to be created.
  • +
  • KB_ACCOUNT_STATEMENT: The statement used to create the system account.
  • +
+

Note: This field is immutable once it has been set.

+
+

ComponentService +

+

+(Appears on:ComponentDefinitionSpec, ComponentSpec) +

+
+

ComponentService defines a service that would be exposed as an inter-component service within a Cluster. +A Service defined in the ComponentService is expected to be accessed by other Components within the same Cluster.

+

When a Component needs to use a ComponentService provided by another Component within the same Cluster, +it can declare a variable in the componentDefinition.spec.vars section and bind it to the specific exposed address +of the ComponentService using the serviceVarRef field.

+
+ + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+Service
+ + +Service + + +
+

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

+
+podService
+ +bool + +
+(Optional) +

Indicates whether to create a corresponding Service for each Pod of the selected Component. +When set to true, a set of Services will be automatically generated for each Pod, +and the roleSelector field will be ignored.

+

The names of the generated Services will follow the same suffix naming pattern: $(serviceName)-$(podOrdinal). +The total number of generated Services will be equal to the number of replicas specified for the Component.

+

Example usage:

+
name: my-service
+serviceName: my-service
+podService: true
+disableAutoProvision: true
+spec:
+  type: NodePort
+  ports:
+  - name: http
+    port: 80
+    targetPort: 8080
+
+

In this example, if the Component has 3 replicas, three Services will be generated: +- my-service-0: Points to the first Pod (podOrdinal: 0) +- my-service-1: Points to the second Pod (podOrdinal: 1) +- my-service-2: Points to the third Pod (podOrdinal: 2)

+

Each generated Service will have the specified spec configuration and will target its respective Pod.

+

This feature is useful when you need to expose each Pod of a Component individually, allowing external access +to specific instances of the Component.

+
+disableAutoProvision
+ +bool + +
+(Optional) +

Indicates whether the automatic provisioning of the service should be disabled.

+

If set to true, the service will not be automatically created at the component provisioning. +Instead, you can enable the creation of this service by specifying it explicitly in the cluster API.

+
+

ComponentSpec +

+

+(Appears on:Component) +

+
+

ComponentSpec defines the desired state of Component

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+compDef
+ +string + +
+

Specifies the name of the referenced ComponentDefinition.

+
+serviceVersion
+ +string + +
+(Optional) +

ServiceVersion specifies the version of the Service expected to be provisioned by this Component. +The version should follow the syntax and semantics of the “Semantic Versioning” specification (http://semver.org/).

+
+serviceRefs
+ + +[]ServiceRef + + +
+(Optional) +

Defines a list of ServiceRef for a Component, enabling access to both external services and +Services provided by other Clusters.

+

Types of services:

+
    +
  • External services: Not managed by KubeBlocks or managed by a different KubeBlocks operator; +Require a ServiceDescriptor for connection details.
  • +
  • Services provided by a Cluster: Managed by the same KubeBlocks operator; +identified using Cluster, Component and Service names.
  • +
+

ServiceRefs with identical serviceRef.name in the same Cluster are considered the same.

+

Example:

+
serviceRefs:
+  - name: "redis-sentinel"
+    serviceDescriptor:
+      name: "external-redis-sentinel"
+  - name: "postgres-cluster"
+    clusterServiceSelector:
+      cluster: "my-postgres-cluster"
+      service:
+        component: "postgresql"
+
+

The example above includes ServiceRefs to an external Redis Sentinel service and a PostgreSQL Cluster.

+
+labels
+ +map[string]string + +
+(Optional) +

Specifies Labels to override or add for underlying Pods.

+
+annotations
+ +map[string]string + +
+(Optional) +

Specifies Annotations to override or add for underlying Pods.

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

List of environment variables to add.

+
+resources
+ + +Kubernetes core/v1.ResourceRequirements + + +
+(Optional) +

Specifies the resources required by the Component. +It allows defining the CPU, memory requirements and limits for the Component’s containers.

+
+volumeClaimTemplates
+ + +[]ClusterComponentVolumeClaimTemplate + + +
+(Optional) +

Specifies a list of PersistentVolumeClaim templates that define the storage requirements for the Component. +Each template specifies the desired characteristics of a persistent volume, such as storage class, +size, and access modes. +These templates are used to dynamically provision persistent volumes for the Component.

+
+volumes
+ + +[]Kubernetes core/v1.Volume + + +
+(Optional) +

List of volumes to override.

+
+services
+ + +[]ComponentService + + +
+(Optional) +

Overrides Services defined in referenced ComponentDefinition and exposes endpoints that can be accessed +by clients.

+
+systemAccounts
+ + +[]ComponentSystemAccount + + +
+(Optional) +

Overrides system accounts defined in referenced ComponentDefinition.

+
+replicas
+ +int32 + +
+

Specifies the desired number of replicas in the Component for enhancing availability and durability, or load balancing.

+
+configs
+ + +[]ClusterComponentConfig + + +
+(Optional) +

Specifies the configuration content of a config template.

+
+enabledLogs
+ +[]string + +
+(Optional) +

Specifies which types of logs should be collected for the Cluster. +The log types are defined in the componentDefinition.spec.logConfigs field with the LogConfig entries.

+

The elements in the enabledLogs array correspond to the names of the LogConfig entries. +For example, if the componentDefinition.spec.logConfigs defines LogConfig entries with +names “slow_query_log” and “error_log”, +you can enable the collection of these logs by including their names in the enabledLogs array:

+
enabledLogs:
+- slow_query_log
+- error_log
+
+
+serviceAccountName
+ +string + +
+(Optional) +

Specifies the name of the ServiceAccount required by the running Component. +This ServiceAccount is used to grant necessary permissions for the Component’s Pods to interact +with other Kubernetes resources, such as modifying Pod labels or sending events.

+

Defaults: +If not specified, KubeBlocks automatically assigns a default ServiceAccount named “kb-{cluster.name}”, +bound to a default role defined during KubeBlocks installation.

+

Future Changes: +Future versions might change the default ServiceAccount creation strategy to one per Component, +potentially revising the naming to “kb-{cluster.name}-{component.name}”.

+

Users can override the automatic ServiceAccount assignment by explicitly setting the name of +an existed ServiceAccount in this field.

+
+parallelPodManagementConcurrency
+ + +Kubernetes api utils intstr.IntOrString + + +
+(Optional) +

Controls the concurrency of pods during initial scale up, when replacing pods on nodes, +or when scaling down. It only used when PodManagementPolicy is set to Parallel. +The default Concurrency is 100%.

+
+podUpdatePolicy
+ + +PodUpdatePolicyType + + +
+(Optional) +

PodUpdatePolicy indicates how pods should be updated

+
    +
  • StrictInPlace indicates that only allows in-place upgrades. +Any attempt to modify other fields will be rejected.
  • +
  • PreferInPlace indicates that we will first attempt an in-place upgrade of the Pod. +If that fails, it will fall back to the ReCreate, where pod will be recreated. +Default value is “PreferInPlace”
  • +
+
+schedulingPolicy
+ + +SchedulingPolicy + + +
+(Optional) +

Specifies the scheduling policy for the Component.

+
+tlsConfig
+ + +TLSConfig + + +
+(Optional) +

Specifies the TLS configuration for the Component, including:

+
    +
  • A boolean flag that indicates whether the Component should use Transport Layer Security (TLS) for secure communication.
  • +
  • An optional field that specifies the configuration for the TLS certificates issuer when TLS is enabled. +It allows defining the issuer name and the reference to the secret containing the TLS certificates and key. +The secret should contain the CA certificate, TLS certificate, and private key in the specified keys.
  • +
+
+instances
+ + +[]InstanceTemplate + + +
+(Optional) +

Allows for the customization of configuration values for each instance within a Component. +An Instance represent a single replica (Pod and associated K8s resources like PVCs, Services, and ConfigMaps). +While instances typically share a common configuration as defined in the ClusterComponentSpec, +they can require unique settings in various scenarios:

+

For example: +- A database Component might require different resource allocations for primary and secondary instances, + with primaries needing more resources. +- During a rolling upgrade, a Component may first update the image for one or a few instances, +and then update the remaining instances after verifying that the updated instances are functioning correctly.

+

InstanceTemplate allows for specifying these unique configurations per instance. +Each instance’s name is constructed using the pattern: $(component.name)-$(template.name)-$(ordinal), +starting with an ordinal of 0. +It is crucial to maintain unique names for each InstanceTemplate to avoid conflicts.

+

The sum of replicas across all InstanceTemplates should not exceed the total number of Replicas specified for the Component. +Any remaining replicas will be generated using the default template and will follow the default naming rules.

+
+offlineInstances
+ +[]string + +
+(Optional) +

Specifies the names of instances to be transitioned to offline status.

+

Marking an instance as offline results in the following:

+
    +
  1. The associated Pod is stopped, and its PersistentVolumeClaim (PVC) is retained for potential +future reuse or data recovery, but it is no longer actively used.
  2. +
  3. The ordinal number assigned to this instance is preserved, ensuring it remains unique +and avoiding conflicts with new instances.
  4. +
+

Setting instances to offline allows for a controlled scale-in process, preserving their data and maintaining +ordinal consistency within the Cluster. +Note that offline instances and their associated resources, such as PVCs, are not automatically deleted. +The administrator must manually manage the cleanup and removal of these resources when they are no longer needed.

+
+runtimeClassName
+ +string + +
+(Optional) +

Defines runtimeClassName for all Pods managed by this Component.

+
+disableExporter
+ +bool + +
+(Optional) +

Determines whether metrics exporter information is annotated on the Component’s headless Service.

+

If set to true, the following annotations will not be patched into the Service:

+
    +
  • “monitor.kubeblocks.io/path”
  • +
  • “monitor.kubeblocks.io/port”
  • +
  • “monitor.kubeblocks.io/scheme”
  • +
+

These annotations allow the Prometheus installed by KubeBlocks to discover and scrape metrics from the exporter.

+
+stop
+ +bool + +
+(Optional) +

Stop the Component. +If set, all the computing resources will be released.

+
+

ComponentStatus +

+

+(Appears on:Component) +

+
+

ComponentStatus represents the observed state of a Component within the Cluster.

+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+observedGeneration
+ +int64 + +
+(Optional) +

Specifies the most recent generation observed for this Component object.

+
+conditions
+ + +[]Kubernetes meta/v1.Condition + + +
+(Optional) +

Represents a list of detailed status of the Component object. +Each condition in the list provides real-time information about certain aspect of the Component object.

+

This field is crucial for administrators and developers to monitor and respond to changes within the Component. +It provides a history of state transitions and a snapshot of the current state that can be used for +automated logic or direct inspection.

+
+phase
+ + +ClusterComponentPhase + + +
+

Indicates the current phase of the Component, with each phase indicating specific conditions:

+
    +
  • Creating: The initial phase for new Components, transitioning from ‘empty’(“”).
  • +
  • Running: All Pods in a Running state.
  • +
  • Updating: The Component is currently being updated, with no failed Pods present.
  • +
  • Abnormal: Some Pods have failed, indicating a potentially unstable state. +However, the cluster remains available as long as a quorum of members is functioning.
  • +
  • Failed: A significant number of Pods or critical Pods have failed +The cluster may be non-functional or may offer only limited services (e.g, read-only).
  • +
  • Stopping: All Pods are being terminated, with current replica count at zero.
  • +
  • Stopped: All associated Pods have been successfully deleted.
  • +
  • Deleting: The Component is being deleted.
  • +
+
+message
+ +map[string]string + +
+(Optional) +

A map that stores detailed message about the Component. +Each entry in the map provides insights into specific elements of the Component, such as Pods or workloads.

+

Keys in this map are formatted as ObjectKind/Name, where ObjectKind could be a type like Pod, +and Name is the specific name of the object.

+
+

ComponentSystemAccount +

+

+(Appears on:ComponentSpec) +

+
+
+ + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+name
+ +string + +
+

The name of the system account.

+
+passwordConfig
+ + +PasswordConfig + + +
+(Optional) +

Specifies the policy for generating the account’s password.

+

This field is immutable once set.

+
+secretRef
+ + +ProvisionSecretRef + + +
+(Optional) +

Refers to the secret from which data will be copied to create the new account.

+

This field is immutable once set.

+
+

ComponentTemplateSpec +

+

+(Appears on:ComponentConfigSpec, ComponentDefinitionSpec) +

+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+name
+ +string + +
+

Specifies the name of the configuration template.

+
+templateRef
+ +string + +
+(Optional) +

Specifies the name of the referenced configuration template ConfigMap object.

+
+namespace
+ +string + +
+(Optional) +

Specifies the namespace of the referenced configuration template ConfigMap object. +An empty namespace is equivalent to the “default” namespace.

+
+volumeName
+ +string + +
+

Refers to the volume name of PodTemplate. The configuration file produced through the configuration +template will be mounted to the corresponding volume. Must be a DNS_LABEL name. +The volume name must be defined in podSpec.containers[*].volumeMounts.

+
+defaultMode
+ +int32 + +
+(Optional) +

The operator attempts to set default file permissions for scripts (0555) and configurations (0444). +However, certain database engines may require different file permissions. +You can specify the desired file permissions here.

+

Must be specified as an octal value between 0000 and 0777 (inclusive), +or as a decimal value between 0 and 511 (inclusive). +YAML supports both octal and decimal values for file permissions.

+

Please note that this setting only affects the permissions of the files themselves. +Directories within the specified path are not impacted by this setting. +It’s important to be aware that this setting might conflict with other options +that influence the file mode, such as fsGroup. +In such cases, the resulting file mode may have additional bits set. +Refers to documents of k8s.ConfigMapVolumeSource.defaultMode for more information.

+
+

ComponentVarSelector +

+

+(Appears on:VarSource) +

+
+

ComponentVarSelector selects a var from a Component.

+
+ + + + + + + + + + + + + + + + + +
FieldDescription
+ClusterObjectReference
+ + +ClusterObjectReference + + +
+

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

+

The Component to select from.

+
+ComponentVars
+ + +ComponentVars + + +
+

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

+
+

ComponentVars +

+

+(Appears on:ComponentVarSelector) +

+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+componentName
+ + +VarOption + + +
+(Optional) +

Reference to the name of the Component object.

+
+shortName
+ + +VarOption + + +
+(Optional) +

Reference to the short name of the Component object.

+
+replicas
+ + +VarOption + + +
+(Optional) +

Reference to the replicas of the component.

+
+podNames
+ + +VarOption + + +
+(Optional) +

Reference to the pod name list of the component. +and the value will be presented in the following format: name1,name2,…

+
+podFQDNs
+ + +VarOption + + +
+(Optional) +

Reference to the pod FQDN list of the component. +The value will be presented in the following format: FQDN1,FQDN2,…

+
+podNamesForRole
+ + +RoledVar + + +
+(Optional) +

Reference to the pod name list of the component that have a specific role. +The value will be presented in the following format: name1,name2,…

+
+podFQDNsForRole
+ + +RoledVar + + +
+(Optional) +

Reference to the pod FQDN list of the component that have a specific role. +The value will be presented in the following format: FQDN1,FQDN2,…

+
+

ComponentVersionCompatibilityRule +

+

+(Appears on:ComponentVersionSpec) +

+
+

ComponentVersionCompatibilityRule defines the compatibility between a set of component definitions and a set of releases.

+
+ + + + + + + + + + + + + + + + + +
FieldDescription
+compDefs
+ +[]string + +
+

CompDefs specifies names for the component definitions associated with this ComponentVersion. +Each name in the list can represent an exact name, or a name prefix.

+

For example:

+
    +
  • “mysql-8.0.30-v1alpha1”: Matches the exact name “mysql-8.0.30-v1alpha1”
  • +
  • “mysql-8.0.30”: Matches all names starting with “mysql-8.0.30”
  • +
+
+releases
+ +[]string + +
+

Releases is a list of identifiers for the releases.

+
+

ComponentVersionRelease +

+

+(Appears on:ComponentVersionSpec) +

+
+

ComponentVersionRelease represents a release of component instances within a ComponentVersion.

+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+name
+ +string + +
+

Name is a unique identifier for this release. +Cannot be updated.

+
+changes
+ +string + +
+(Optional) +

Changes provides information about the changes made in this release.

+
+serviceVersion
+ +string + +
+

ServiceVersion defines the version of the well-known service that the component provides. +The version should follow the syntax and semantics of the “Semantic Versioning” specification (http://semver.org/). +If the release is used, it will serve as the service version for component instances, overriding the one defined in the component definition. +Cannot be updated.

+
+images
+ +map[string]string + +
+

Images define the new images for different containers within the release.

+
+

ComponentVersionSpec +

+

+(Appears on:ComponentVersion) +

+
+

ComponentVersionSpec defines the desired state of ComponentVersion

+
+ + + + + + + + + + + + + + + + + +
FieldDescription
+compatibilityRules
+ + +[]ComponentVersionCompatibilityRule + + +
+

CompatibilityRules defines compatibility rules between sets of component definitions and releases.

+
+releases
+ + +[]ComponentVersionRelease + + +
+

Releases represents different releases of component instances within this ComponentVersion.

+
+

ComponentVersionStatus +

+

+(Appears on:ComponentVersion) +

+
+

ComponentVersionStatus defines the observed state of ComponentVersion

+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+observedGeneration
+ +int64 + +
+(Optional) +

ObservedGeneration is the most recent generation observed for this ComponentVersion.

+
+phase
+ + +Phase + + +
+(Optional) +

Phase valid values are `,Available, 'Unavailable. +Available is ComponentVersion become available, and can be used for co-related objects.

+
+message
+ +string + +
+(Optional) +

Extra message for current phase.

+
+serviceVersions
+ +string + +
+(Optional) +

ServiceVersions represent the supported service versions of this ComponentVersion.

+
+

ComponentVolume +

+

+(Appears on:ComponentDefinitionSpec) +

+
+
+ + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+name
+ +string + +
+

Specifies the name of the volume. +It must be a DNS_LABEL and unique within the pod. +More info can be found at: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names +Note: This field cannot be updated.

+
+needSnapshot
+ +bool + +
+(Optional) +

Specifies whether the creation of a snapshot of this volume is necessary when performing a backup of the Component.

+

Note: This field cannot be updated.

+
+highWatermark
+ +int + +
+(Optional) +

Sets the critical threshold for volume space utilization as a percentage (0-100).

+

Exceeding this percentage triggers the system to switch the volume to read-only mode as specified in +componentDefinition.spec.lifecycleActions.readOnly. +This precaution helps prevent space depletion while maintaining read-only access. +If the space utilization later falls below this threshold, the system reverts the volume to read-write mode +as defined in componentDefinition.spec.lifecycleActions.readWrite, restoring full functionality.

+

Note: This field cannot be updated.

+
+

ConfigTemplateExtension +

+

+(Appears on:LegacyRenderedTemplateSpec) +

+
+
+ + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+templateRef
+ +string + +
+

Specifies the name of the referenced configuration template ConfigMap object.

+
+namespace
+ +string + +
+(Optional) +

Specifies the namespace of the referenced configuration template ConfigMap object. +An empty namespace is equivalent to the “default” namespace.

+
+policy
+ + +MergedPolicy + + +
+(Optional) +

Defines the strategy for merging externally imported templates into component templates.

+
+

ConnectionCredentialAuth +

+

+(Appears on:ServiceDescriptorSpec) +

+
+

ConnectionCredentialAuth specifies the authentication credentials required for accessing an external service.

+
+ + + + + + + + + + + + + + + + + +
FieldDescription
+username
+ + +CredentialVar + + +
+(Optional) +

Specifies the username for the external service.

+
+password
+ + +CredentialVar + + +
+(Optional) +

Specifies the password for the external service.

+
+

ContainerVars +

+

+(Appears on:HostNetworkVars) +

+
+

ContainerVars defines the vars that can be referenced from a Container.

+
+ + + + + + + + + + + + + + + + + +
FieldDescription
+name
+ +string + +
+

The name of the container.

+
+port
+ + +NamedVar + + +
+(Optional) +

Container port to reference.

+
+

CredentialVar +

+

+(Appears on:ConnectionCredentialAuth, ServiceDescriptorSpec) +

+
+

CredentialVar represents a variable that retrieves its value either directly from a specified expression +or from a source defined in valueFrom. +Only one of these options may be used at a time.

+
+ + + + + + + + + + + + + + + + + +
FieldDescription
+value
+ +string + +
+(Optional) +

Holds a direct string or an expression that can be evaluated to a string.

+

It can include variables denoted by $(VAR_NAME). +These variables are expanded to the value of the environment variables defined in the container. +If a variable cannot be resolved, it remains unchanged in the output.

+

To escape variable expansion and retain the literal value, use double $ characters.

+

For example:

+
    +
  • ”$(VAR_NAME)” will be expanded to the value of the environment variable VAR_NAME.
  • +
  • ”$$(VAR_NAME)” will result in “$(VAR_NAME)” in the output, without any variable expansion.
  • +
+

Default value is an empty string.

+
+valueFrom
+ + +Kubernetes core/v1.EnvVarSource + + +
+(Optional) +

Specifies the source for the variable’s value.

+
+

CredentialVarSelector +

+

+(Appears on:VarSource) +

+
+

CredentialVarSelector selects a var from a Credential (SystemAccount).

+
+ + + + + + + + + + + + + + + + + +
FieldDescription
+ClusterObjectReference
+ + +ClusterObjectReference + + +
+

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

+

The Credential (SystemAccount) to select from.

+
+CredentialVars
+ + +CredentialVars + + +
+

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

+
+

CredentialVars +

+

+(Appears on:CredentialVarSelector, ServiceRefVars) +

+
+

CredentialVars defines the vars that can be referenced from a Credential (SystemAccount). +!!!!! CredentialVars will only be used as environment variables for Pods & Actions, and will not be used to render the templates.

+
+ + + + + + + + + + + + + + + + + +
FieldDescription
+username
+ + +VarOption + + +
+(Optional) +
+password
+ + +VarOption + + +
+(Optional) +
+

EnvVar +

+

+(Appears on:ComponentDefinitionSpec) +

+
+

EnvVar represents a variable present in the env of Pod/Action or the template of config/script.

+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+name
+ +string + +
+

Name of the variable. Must be a C_IDENTIFIER.

+
+value
+ +string + +
+(Optional) +

Variable references $(VAR_NAME) are expanded using the previously defined variables in the current context.

+

If a variable cannot be resolved, the reference in the input string will be unchanged. +Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e.

+
    +
  • $$(VAR_NAME) will produce the string literal $(VAR_NAME).
  • +
+

Escaped references will never be expanded, regardless of whether the variable exists or not. +Defaults to “”.

+
+valueFrom
+ + +VarSource + + +
+(Optional) +

Source for the variable’s value. Cannot be used if value is not empty.

+
+expression
+ +string + +
+(Optional) +

A Go template expression that will be applied to the resolved value of the var.

+

The expression will only be evaluated if the var is successfully resolved to a non-credential value.

+

The resolved value can be accessed by its name within the expression, system vars and other user-defined +non-credential vars can be used within the expression in the same way. +Notice that, when accessing vars by its name, you should replace all the “-” in the name with “_”, because of +that “-” is not a valid identifier in Go.

+

All expressions are evaluated in the order the vars are defined. If a var depends on any vars that also +have expressions defined, be careful about the evaluation order as it may use intermediate values.

+

The result of evaluation will be used as the final value of the var. If the expression fails to evaluate, +the resolving of var will also be considered failed.

+
+

ExecAction +

+

+(Appears on:Action) +

+
+

ExecAction describes an Action that executes a command inside a container.

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

Specifies the container image to be used for running the Action.

+

When specified, a dedicated container will be created using this image to execute the Action. +All actions with same image will share the same container.

+

This field cannot be updated.

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

Represents a list of environment variables that will be injected into the container. +These variables enable the container to adapt its behavior based on the environment it’s running in.

+

This field cannot be updated.

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

Specifies the command to be executed inside the container. +The working directory for this command is the container’s root directory(‘/’). +Commands are executed directly without a shell environment, meaning shell-specific syntax (‘|’, etc.) is not supported. +If the shell is required, it must be explicitly invoked in the command.

+

A successful execution is indicated by an exit status of 0; any non-zero status signifies a failure.

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

Args represents the arguments that are passed to the command for execution.

+
+targetPodSelector
+ + +TargetPodSelector + + +
+(Optional) +

Defines the criteria used to select the target Pod(s) for executing the Action. +This is useful when there is no default target replica identified. +It allows for precise control over which Pod(s) the Action should run in.

+

If not specified, the Action will be executed in the pod where the Action is triggered, such as the pod +to be removed or added; or a random pod if the Action is triggered at the component level, such as +post-provision or pre-terminate of the component.

+

This field cannot be updated.

+
+matchingKey
+ +string + +
+(Optional) +

Used in conjunction with the targetPodSelector field to refine the selection of target pod(s) for Action execution. +The impact of this field depends on the targetPodSelector value:

+
    +
  • When targetPodSelector is set to Any or All, this field will be ignored.
  • +
  • When targetPodSelector is set to Role, only those replicas whose role matches the matchingKey +will be selected for the Action.
  • +
+

This field cannot be updated.

+
+container
+ +string + +
+(Optional) +

Specifies the name of the container within the same pod whose resources will be shared with the action. +This allows the action to utilize the specified container’s resources without executing within it.

+

The name must match one of the containers defined in componentDefinition.spec.runtime.

+

The resources that can be shared are included:

+
    +
  • volume mounts
  • +
+

This field cannot be updated.

+
+

Exporter +

+

+(Appears on:ComponentDefinitionSpec) +

+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+containerName
+ +string + +
+(Optional) +

Specifies the name of the built-in metrics exporter container.

+
+scrapePath
+ +string + +
+(Optional) +

Specifies the http/https url path to scrape for metrics. +If empty, Prometheus uses the default value (e.g. /metrics).

+
+scrapePort
+ +string + +
+(Optional) +

Specifies the port name to scrape for metrics.

+
+scrapeScheme
+ + +PrometheusScheme + + +
+(Optional) +

Specifies the schema to use for scraping. +http and https are the expected values unless you rewrite the __scheme__ label via relabeling. +If empty, Prometheus uses the default value http.

+
+

HostNetwork +

+

+(Appears on:ComponentDefinitionSpec) +

+
+
+ + + + + + + + + + + + + +
FieldDescription
+containerPorts
+ + +[]HostNetworkContainerPort + + +
+(Optional) +

The list of container ports that are required by the component.

+
+

HostNetworkContainerPort +

+

+(Appears on:HostNetwork) +

+
+
+ + + + + + + + + + + + + + + + + +
FieldDescription
+container
+ +string + +
+

Container specifies the target container within the Pod.

+
+ports
+ +[]string + +
+

Ports are named container ports within the specified container. +These container ports must be defined in the container for proper port allocation.

+
+

HostNetworkVarSelector +

+

+(Appears on:VarSource) +

+
+

HostNetworkVarSelector selects a var from host-network resources.

+
+ + + + + + + + + + + + + + + + + +
FieldDescription
+ClusterObjectReference
+ + +ClusterObjectReference + + +
+

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

+

The component to select from.

+
+HostNetworkVars
+ + +HostNetworkVars + + +
+

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

+
+

HostNetworkVars +

+

+(Appears on:HostNetworkVarSelector) +

+
+

HostNetworkVars defines the vars that can be referenced from host-network resources.

+
+ + + + + + + + + + + + + +
FieldDescription
+container
+ + +ContainerVars + + +
+(Optional) +
+

InstanceTemplate +

+

+(Appears on:ComponentSpec) +

+
+

InstanceTemplate allows customization of individual replica configurations in a Component.

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+name
+ +string + +
+

Name specifies the unique name of the instance Pod created using this InstanceTemplate. +This name is constructed by concatenating the Component’s name, the template’s name, and the instance’s ordinal +using the pattern: $(cluster.name)-$(component.name)-$(template.name)-$(ordinal). Ordinals start from 0. +The specified name overrides any default naming conventions or patterns.

+
+replicas
+ +int32 + +
+(Optional) +

Specifies the number of instances (Pods) to create from this InstanceTemplate. +This field allows setting how many replicated instances of the Component, +with the specific overrides in the InstanceTemplate, are created. +The default value is 1. A value of 0 disables instance creation.

+
+annotations
+ +map[string]string + +
+(Optional) +

Specifies a map of key-value pairs to be merged into the Pod’s existing annotations. +Existing keys will have their values overwritten, while new keys will be added to the annotations.

+
+labels
+ +map[string]string + +
+(Optional) +

Specifies a map of key-value pairs that will be merged into the Pod’s existing labels. +Values for existing keys will be overwritten, and new keys will be added.

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

Specifies an override for the first container’s image in the Pod.

+
+schedulingPolicy
+ + +SchedulingPolicy + + +
+(Optional) +

Specifies the scheduling policy for the Component.

+
+resources
+ + +Kubernetes core/v1.ResourceRequirements + + +
+(Optional) +

Specifies an override for the resource requirements of the first container in the Pod. +This field allows for customizing resource allocation (CPU, memory, etc.) for the container.

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

Defines Env to override. +Add new or override existing envs.

+
+volumes
+ + +[]Kubernetes core/v1.Volume + + +
+(Optional) +

Defines Volumes to override. +Add new or override existing volumes.

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

Defines VolumeMounts to override. +Add new or override existing volume mounts of the first container in the Pod.

+
+volumeClaimTemplates
+ + +[]ClusterComponentVolumeClaimTemplate + + +
+(Optional) +

Defines VolumeClaimTemplates to override. +Add new or override existing volume claim templates.

+
+

Issuer +

+

+(Appears on:TLSConfig) +

+
+

Issuer defines the TLS certificates issuer for the Cluster.

+
+ + + + + + + + + + + + + + + + + +
FieldDescription
+name
+ + +IssuerName + + +
+

The issuer for TLS certificates. +It only allows two enum values: KubeBlocks and UserProvided.

+
    +
  • KubeBlocks indicates that the self-signed TLS certificates generated by the KubeBlocks Operator will be used.
  • +
  • UserProvided means that the user is responsible for providing their own CA, Cert, and Key. +In this case, the user-provided CA certificate, server certificate, and private key will be used +for TLS communication.
  • +
+
+secretRef
+ + +TLSSecretRef + + +
+(Optional) +

SecretRef is the reference to the secret that contains user-provided certificates. +It is required when the issuer is set to UserProvided.

+
+

IssuerName +(string alias)

+

+(Appears on:Issuer) +

+
+

IssuerName defines the name of the TLS certificates issuer.

+
+ + + + + + + + + + + + +
ValueDescription

"KubeBlocks"

IssuerKubeBlocks represents certificates that are signed by the KubeBlocks Operator.

+

"UserProvided"

IssuerUserProvided indicates that the user has provided their own CA-signed certificates.

+
+

LegacyRenderedTemplateSpec +

+

+(Appears on:ComponentConfigSpec) +

+
+

LegacyRenderedTemplateSpec describes the configuration extension for the lazy rendered template. +Deprecated: LegacyRenderedTemplateSpec has been deprecated since 0.9.0 and will be removed in 0.10.0

+
+ + + + + + + + + + + + + +
FieldDescription
+ConfigTemplateExtension
+ + +ConfigTemplateExtension + + +
+

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

+

Extends the configuration template.

+
+

LetterCase +(string alias)

+

+(Appears on:PasswordConfig) +

+
+

LetterCase defines the available cases to be used in password generation.

+
+ + + + + + + + + + + + + + +
ValueDescription

"LowerCases"

LowerCases represents the use of lower case letters only.

+

"MixedCases"

MixedCases represents the use of a mix of both lower and upper case letters.

+

"UpperCases"

UpperCases represents the use of upper case letters only.

+
+

LogConfig +

+

+(Appears on:ComponentDefinitionSpec) +

+
+
+ + + + + + + + + + + + + + + + + +
FieldDescription
+name
+ +string + +
+

Specifies a descriptive label for the log type, such as ‘slow’ for a MySQL slow log file. +It provides a clear identification of the log’s purpose and content.

+
+filePathPattern
+ +string + +
+

Specifies the paths or patterns identifying where the log files are stored. +This field allows the system to locate and manage log files effectively.

+

Examples:

+
    +
  • /home/postgres/pgdata/pgroot/data/log/postgresql-*
  • +
  • /data/mysql/log/mysqld-error.log
  • +
+
+

MergedPolicy +(string alias)

+

+(Appears on:ConfigTemplateExtension) +

+
+

MergedPolicy defines how to merge external imported templates into component templates.

+
+ + + + + + + + + + + + + + + + +
ValueDescription

"none"

"add"

"patch"

"replace"

+

MultipleClusterObjectCombinedOption +

+

+(Appears on:MultipleClusterObjectOption) +

+
+

MultipleClusterObjectCombinedOption defines options for handling combined variables.

+
+ + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+newVarSuffix
+ +string + +
+(Optional) +

If set, the existing variable will be kept, and a new variable will be defined with the specified suffix +in pattern: $(var.name)_$(suffix). +The new variable will be auto-created and placed behind the existing one. +If not set, the existing variable will be reused with the value format defined below.

+
+valueFormat
+ + +MultipleClusterObjectValueFormat + + +
+(Optional) +

The format of the value that the operator will use to compose values from multiple components.

+
+flattenFormat
+ + +MultipleClusterObjectValueFormatFlatten + + +
+(Optional) +

The flatten format, default is: $(comp-name-1):value,$(comp-name-2):value.

+
+

MultipleClusterObjectOption +

+

+(Appears on:ClusterObjectReference) +

+
+

MultipleClusterObjectOption defines the options for handling multiple cluster objects matched.

+
+ + + + + + + + + + + + + + + + + +
FieldDescription
+strategy
+ + +MultipleClusterObjectStrategy + + +
+

Define the strategy for handling multiple cluster objects.

+
+combinedOption
+ + +MultipleClusterObjectCombinedOption + + +
+(Optional) +

Define the options for handling combined variables. +Valid only when the strategy is set to “combined”.

+
+

MultipleClusterObjectStrategy +(string alias)

+

+(Appears on:MultipleClusterObjectOption) +

+
+

MultipleClusterObjectStrategy defines the strategy for handling multiple cluster objects.

+
+ + + + + + + + + + + + +
ValueDescription

"combined"

MultipleClusterObjectStrategyCombined - the values from all matched components will be combined into a single +variable using the specified option.

+

"individual"

MultipleClusterObjectStrategyIndividual - each matched component will have its individual variable with its name +as the suffix. +This is required when referencing credential variables that cannot be passed by values.

+
+

MultipleClusterObjectValueFormat +(string alias)

+

+(Appears on:MultipleClusterObjectCombinedOption) +

+
+

MultipleClusterObjectValueFormat defines the format details for the value.

+
+ + + + + + + + + + +
ValueDescription

"Flatten"

+

MultipleClusterObjectValueFormatFlatten +

+

+(Appears on:MultipleClusterObjectCombinedOption) +

+
+

MultipleClusterObjectValueFormatFlatten defines the flatten format for the value.

+
+ + + + + + + + + + + + + + + + + +
FieldDescription
+delimiter
+ +string + +
+

Pair delimiter.

+
+keyValueDelimiter
+ +string + +
+

Key-value delimiter.

+
+

NamedVar +

+

+(Appears on:ContainerVars, ServiceVars) +

+
+
+ + + + + + + + + + + + + + + + + +
FieldDescription
+name
+ +string + +
+(Optional) +
+option
+ + +VarOption + + +
+(Optional) +
+

PasswordConfig +

+

+(Appears on:ComponentSystemAccount, SystemAccount) +

+
+

PasswordConfig helps provide to customize complexity of password generation pattern.

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+length
+ +int32 + +
+(Optional) +

The length of the password.

+
+numDigits
+ +int32 + +
+(Optional) +

The number of digits in the password.

+
+numSymbols
+ +int32 + +
+(Optional) +

The number of symbols in the password.

+
+letterCase
+ + +LetterCase + + +
+(Optional) +

The case of the letters in the password.

+
+seed
+ +string + +
+(Optional) +

Seed to generate the account’s password. +Cannot be updated.

+
+

PersistentVolumeClaimSpec +

+

+(Appears on:ClusterComponentVolumeClaimTemplate) +

+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+accessModes
+ + +[]Kubernetes core/v1.PersistentVolumeAccessMode + + +
+(Optional) +

Contains the desired access modes the volume should have. +More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1.

+
+resources
+ + +Kubernetes core/v1.VolumeResourceRequirements + + +
+(Optional) +

Represents the minimum resources the volume should have. +If the RecoverVolumeExpansionFailure feature is enabled, users are allowed to specify resource requirements that +are lower than the previous value but must still be higher than the capacity recorded in the status field of the claim. +More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources.

+
+storageClassName
+ +string + +
+(Optional) +

The name of the StorageClass required by the claim. +More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1.

+
+volumeMode
+ + +Kubernetes core/v1.PersistentVolumeMode + + +
+(Optional) +

Defines what type of volume is required by the claim, either Block or Filesystem.

+
+

Phase +(string alias)

+

+(Appears on:ClusterDefinitionStatus, ComponentDefinitionStatus, ComponentVersionStatus, ServiceDescriptorStatus) +

+
+

Phase represents the status of a CR.

+
+ + + + + + + + + + + + +
ValueDescription

"Available"

AvailablePhase indicates that a CR is in an available state.

+

"Unavailable"

UnavailablePhase indicates that a CR is in an unavailable state.

+
+

PodUpdatePolicyType +(string alias)

+

+(Appears on:ComponentSpec) +

+
+
+ + + + + + + + + + + + +
ValueDescription

"PreferInPlace"

PreferInPlacePodUpdatePolicyType indicates that we will first attempt an in-place upgrade of the Pod. +If that fails, it will fall back to the ReCreate, where pod will be recreated.

+

"StrictInPlace"

StrictInPlacePodUpdatePolicyType indicates that only allows in-place upgrades. +Any attempt to modify other fields will be rejected.

+
+

PreConditionType +(string alias)

+

+(Appears on:Action) +

+
+

PreConditionType defines the preCondition type of the action execution.

+
+ + + + + + + + + + + + + + + + +
ValueDescription

"ClusterReady"

"ComponentReady"

"Immediately"

"RuntimeReady"

+

Probe +

+

+(Appears on:ComponentLifecycleActions) +

+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+Action
+ + +Action + + +
+

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

+
+initialDelaySeconds
+ +int32 + +
+(Optional) +

Specifies the number of seconds to wait after the container has started before the RoleProbe +begins to detect the container’s role.

+
+periodSeconds
+ +int32 + +
+(Optional) +

Specifies the frequency at which the probe is conducted. This value is expressed in seconds. +Default to 10 seconds. Minimum value is 1.

+
+successThreshold
+ +int32 + +
+(Optional) +

Minimum consecutive successes for the probe to be considered successful after having failed. +Defaults to 1. Minimum value is 1.

+
+failureThreshold
+ +int32 + +
+(Optional) +

Minimum consecutive failures for the probe to be considered failed after having succeeded. +Defaults to 3. Minimum value is 1.

+
+

PrometheusScheme +(string alias)

+

+(Appears on:Exporter) +

+
+

PrometheusScheme defines the protocol of prometheus scrape metrics.

+
+ + + + + + + + + + + + +
ValueDescription

"http"

"https"

+

ProvisionSecretRef +

+

+(Appears on:ComponentSystemAccount, SystemAccount) +

+
+

ProvisionSecretRef represents the reference to a secret.

+
+ + + + + + + + + + + + + + + + + +
FieldDescription
+name
+ +string + +
+

The unique identifier of the secret.

+
+namespace
+ +string + +
+

The namespace where the secret is located.

+
+

ReplicaRole +

+

+(Appears on:ComponentDefinitionSpec) +

+
+

ReplicaRole represents a role that can be assumed by a component instance.

+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+name
+ +string + +
+

Defines the role’s identifier. It is used to set the “apps.kubeblocks.io/role” label value +on the corresponding object.

+

This field is immutable once set.

+
+serviceable
+ +bool + +
+(Optional) +

Indicates whether a replica assigned this role is capable of providing services.

+

This field is immutable once set.

+
+writable
+ +bool + +
+(Optional) +

Determines if a replica in this role has the authority to perform write operations. +A writable replica can modify data, handle update operations.

+

This field is immutable once set.

+
+votable
+ +bool + +
+(Optional) +

Specifies whether a replica with this role has voting rights. +In distributed systems, this typically means the replica can participate in consensus decisions, +configuration changes, or other processes that require a quorum.

+

This field is immutable once set.

+
+

ReplicasLimit +

+

+(Appears on:ComponentDefinitionSpec) +

+
+

ReplicasLimit defines the valid range of number of replicas supported.

+
+ + + + + + + + + + + + + + + + + +
FieldDescription
+minReplicas
+ +int32 + +
+

The minimum limit of replicas.

+
+maxReplicas
+ +int32 + +
+

The maximum limit of replicas.

+
+

RerenderResourceType +(string alias)

+

+(Appears on:ComponentConfigSpec) +

+
+

RerenderResourceType defines the resource requirements for a component.

+
+ + + + + + + + + + + + +
ValueDescription

"hscale"

"vscale"

+

RetryPolicy +

+

+(Appears on:Action) +

+
+
+ + + + + + + + + + + + + + + + + +
FieldDescription
+maxRetries
+ +int + +
+(Optional) +

Defines the maximum number of retry attempts that should be made for a given Action. +This value is set to 0 by default, indicating that no retries will be made.

+
+retryInterval
+ +time.Duration + +
+(Optional) +

Indicates the duration of time to wait between each retry attempt. +This value is set to 0 by default, indicating that there will be no delay between retry attempts.

+
+

RoledVar +

+

+(Appears on:ComponentVars) +

+
+
+ + + + + + + + + + + + + + + + + +
FieldDescription
+role
+ +string + +
+(Optional) +
+option
+ + +VarOption + + +
+(Optional) +
+

SchedulingPolicy +

+

+(Appears on:ComponentSpec, InstanceTemplate) +

+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+schedulerName
+ +string + +
+(Optional) +

If specified, the Pod will be dispatched by specified scheduler. +If not specified, the Pod will be dispatched by default scheduler.

+
+nodeSelector
+ +map[string]string + +
+(Optional) +

NodeSelector is a selector which must be true for the Pod to fit on a node. +Selector which must match a node’s labels for the Pod to be scheduled on that node. +More info: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/

+
+nodeName
+ +string + +
+(Optional) +

NodeName is a request to schedule this Pod onto a specific node. If it is non-empty, +the scheduler simply schedules this Pod onto that node, assuming that it fits resource +requirements.

+
+affinity
+ + +Kubernetes core/v1.Affinity + + +
+(Optional) +

Specifies a group of affinity scheduling rules of the Cluster, including NodeAffinity, PodAffinity, and PodAntiAffinity.

+
+tolerations
+ + +[]Kubernetes core/v1.Toleration + + +
+(Optional) +

Allows Pods to be scheduled onto nodes with matching taints. +Each toleration in the array allows the Pod to tolerate node taints based on +specified key, value, effect, and operator.

+
    +
  • The key, value, and effect identify the taint that the toleration matches.
  • +
  • The operator determines how the toleration matches the taint.
  • +
+

Pods with matching tolerations are allowed to be scheduled on tainted nodes, typically reserved for specific purposes.

+
+topologySpreadConstraints
+ + +[]Kubernetes core/v1.TopologySpreadConstraint + + +
+(Optional) +

TopologySpreadConstraints describes how a group of Pods ought to spread across topology +domains. Scheduler will schedule Pods in a way which abides by the constraints. +All topologySpreadConstraints are ANDed.

+
+

Service +

+

+(Appears on:ComponentService) +

+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+name
+ +string + +
+

Name defines the name of the service. +otherwise, it indicates the name of the service. +Others can refer to this service by its name. (e.g., connection credential) +Cannot be updated.

+
+serviceName
+ +string + +
+(Optional) +

ServiceName defines the name of the underlying service object. +If not specified, the default service name with different patterns will be used:

+
    +
  • CLUSTER_NAME: for cluster-level services
  • +
  • CLUSTER_NAME-COMPONENT_NAME: for component-level services
  • +
+

Only one default service name is allowed. +Cannot be updated.

+
+annotations
+ +map[string]string + +
+(Optional) +

If ServiceType is LoadBalancer, cloud provider related parameters can be put here +More info: https://kubernetes.io/docs/concepts/services-networking/service/#loadbalancer.

+
+spec
+ + +Kubernetes core/v1.ServiceSpec + + +
+(Optional) +

Spec defines the behavior of a service. +https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status

+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -
+ports
+ + +[]Kubernetes core/v1.ServicePort + + +
+

The list of ports that are exposed by this service. +More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies

+
+selector
+ +map[string]string + +
+(Optional) +

Route service traffic to pods with label keys and values matching this +selector. If empty or not present, the service is assumed to have an +external process managing its endpoints, which Kubernetes will not +modify. Only applies to types ClusterIP, NodePort, and LoadBalancer. +Ignored if type is ExternalName. +More info: https://kubernetes.io/docs/concepts/services-networking/service/

+
+clusterIP
+ +string + +
+(Optional) +

clusterIP is the IP address of the service and is usually assigned +randomly. If an address is specified manually, is in-range (as per +system configuration), and is not in use, it will be allocated to the +service; otherwise creation of the service will fail. This field may not +be changed through updates unless the type field is also being changed +to ExternalName (which requires this field to be blank) or the type +field is being changed from ExternalName (in which case this field may +optionally be specified, as describe above). Valid values are “None”, +empty string (“”), or a valid IP address. Setting this to “None” makes a +“headless service” (no virtual IP), which is useful when direct endpoint +connections are preferred and proxying is not required. Only applies to +types ClusterIP, NodePort, and LoadBalancer. If this field is specified +when creating a Service of type ExternalName, creation will fail. This +field will be wiped when updating a Service to type ExternalName. +More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies

+
+clusterIPs
+ +[]string + +
+(Optional) +

ClusterIPs is a list of IP addresses assigned to this service, and are +usually assigned randomly. If an address is specified manually, is +in-range (as per system configuration), and is not in use, it will be +allocated to the service; otherwise creation of the service will fail. +This field may not be changed through updates unless the type field is +also being changed to ExternalName (which requires this field to be +empty) or the type field is being changed from ExternalName (in which +case this field may optionally be specified, as describe above). Valid +values are “None”, empty string (“”), or a valid IP address. Setting +this to “None” makes a “headless service” (no virtual IP), which is +useful when direct endpoint connections are preferred and proxying is +not required. Only applies to types ClusterIP, NodePort, and +LoadBalancer. If this field is specified when creating a Service of type +ExternalName, creation will fail. This field will be wiped when updating +a Service to type ExternalName. If this field is not specified, it will +be initialized from the clusterIP field. If this field is specified, +clients must ensure that clusterIPs[0] and clusterIP have the same +value.

+

This field may hold a maximum of two entries (dual-stack IPs, in either order). +These IPs must correspond to the values of the ipFamilies field. Both +clusterIPs and ipFamilies are governed by the ipFamilyPolicy field. +More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies

+
+type
+ + +Kubernetes core/v1.ServiceType + + +
+(Optional) +

type determines how the Service is exposed. Defaults to ClusterIP. Valid +options are ExternalName, ClusterIP, NodePort, and LoadBalancer. +“ClusterIP” allocates a cluster-internal IP address for load-balancing +to endpoints. Endpoints are determined by the selector or if that is not +specified, by manual construction of an Endpoints object or +EndpointSlice objects. If clusterIP is “None”, no virtual IP is +allocated and the endpoints are published as a set of endpoints rather +than a virtual IP. +“NodePort” builds on ClusterIP and allocates a port on every node which +routes to the same endpoints as the clusterIP. +“LoadBalancer” builds on NodePort and creates an external load-balancer +(if supported in the current cloud) which routes to the same endpoints +as the clusterIP. +“ExternalName” aliases this service to the specified externalName. +Several other fields do not apply to ExternalName services. +More info: https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types

+
+externalIPs
+ +[]string + +
+(Optional) +

externalIPs is a list of IP addresses for which nodes in the cluster +will also accept traffic for this service. These IPs are not managed by +Kubernetes. The user is responsible for ensuring that traffic arrives +at a node with this IP. A common example is external load-balancers +that are not part of the Kubernetes system.

+
+sessionAffinity
+ + +Kubernetes core/v1.ServiceAffinity + + +
+(Optional) +

Supports “ClientIP” and “None”. Used to maintain session affinity. +Enable client IP based session affinity. +Must be ClientIP or None. +Defaults to None. +More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies

+
+loadBalancerIP
+ +string + +
+(Optional) +

Only applies to Service Type: LoadBalancer. +This feature depends on whether the underlying cloud-provider supports specifying +the loadBalancerIP when a load balancer is created. +This field will be ignored if the cloud-provider does not support the feature. +Deprecated: This field was under-specified and its meaning varies across implementations. +Using it is non-portable and it may not support dual-stack. +Users are encouraged to use implementation-specific annotations when available.

+
+loadBalancerSourceRanges
+ +[]string + +
+(Optional) +

If specified and supported by the platform, this will restrict traffic through the cloud-provider +load-balancer will be restricted to the specified client IPs. This field will be ignored if the +cloud-provider does not support the feature.” +More info: https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/

+
+externalName
+ +string + +
+(Optional) +

externalName is the external reference that discovery mechanisms will +return as an alias for this service (e.g. a DNS CNAME record). No +proxying will be involved. Must be a lowercase RFC-1123 hostname +(https://tools.ietf.org/html/rfc1123) and requires type to be “ExternalName”.

+
+externalTrafficPolicy
+ + +Kubernetes core/v1.ServiceExternalTrafficPolicy + + +
+(Optional) +

externalTrafficPolicy describes how nodes distribute service traffic they +receive on one of the Service’s “externally-facing” addresses (NodePorts, +ExternalIPs, and LoadBalancer IPs). If set to “Local”, the proxy will configure +the service in a way that assumes that external load balancers will take care +of balancing the service traffic between nodes, and so each node will deliver +traffic only to the node-local endpoints of the service, without masquerading +the client source IP. (Traffic mistakenly sent to a node with no endpoints will +be dropped.) The default value, “Cluster”, uses the standard behavior of +routing to all endpoints evenly (possibly modified by topology and other +features). Note that traffic sent to an External IP or LoadBalancer IP from +within the cluster will always get “Cluster” semantics, but clients sending to +a NodePort from within the cluster may need to take traffic policy into account +when picking a node.

+
+healthCheckNodePort
+ +int32 + +
+(Optional) +

healthCheckNodePort specifies the healthcheck nodePort for the service. +This only applies when type is set to LoadBalancer and +externalTrafficPolicy is set to Local. If a value is specified, is +in-range, and is not in use, it will be used. If not specified, a value +will be automatically allocated. External systems (e.g. load-balancers) +can use this port to determine if a given node holds endpoints for this +service or not. If this field is specified when creating a Service +which does not need it, creation will fail. This field will be wiped +when updating a Service to no longer need it (e.g. changing type). +This field cannot be updated once set.

+
+publishNotReadyAddresses
+ +bool + +
+(Optional) +

publishNotReadyAddresses indicates that any agent which deals with endpoints for this +Service should disregard any indications of ready/not-ready. +The primary use case for setting this field is for a StatefulSet’s Headless Service to +propagate SRV DNS records for its Pods for the purpose of peer discovery. +The Kubernetes controllers that generate Endpoints and EndpointSlice resources for +Services interpret this to mean that all endpoints are considered “ready” even if the +Pods themselves are not. Agents which consume only Kubernetes generated endpoints +through the Endpoints or EndpointSlice resources can safely assume this behavior.

+
+sessionAffinityConfig
+ + +Kubernetes core/v1.SessionAffinityConfig + + +
+(Optional) +

sessionAffinityConfig contains the configurations of session affinity.

+
+ipFamilies
+ + +[]Kubernetes core/v1.IPFamily + + +
+(Optional) +

IPFamilies is a list of IP families (e.g. IPv4, IPv6) assigned to this +service. This field is usually assigned automatically based on cluster +configuration and the ipFamilyPolicy field. If this field is specified +manually, the requested family is available in the cluster, +and ipFamilyPolicy allows it, it will be used; otherwise creation of +the service will fail. This field is conditionally mutable: it allows +for adding or removing a secondary IP family, but it does not allow +changing the primary IP family of the Service. Valid values are “IPv4” +and “IPv6”. This field only applies to Services of types ClusterIP, +NodePort, and LoadBalancer, and does apply to “headless” services. +This field will be wiped when updating a Service to type ExternalName.

+

This field may hold a maximum of two entries (dual-stack families, in +either order). These families must correspond to the values of the +clusterIPs field, if specified. Both clusterIPs and ipFamilies are +governed by the ipFamilyPolicy field.

ComponentDefinition
-metadata
+ipFamilyPolicy
- -Kubernetes meta/v1.ObjectMeta + +Kubernetes core/v1.IPFamilyPolicy
-Refer to the Kubernetes API documentation for the fields of the -metadata field. +(Optional) +

IPFamilyPolicy represents the dual-stack-ness requested or required by +this Service. If there is no value provided, then this field will be set +to SingleStack. Services can be “SingleStack” (a single IP family), +“PreferDualStack” (two IP families on dual-stack configured clusters or +a single IP family on single-stack clusters), or “RequireDualStack” +(two IP families on dual-stack configured clusters, otherwise fail). The +ipFamilies and clusterIPs fields depend on the value of this field. This +field will be wiped when updating a service to type ExternalName.

-spec
+allocateLoadBalancerNodePorts
- -ComponentDefinitionSpec - +bool
-
-
- +(Optional) +

allocateLoadBalancerNodePorts defines if NodePorts will be automatically +allocated for services with type LoadBalancer. Default is “true”. It +may be set to “false” if the cluster load-balancer does not rely on +NodePorts. If the caller requests specific NodePorts (by specifying a +value), those requests will be respected, regardless of this field. +This field may only be set for services with type LoadBalancer and will +be cleared if the type is changed to any other type.

+ + + + + +
-foo
+loadBalancerClass
string
-

Foo is an example field of ComponentDefinition. Edit componentdefinition_types.go to remove/update

+(Optional) +

loadBalancerClass is the class of the load balancer implementation this Service belongs to. +If specified, the value of this field must be a label-style identifier, with an optional prefix, +e.g. “internal-vip” or “example.com/internal-vip”. Unprefixed names are reserved for end-users. +This field can only be set when the Service type is ‘LoadBalancer’. If not set, the default load +balancer implementation is used, today this is typically done through the cloud provider integration, +but should apply for any default implementation. If set, it is assumed that a load balancer +implementation is watching for Services with a matching class. Any default load balancer +implementation (e.g. cloud providers) should ignore Services that set this field. +This field can only be set when creating or updating a Service to type ‘LoadBalancer’. +Once set, it can not be changed. This field will be wiped when a service is updated to a non ‘LoadBalancer’ type.

+
+internalTrafficPolicy
+ + +Kubernetes core/v1.ServiceInternalTrafficPolicy + + +
+(Optional) +

InternalTrafficPolicy describes how nodes distribute service traffic they +receive on the ClusterIP. If set to “Local”, the proxy will assume that pods +only want to talk to endpoints of the service on the same node as the pod, +dropping the traffic if there are no local endpoints. The default value, +“Cluster”, uses the standard behavior of routing to all endpoints evenly +(possibly modified by topology and other features).

@@ -418,22 +7326,36 @@ string
-status
+roleSelector
- -ComponentDefinitionStatus - +string
+(Optional) +

Extends the above serviceSpec.selector by allowing you to specify defined role as selector for the service. +When roleSelector is set, it adds a label selector “kubeblocks.io/role: {roleSelector}” +to the serviceSpec.selector. +Example usage:

+
  roleSelector: "leader"
+
+

In this example, setting roleSelector to “leader” will add a label selector +“kubeblocks.io/role: leader” to the serviceSpec.selector. +This means that the service will select and route traffic to Pods with the label +“kubeblocks.io/role” set to “leader”.

+

Note that if podService sets to true, RoleSelector will be ignored. +The podService flag takes precedence over roleSelector and generates a service for each Pod.

-

ComponentVersion +

ServiceDescriptorSpec

+

+(Appears on:ServiceDescriptor) +

-

ComponentVersion is the Schema for the componentversions API

+

ServiceDescriptorSpec defines the desired state of ServiceDescriptor

@@ -445,96 +7367,104 @@ ComponentDefinitionStatus - - - -
-apiVersion
-string
-apps.kubeblocks.io/v1 +serviceKind
+ +string +
-kind
-string +

Describes the type of database service provided by the external service. +For example, “mysql”, “redis”, “mongodb”. +This field categorizes databases by their functionality, protocol and compatibility, facilitating appropriate +service integration based on their unique capabilities.

+

This field is case-insensitive.

+

It also supports abbreviations for some well-known databases: +- “pg”, “pgsql”, “postgres”, “postgresql”: PostgreSQL service +- “zk”, “zookeeper”: ZooKeeper service +- “es”, “elasticsearch”: Elasticsearch service +- “mongo”, “mongodb”: MongoDB service +- “ch”, “clickhouse”: ClickHouse service

ComponentVersion
-metadata
+serviceVersion
- -Kubernetes meta/v1.ObjectMeta - +string
-Refer to the Kubernetes API documentation for the fields of the -metadata field. +

Describes the version of the service provided by the external service. +This is crucial for ensuring compatibility between different components of the system, +as different versions of a service may have varying features.

-spec
+endpoint
- -ComponentVersionSpec + +CredentialVar
-
-
- +(Optional) +

Specifies the endpoint of the external service.

+

If the service is exposed via a cluster, the endpoint will be provided in the format of host:port.

+ + - -
-compatibilityRules
+host
- -[]ComponentVersionCompatibilityRule + +CredentialVar
-

CompatibilityRules defines compatibility rules between sets of component definitions and releases.

+(Optional) +

Specifies the service or IP address of the external service.

-releases
+port
- -[]ComponentVersionRelease + +CredentialVar
-

Releases represents different releases of component instances within this ComponentVersion.

-
+(Optional) +

Specifies the port of the external service.

-status
+auth
- -ComponentVersionStatus + +ConnectionCredentialAuth
+(Optional) +

Specifies the authentication credentials required for accessing an external service.

-

ServiceDescriptor +

ServiceDescriptorStatus

+

+(Appears on:ServiceDescriptor) +

-

ServiceDescriptor describes a service provided by external sources. -It contains the necessary details such as the service’s address and connection credentials. -To enable a Cluster to access this service, the ServiceDescriptor’s name should be specified -in the Cluster configuration under clusterComponent.serviceRefs[*].serviceDescriptor.

+

ServiceDescriptorStatus defines the observed state of ServiceDescriptor

@@ -546,193 +7476,155 @@ in the Cluster configuration under clusterComponent.serviceRefs[*].service - - - - - - - - - -
-apiVersion
-string
-apps.kubeblocks.io/v1 -
-kind
-string -
ServiceDescriptor
-metadata
+observedGeneration
- -Kubernetes meta/v1.ObjectMeta - +int64
-Refer to the Kubernetes API documentation for the fields of the -metadata field. +(Optional) +

Represents the generation number that has been processed by the controller.

-spec
+phase
- -ServiceDescriptorSpec + +Phase
-
-
- - - - - - - - + +
-serviceKind
- -string - -
-

Describes the type of database service provided by the external service. -For example, “mysql”, “redis”, “mongodb”. -This field categorizes databases by their functionality, protocol and compatibility, facilitating appropriate -service integration based on their unique capabilities.

-

This field is case-insensitive.

-

It also supports abbreviations for some well-known databases: -- “pg”, “pgsql”, “postgres”, “postgresql”: PostgreSQL service -- “zk”, “zookeeper”: ZooKeeper service -- “es”, “elasticsearch”: Elasticsearch service -- “mongo”, “mongodb”: MongoDB service -- “ch”, “clickhouse”: ClickHouse service

+(Optional) +

Indicates the current lifecycle phase of the ServiceDescriptor. This can be either ‘Available’ or ‘Unavailable’.

-serviceVersion
+message
string
-

Describes the version of the service provided by the external service. -This is crucial for ensuring compatibility between different components of the system, -as different versions of a service may have varying features.

-
-endpoint
- - -CredentialVar - - -
(Optional) -

Specifies the endpoint of the external service.

-

If the service is exposed via a cluster, the endpoint will be provided in the format of host:port.

+

Provides a human-readable explanation detailing the reason for the current phase of the ServiceConnectionCredential.

+

ServiceRef +

+

+(Appears on:ComponentSpec) +

+
+
+ + + + + + + + - -
FieldDescription
-host
+name
- -CredentialVar - +string
-(Optional) -

Specifies the service or IP address of the external service.

+

Specifies the identifier of the service reference declaration. +It corresponds to the serviceRefDeclaration name defined in either:

+
    +
  • componentDefinition.spec.serviceRefDeclarations[*].name
  • +
  • clusterDefinition.spec.componentDefs[*].serviceRefDeclarations[*].name (deprecated)
  • +
-port
+namespace
- -CredentialVar - +string
(Optional) -

Specifies the port of the external service.

+

Specifies the namespace of the referenced Cluster or the namespace of the referenced ServiceDescriptor object. +If not provided, the referenced Cluster and ServiceDescriptor will be searched in the namespace of the current +Cluster by default.

-auth
+cluster
- -ConnectionCredentialAuth - +string
(Optional) -

Specifies the authentication credentials required for accessing an external service.

-
+

Specifies the name of the KubeBlocks Cluster being referenced. +This is used when services from another KubeBlocks Cluster are consumed.

+

By default, the referenced KubeBlocks Cluster’s clusterDefinition.spec.connectionCredential +will be utilized to bind to the current Component. This credential should include: +endpoint, port, username, and password.

+

Note:

+
    +
  • The ServiceKind and ServiceVersion specified in the service reference within the +ClusterDefinition are not validated when using this approach.
  • +
  • If both cluster and serviceDescriptor are present, cluster will take precedence.
  • +
+

Deprecated since v0.9 since clusterDefinition.spec.connectionCredential is deprecated, +use clusterServiceSelector instead. +This field is maintained for backward compatibility and its use is discouraged. +Existing usage should be updated to the current preferred approach to avoid compatibility issues in future releases.

-status
+clusterServiceSelector
- -ServiceDescriptorStatus + +ServiceRefClusterSelector
+(Optional) +

References a service provided by another KubeBlocks Cluster. +It specifies the ClusterService and the account credentials needed for access.

-

ClusterDefinitionSpec -

-

-(Appears on:ClusterDefinition) -

-
-

ClusterDefinitionSpec defines the desired state of ClusterDefinition.

-
- - - - - - - -
FieldDescription
-topologies
+serviceDescriptor
- -[]ClusterTopology - +string
(Optional) -

Topologies defines all possible topologies within the cluster.

+

Specifies the name of the ServiceDescriptor object that describes a service provided by external sources.

+

When referencing a service provided by external sources, a ServiceDescriptor object is required to establish +the service binding. +The serviceDescriptor.spec.serviceKind and serviceDescriptor.spec.serviceVersion should match the serviceKind +and serviceVersion declared in the definition.

+

If both cluster and serviceDescriptor are specified, the cluster takes precedence.

-

ClusterDefinitionStatus +

ServiceRefClusterSelector

-(Appears on:ClusterDefinition) +(Appears on:ServiceRef)

-

ClusterDefinitionStatus defines the observed state of ClusterDefinition

@@ -744,63 +7636,53 @@ ServiceDescriptorStatus - - - -
-observedGeneration
+cluster
-int64 +string
-(Optional) -

Represents the most recent generation observed for this ClusterDefinition.

+

The name of the Cluster being referenced.

-phase
+service
- -Phase + +ServiceRefServiceSelector
-

Specifies the current phase of the ClusterDefinition. Valid values are empty, Available, Unavailable. -When Available, the ClusterDefinition is ready and can be referenced by related objects.

-
-message
- -string - -
(Optional) -

Provides additional information about the current phase.

+

Identifies a ClusterService from the list of Services defined in cluster.spec.services of the referenced Cluster.

-topologies
+credential
-string + +ServiceRefCredentialSelector +
(Optional) -

Topologies this ClusterDefinition supported.

+

Specifies the SystemAccount to authenticate and establish a connection with the referenced Cluster. +The SystemAccount should be defined in componentDefinition.spec.systemAccounts +of the Component providing the service in the referenced Cluster.

-

ClusterSpec +

ServiceRefCredentialSelector

-(Appears on:Cluster) +(Appears on:ServiceRefClusterSelector)

-

ClusterSpec defines the desired state of Cluster

@@ -812,32 +7694,44 @@ string + + + +
-foo
+component
string
-

Foo is an example field of Cluster. Edit cluster_types.go to remove/update

+

The name of the Component where the credential resides in.

+
+name
+ +string + +
+

The name of the credential (SystemAccount) to reference.

-

ClusterStatus -

-

-(Appears on:Cluster) -

-
-

ClusterStatus defines the observed state of Cluster

-
-

ClusterTopology +

ServiceRefDeclaration

-(Appears on:ClusterDefinitionSpec) +(Appears on:ComponentDefinitionSpec)

-

ClusterTopology represents the definition for a specific cluster topology.

+

ServiceRefDeclaration represents a reference to a service that can be either provided by a KubeBlocks Cluster +or an external service. +It acts as a placeholder for the actual service reference, which is determined later when a Cluster is created.

+

The purpose of ServiceRefDeclaration is to declare a service dependency without specifying the concrete details +of the service. +It allows for flexibility and abstraction in defining service references within a Component. +By using ServiceRefDeclaration, you can define service dependencies in a declarative manner, enabling loose coupling +and easier management of service references across different components and clusters.

+

Upon Cluster creation, the ServiceRefDeclaration is bound to an actual service through the ServiceRef field, +effectively resolving and connecting to the specified service.

@@ -855,61 +7749,49 @@ string - - - -
-

Name is the unique identifier for the cluster topology. -Cannot be updated.

-
-components
- - -[]ClusterTopologyComponent - - -
-

Components specifies the components in the topology.

+

Specifies the name of the ServiceRefDeclaration.

-orders
+serviceRefDeclarationSpecs
- -ClusterTopologyOrders + +[]ServiceRefDeclarationSpec
-(Optional) -

Specifies the sequence in which components within a cluster topology are -started, stopped, and upgraded. -This ordering is crucial for maintaining the correct dependencies and operational flow across components.

+

Defines a list of constraints and requirements for services that can be bound to this ServiceRefDeclaration +upon Cluster creation. +Each ServiceRefDeclarationSpec defines a ServiceKind and ServiceVersion, +outlining the acceptable service types and versions that are compatible.

+

This flexibility allows a ServiceRefDeclaration to be fulfilled by any one of the provided specs. +For example, if it requires an OLTP database, specs for both MySQL and PostgreSQL are listed, +either MySQL or PostgreSQL services can be used when binding.

-default
+optional
bool
(Optional) -

Default indicates whether this topology serves as the default configuration. -When set to true, this topology is automatically used unless another is explicitly specified.

+

Specifies whether the service reference can be optional.

+

For an optional service-ref, the component can still be created even if the service-ref is not provided.

-

ClusterTopologyComponent +

ServiceRefDeclarationSpec

-(Appears on:ClusterTopology) +(Appears on:ServiceRefDeclaration)

-

ClusterTopologyComponent defines a Component within a ClusterTopology.

@@ -921,51 +7803,39 @@ When set to true, this topology is automatically used unless another is explicit
-name
+serviceKind
string
-

Defines the unique identifier of the component within the cluster topology. -It follows IANA Service naming rules and is used as part of the Service’s DNS name. -The name must start with a lowercase letter, can contain lowercase letters, numbers, -and hyphens, and must end with a lowercase letter or number.

-

Cannot be updated once set.

+

Specifies the type or nature of the service. This should be a well-known application cluster type, such as +{mysql, redis, mongodb}. +The field is case-insensitive and supports abbreviations for some well-known databases. +For instance, both zk and zookeeper are considered as a ZooKeeper cluster, while pg, postgres, postgresql +are all recognized as a PostgreSQL cluster.

-compDef
+serviceVersion
string
-

Specifies the name or prefix of the ComponentDefinition custom resource(CR) that -defines the Component’s characteristics and behavior.

-

When a prefix is used, the system selects the ComponentDefinition CR with the latest version that matches the prefix. -This approach allows:

-
    -
  1. Precise selection by providing the exact name of a ComponentDefinition CR.
  2. -
  3. Flexible and automatic selection of the most up-to-date ComponentDefinition CR by specifying a prefix.
  4. -
-

Once set, this field cannot be updated.

+

Defines the service version of the service reference. This is a regular expression that matches a version number pattern. +For instance, ^8.0.8$, 8.0.\d{1,2}$, ^[v\-]*?(\d{1,2}\.){0,3}\d{1,2}$ are all valid patterns.

-

ClusterTopologyOrders +

ServiceRefServiceSelector

-(Appears on:ClusterTopology) +(Appears on:ServiceRefClusterSelector)

-

ClusterTopologyOrders manages the lifecycle of components within a cluster by defining their provisioning, -terminating, and updating sequences. -It organizes components into stages or groups, where each group indicates a set of components -that can be managed concurrently. -These groups are processed sequentially, allowing precise control based on component dependencies and requirements.

@@ -977,58 +7847,55 @@ These groups are processed sequentially, allowing precise control based on compo
-provision
+component
-[]string +string
(Optional) -

Specifies the order for creating and initializing components. -This is designed for components that depend on one another. Components without dependencies can be grouped together.

-

Components that can be provisioned independently or have no dependencies can be listed together in the same stage, -separated by commas.

+

The name of the Component where the Service resides in.

+

It is required when referencing a Component’s Service.

-terminate
+service
-[]string +string
-(Optional) -

Outlines the order for stopping and deleting components. -This sequence is designed for components that require a graceful shutdown or have interdependencies.

-

Components that can be terminated independently or have no dependencies can be listed together in the same stage, -separated by commas.

+

The name of the Service to be referenced.

+

Leave it empty to reference the default Service. Set it to “headless” to reference the default headless Service.

+

If the referenced Service is of pod-service type (a Service per Pod), there will be multiple Service objects matched, +and the resolved value will be presented in the following format: service1.name,service2.name…

-update
+port
-[]string +string
(Optional) -

Update determines the order for updating components’ specifications, such as image upgrades or resource scaling. -This sequence is designed for components that have dependencies or require specific update procedures.

-

Components that can be updated independently or have no dependencies can be listed together in the same stage, -separated by commas.

+

The port name of the Service to be referenced.

+

If there is a non-zero node-port exist for the matched Service port, the node-port will be selected first.

+

If the referenced Service is of pod-service type (a Service per Pod), there will be multiple Service objects matched, +and the resolved value will be presented in the following format: service1.name:port1,service2.name:port2…

-

ComponentDefinitionSpec +

ServiceRefVarSelector

-(Appears on:ComponentDefinition) +(Appears on:VarSource)

-

ComponentDefinitionSpec defines the desired state of ComponentDefinition

+

ServiceRefVarSelector selects a var from a ServiceRefDeclaration.

@@ -1040,32 +7907,44 @@ separated by commas.

- -
-foo
+ClusterObjectReference
-string + +ClusterObjectReference +
-

Foo is an example field of ComponentDefinition. Edit componentdefinition_types.go to remove/update

+

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

+

The ServiceRefDeclaration to select from.

-

ComponentDefinitionStatus -

+
+ServiceRefVars
+ + +ServiceRefVars + + +

-(Appears on:ComponentDefinition) +(Members of ServiceRefVars are embedded into this type.)

-
-

ComponentDefinitionStatus defines the observed state of ComponentDefinition

-
-

ComponentSpec +

+

ServiceRefVars

-(Appears on:Component) +(Appears on:ServiceRefVarSelector)

-

ComponentSpec defines the desired state of Component

+

ServiceRefVars defines the vars that can be referenced from a ServiceRef.

@@ -1077,32 +7956,67 @@ string - -
-foo
+endpoint
-string + +VarOption +
-

Foo is an example field of Component. Edit component_types.go to remove/update

+(Optional)
-

ComponentStatus -

+ + +host
+ + +VarOption + + + + +(Optional) + + + + +port
+ + +VarOption + + + + +(Optional) + + + + +CredentialVars
+ + +CredentialVars + + + +

-(Appears on:Component) +(Members of CredentialVars are embedded into this type.)

-
-

ComponentStatus defines the observed state of Component

-
-

ComponentVersionCompatibilityRule + + + + +

ServiceVarSelector

-(Appears on:ComponentVersionSpec) +(Appears on:VarSource)

-

ComponentVersionCompatibilityRule defines the compatibility between a set of component definitions and a set of releases.

+

ServiceVarSelector selects a var from a Service.

@@ -1114,41 +8028,45 @@ string
-compDefs
+ClusterObjectReference
-[]string + +ClusterObjectReference +
-

CompDefs specifies names for the component definitions associated with this ComponentVersion. -Each name in the list can represent an exact name, or a name prefix.

-

For example:

-
    -
  • “mysql-8.0.30-v1alpha1”: Matches the exact name “mysql-8.0.30-v1alpha1”
  • -
  • “mysql-8.0.30”: Matches all names starting with “mysql-8.0.30”
  • -
+

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

+

The Service to select from. +It can be referenced from the default headless service by setting the name to “headless”.

-releases
+ServiceVars
-[]string + +ServiceVars +
-

Releases is a list of identifiers for the releases.

+

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

-

ComponentVersionRelease +

ServiceVars

-(Appears on:ComponentVersionSpec) +(Appears on:ServiceVarSelector)

-

ComponentVersionRelease represents a release of component instances within a ComponentVersion.

+

ServiceVars defines the vars that can be referenced from a Service.

@@ -1160,62 +8078,70 @@ Each name in the list can represent an exact name, or a name prefix.

-name
+serviceType
-string + +VarOption +
-

Name is a unique identifier for this release. -Cannot be updated.

+(Optional) +

ServiceType references the type of the service.

-changes
+host
-string + +VarOption +
(Optional) -

Changes provides information about the changes made in this release.

-serviceVersion
+loadBalancer
-string + +VarOption +
-

ServiceVersion defines the version of the well-known service that the component provides. -The version should follow the syntax and semantics of the “Semantic Versioning” specification (http://semver.org/). -If the release is used, it will serve as the service version for component instances, overriding the one defined in the component definition. -Cannot be updated.

+(Optional) +

LoadBalancer represents the LoadBalancer ingress point of the service.

+

If multiple ingress points are available, the first one will be used automatically, choosing between IP and Hostname.

-images
+port
-map[string]string + +NamedVar +
-

Images define the new images for different containers within the release.

+(Optional) +

Port references a port or node-port defined in the service.

+

If the referenced service is a pod-service, there will be multiple service objects matched, +and the value will be presented in the following format: service1.name:port1,service2.name:port2…

-

ComponentVersionSpec +

SystemAccount

-(Appears on:ComponentVersion) +(Appears on:ComponentDefinitionSpec)

-

ComponentVersionSpec defines the desired state of ComponentVersion

@@ -1227,108 +8153,80 @@ map[string]string - - - - - -
-compatibilityRules
- - -[]ComponentVersionCompatibilityRule - - -
-

CompatibilityRules defines compatibility rules between sets of component definitions and releases.

-
-releases
+name
- -[]ComponentVersionRelease - +string
-

Releases represents different releases of component instances within this ComponentVersion.

+

Specifies the unique identifier for the account. This name is used by other entities to reference the account.

+

This field is immutable once set.

-

ComponentVersionStatus -

-

-(Appears on:ComponentVersion) -

-
-

ComponentVersionStatus defines the observed state of ComponentVersion

-
- - - - - - - -
FieldDescription
-observedGeneration
+initAccount
-int64 +bool
(Optional) -

ObservedGeneration is the most recent generation observed for this ComponentVersion.

+

Indicates if this account is a system initialization account (e.g., MySQL root).

+

This field is immutable once set.

-phase
+statement
- -Phase - +string
(Optional) -

Phase valid values are `,Available, 'Unavailable. -Available is ComponentVersion become available, and can be used for co-related objects.

+

Defines the statement used to create the account with the necessary privileges.

+

This field is immutable once set.

-message
+passwordGenerationPolicy
-string + +PasswordConfig +
(Optional) -

Extra message for current phase.

+

Specifies the policy for generating the account’s password.

+

This field is immutable once set.

-serviceVersions
+secretRef
-string + +ProvisionSecretRef +
(Optional) -

ServiceVersions represent the supported service versions of this ComponentVersion.

+

Refers to the secret from which data will be copied to create the new account.

+

This field is immutable once set.

-

ConnectionCredentialAuth +

TLSConfig

-(Appears on:ServiceDescriptorSpec) +(Appears on:ComponentSpec)

-

ConnectionCredentialAuth specifies the authentication credentials required for accessing an external service.

@@ -1340,43 +8238,48 @@ string
-username
+enable
- -CredentialVar - +bool
(Optional) -

Specifies the username for the external service.

+

A boolean flag that indicates whether the Component should use Transport Layer Security (TLS) +for secure communication. +When set to true, the Component will be configured to use TLS encryption for its network connections. +This ensures that the data transmitted between the Component and its clients or other Components is encrypted +and protected from unauthorized access. +If TLS is enabled, the Component may require additional configuration, +such as specifying TLS certificates and keys, to properly set up the secure communication channel.

-password
+issuer
- -CredentialVar + +Issuer
(Optional) -

Specifies the password for the external service.

+

Specifies the configuration for the TLS certificates issuer. +It allows defining the issuer name and the reference to the secret containing the TLS certificates and key. +The secret should contain the CA certificate, TLS certificate, and private key in the specified keys. +Required when TLS is enabled.

-

CredentialVar +

TLSSecretRef

-(Appears on:ConnectionCredentialAuth, ServiceDescriptorSpec) +(Appears on:Issuer)

-

CredentialVar represents a variable that retrieves its value either directly from a specified expression -or from a source defined in valueFrom. -Only one of these options may be used at a time.

+

TLSSecretRef defines Secret contains Tls certs

@@ -1388,49 +8291,57 @@ Only one of these options may be used at a time.

+ + + + + + + +
-value
+name
string
-(Optional) -

Holds a direct string or an expression that can be evaluated to a string.

-

It can include variables denoted by $(VAR_NAME). -These variables are expanded to the value of the environment variables defined in the container. -If a variable cannot be resolved, it remains unchanged in the output.

-

To escape variable expansion and retain the literal value, use double $ characters.

-

For example:

-
    -
  • ”$(VAR_NAME)” will be expanded to the value of the environment variable VAR_NAME.
  • -
  • ”$$(VAR_NAME)” will result in “$(VAR_NAME)” in the output, without any variable expansion.
  • -
-

Default value is an empty string.

+

Name of the Secret that contains user-provided certificates.

-valueFrom
+ca
- -Kubernetes core/v1.EnvVarSource - +string
-(Optional) -

Specifies the source for the variable’s value.

+

Key of CA cert in Secret

+
+cert
+ +string + +
+

Key of Cert in Secret

+
+key
+ +string + +
+

Key of TLS private key in Secret

-

Phase +

TargetPodSelector (string alias)

-(Appears on:ClusterDefinitionStatus, ComponentVersionStatus, ServiceDescriptorStatus) +(Appears on:ExecAction)

-

Phase represents the status of a CR.

+

TargetPodSelector defines how to select pod(s) to execute an Action.

@@ -1439,21 +8350,72 @@ Kubernetes core/v1.EnvVarSource - - + + + + + + + + +
Description

"Available"

AvailablePhase indicates that a CR is in an available state.

+

"All"

"Any"

"Ordinal"

"Role"

+

UpdateStrategy +(string alias)

+

+(Appears on:ComponentDefinitionSpec) +

+
+

UpdateStrategy defines the update strategy for cluster components. This strategy determines how updates are applied +across the cluster. +The available strategies are Serial, BestEffortParallel, and Parallel.

+
+ + + + + + + + + - - + + +
ValueDescription

"BestEffortParallel"

BestEffortParallelStrategy indicates that the replicas are updated in parallel, with the operator making +a best-effort attempt to update as many replicas as possible concurrently +while maintaining the component’s availability. +Unlike the Parallel strategy, the BestEffortParallel strategy aims to ensure that a minimum number +of replicas remain available during the update process to maintain the component’s quorum and functionality.

+

For example, consider a component with 5 replicas. To maintain the component’s availability and quorum, +the operator may allow a maximum of 2 replicas to be simultaneously updated. This ensures that at least +3 replicas (a quorum) remain available and functional during the update process.

+

The BestEffortParallel strategy strikes a balance between update speed and component availability.

"Unavailable"

UnavailablePhase indicates that a CR is in an unavailable state.

+

"Parallel"

ParallelStrategy indicates that updates are applied simultaneously to all Pods of a Component. +The replicas are updated in parallel, with the operator updating all replicas concurrently. +This strategy provides the fastest update time but may lead to a period of reduced availability or +capacity during the update process.

+

"Serial"

SerialStrategy indicates that updates are applied one at a time in a sequential manner. +The operator waits for each replica to be updated and ready before proceeding to the next one. +This ensures that only one replica is unavailable at a time during the update process.

-

ServiceDescriptorSpec +

VarOption +(string alias)

+

+(Appears on:ClusterVars, ComponentVars, CredentialVars, NamedVar, RoledVar, ServiceRefVars, ServiceVars) +

+
+

VarOption defines whether a variable is required or optional.

+
+

VarSource

-(Appears on:ServiceDescriptor) +(Appears on:EnvVar)

-

ServiceDescriptorSpec defines the desired state of ServiceDescriptor

+

VarSource represents a source for the value of an EnvVar.

@@ -1465,149 +8427,114 @@ Kubernetes core/v1.EnvVarSource - - - - - -
-serviceKind
- -string - -
-

Describes the type of database service provided by the external service. -For example, “mysql”, “redis”, “mongodb”. -This field categorizes databases by their functionality, protocol and compatibility, facilitating appropriate -service integration based on their unique capabilities.

-

This field is case-insensitive.

-

It also supports abbreviations for some well-known databases: -- “pg”, “pgsql”, “postgres”, “postgresql”: PostgreSQL service -- “zk”, “zookeeper”: ZooKeeper service -- “es”, “elasticsearch”: Elasticsearch service -- “mongo”, “mongodb”: MongoDB service -- “ch”, “clickhouse”: ClickHouse service

-
-serviceVersion
+configMapKeyRef
-string + +Kubernetes core/v1.ConfigMapKeySelector +
-

Describes the version of the service provided by the external service. -This is crucial for ensuring compatibility between different components of the system, -as different versions of a service may have varying features.

+(Optional) +

Selects a key of a ConfigMap.

-endpoint
+secretKeyRef
- -CredentialVar + +Kubernetes core/v1.SecretKeySelector
(Optional) -

Specifies the endpoint of the external service.

-

If the service is exposed via a cluster, the endpoint will be provided in the format of host:port.

+

Selects a key of a Secret.

-host
+hostNetworkVarRef
- -CredentialVar + +HostNetworkVarSelector
(Optional) -

Specifies the service or IP address of the external service.

+

Selects a defined var of host-network resources.

-port
+serviceVarRef
- -CredentialVar + +ServiceVarSelector
(Optional) -

Specifies the port of the external service.

+

Selects a defined var of a Service.

-auth
+credentialVarRef
- -ConnectionCredentialAuth + +CredentialVarSelector
(Optional) -

Specifies the authentication credentials required for accessing an external service.

+

Selects a defined var of a Credential (SystemAccount).

-

ServiceDescriptorStatus -

-

-(Appears on:ServiceDescriptor) -

-
-

ServiceDescriptorStatus defines the observed state of ServiceDescriptor

-
- - - - - - - - diff --git a/pkg/common/monitor.go b/pkg/common/monitor.go index 03c1adccad1..b455d4041df 100644 --- a/pkg/common/monitor.go +++ b/pkg/common/monitor.go @@ -22,7 +22,7 @@ import ( corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/util/intstr" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" ) const ( @@ -34,10 +34,10 @@ const ( const ( defaultScrapePath = "/metrics" - defaultScrapeScheme = string(appsv1alpha1.HTTPProtocol) + defaultScrapeScheme = string(appsv1.HTTPProtocol) ) -func FromScrapePath(exporter appsv1alpha1.Exporter) string { +func FromScrapePath(exporter appsv1.Exporter) string { if exporter.ScrapePath != "" { return exporter.ScrapePath } @@ -82,7 +82,7 @@ func FromContainerPort(exporter Exporter, container *corev1.Container) string { return "" } -func FromScheme(exporter appsv1alpha1.Exporter) string { +func FromScheme(exporter appsv1.Exporter) string { if exporter.ScrapeScheme != "" { return string(exporter.ScrapeScheme) } diff --git a/pkg/common/monitor_test.go b/pkg/common/monitor_test.go index 77c30c86c80..7c990d734ea 100644 --- a/pkg/common/monitor_test.go +++ b/pkg/common/monitor_test.go @@ -22,7 +22,7 @@ import ( corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/util/intstr" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" ) func TestFromContainerPort(t *testing.T) { @@ -48,7 +48,7 @@ func TestFromContainerPort(t *testing.T) { name: "port name", args: args{ exporter: Exporter{ - Exporter: appsv1alpha1.Exporter{ + Exporter: appsv1.Exporter{ ContainerName: "metrics", ScrapePath: "/metrics", ScrapePort: "http", @@ -61,7 +61,7 @@ func TestFromContainerPort(t *testing.T) { name: "port number", args: args{ exporter: Exporter{ - Exporter: appsv1alpha1.Exporter{ + Exporter: appsv1.Exporter{ ContainerName: "metrics", ScrapePath: "/metrics", ScrapePort: "8080", @@ -74,7 +74,7 @@ func TestFromContainerPort(t *testing.T) { name: "empty port test", args: args{ exporter: Exporter{ - Exporter: appsv1alpha1.Exporter{ + Exporter: appsv1.Exporter{ ContainerName: "metrics", ScrapePath: "/metrics", }, diff --git a/pkg/common/types.go b/pkg/common/types.go index 9e28095dcb6..9b717fa6c2b 100644 --- a/pkg/common/types.go +++ b/pkg/common/types.go @@ -22,7 +22,7 @@ package common import ( "k8s.io/apimachinery/pkg/util/intstr" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" ) // PodRoleNamePair defines a pod name and role name pair. @@ -47,6 +47,6 @@ type GlobalRoleSnapshot struct { // Exporter defines the built-in metrics exporter. type Exporter struct { - appsv1alpha1.Exporter `json:",inline"` - TargetPort *intstr.IntOrString `json:"targetPort,omitempty"` + appsv1.Exporter `json:",inline"` + TargetPort *intstr.IntOrString `json:"targetPort,omitempty"` } diff --git a/pkg/configuration/config_manager/builder.go b/pkg/configuration/config_manager/builder.go index 96cdb074734..6ee738d1f19 100644 --- a/pkg/configuration/config_manager/builder.go +++ b/pkg/configuration/config_manager/builder.go @@ -37,6 +37,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" appsv1beta1 "github.com/apecloud/kubeblocks/apis/apps/v1beta1" "github.com/apecloud/kubeblocks/pkg/configuration/core" @@ -333,7 +334,7 @@ func buildReloadScriptVolume(scriptCMName string, manager *CfgManagerBuildParams }) } -func buildLazyRenderedConfigVolume(cmName string, manager *CfgManagerBuildParams, mountPoint, volumeName string, configSpec appsv1alpha1.ComponentConfigSpec) { +func buildLazyRenderedConfigVolume(cmName string, manager *CfgManagerBuildParams, mountPoint, volumeName string, configSpec appsv1.ComponentConfigSpec) { n := len(manager.Volumes) manager.Volumes = append(manager.Volumes, corev1.VolumeMount{ Name: volumeName, @@ -436,7 +437,7 @@ func checkAndUpdateReloadYaml(data map[string]string, reloadConfig string, forma return data, nil } -func buildCfgManagerScripts(options appsv1beta1.ScriptConfig, manager *CfgManagerBuildParams, cli client.Client, ctx context.Context, configSpec appsv1alpha1.ComponentConfigSpec) error { +func buildCfgManagerScripts(options appsv1beta1.ScriptConfig, manager *CfgManagerBuildParams, cli client.Client, ctx context.Context, configSpec appsv1.ComponentConfigSpec) error { mountPoint := filepath.Join(KBScriptVolumePath, configSpec.Name) referenceCMKey := client.ObjectKey{ Namespace: options.Namespace, @@ -453,19 +454,19 @@ func buildCfgManagerScripts(options appsv1beta1.ScriptConfig, manager *CfgManage return nil } -func GetConfigMountPoint(configSpec appsv1alpha1.ComponentConfigSpec) string { +func GetConfigMountPoint(configSpec appsv1.ComponentConfigSpec) string { return filepath.Join(KBConfigVolumePath, configSpec.Name) } -func GetScriptsMountPoint(configSpec appsv1alpha1.ComponentConfigSpec) string { +func GetScriptsMountPoint(configSpec appsv1.ComponentConfigSpec) string { return filepath.Join(KBScriptVolumePath, configSpec.Name) } -func GetScriptsVolumeName(configSpec appsv1alpha1.ComponentConfigSpec) string { +func GetScriptsVolumeName(configSpec appsv1.ComponentConfigSpec) string { return fmt.Sprintf("%s%s", scriptVolumePrefix, configSpec.Name) } -func GetConfigVolumeName(configSpec appsv1alpha1.ComponentConfigSpec) string { +func GetConfigVolumeName(configSpec appsv1.ComponentConfigSpec) string { return fmt.Sprintf("%s%s", configVolumePrefix, configSpec.Name) } diff --git a/pkg/configuration/config_manager/builder_test.go b/pkg/configuration/config_manager/builder_test.go index b365b45f2ba..b1e4d24a1fc 100644 --- a/pkg/configuration/config_manager/builder_test.go +++ b/pkg/configuration/config_manager/builder_test.go @@ -33,6 +33,7 @@ import ( "k8s.io/apimachinery/pkg/util/yaml" "sigs.k8s.io/controller-runtime/pkg/client" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" appsv1beta1 "github.com/apecloud/kubeblocks/apis/apps/v1beta1" testutil "github.com/apecloud/kubeblocks/pkg/testutil/k8s" @@ -118,8 +119,8 @@ var _ = Describe("Config Builder Test", func() { return []ConfigSpecMeta{ { ConfigSpecInfo: ConfigSpecInfo{ - ConfigSpec: appsv1alpha1.ComponentConfigSpec{ - ComponentTemplateSpec: appsv1alpha1.ComponentTemplateSpec{ + ConfigSpec: appsv1.ComponentConfigSpec{ + ComponentTemplateSpec: appsv1.ComponentTemplateSpec{ Name: "pg_config", VolumeName: "pg_config", }, @@ -277,8 +278,8 @@ formatterConfig: buildParam := ¶m.ConfigSpecsBuildParams[i] buildParam.ReloadAction = reloadOptions buildParam.ReloadType = appsv1beta1.TPLScriptType - buildParam.ConfigSpec.LegacyRenderedConfigSpec = &appsv1alpha1.LegacyRenderedTemplateSpec{ - ConfigTemplateExtension: appsv1alpha1.ConfigTemplateExtension{ + buildParam.ConfigSpec.LegacyRenderedConfigSpec = &appsv1.LegacyRenderedTemplateSpec{ + ConfigTemplateExtension: appsv1.ConfigTemplateExtension{ Namespace: scriptsNS, TemplateRef: lazyRenderedTemplateName, }, diff --git a/pkg/configuration/config_manager/handler_util.go b/pkg/configuration/config_manager/handler_util.go index ac7d6e882e4..b396bb0e44d 100644 --- a/pkg/configuration/config_manager/handler_util.go +++ b/pkg/configuration/config_manager/handler_util.go @@ -28,6 +28,7 @@ import ( corev1 "k8s.io/api/core/v1" "sigs.k8s.io/controller-runtime/pkg/client" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" appsv1beta1 "github.com/apecloud/kubeblocks/apis/apps/v1beta1" "github.com/apecloud/kubeblocks/pkg/configuration/core" @@ -155,7 +156,7 @@ func CreateValidConfigMapFilter() NotifyEventFilter { } } -func GetSupportReloadConfigSpecs(configSpecs []appsv1alpha1.ComponentConfigSpec, cli client.Client, ctx context.Context) ([]ConfigSpecMeta, error) { +func GetSupportReloadConfigSpecs(configSpecs []appsv1.ComponentConfigSpec, cli client.Client, ctx context.Context) ([]ConfigSpecMeta, error) { var reloadConfigSpecMeta []ConfigSpecMeta for _, configSpec := range configSpecs { // pass if support change and reload ConfigMap when parameters change diff --git a/pkg/configuration/config_manager/handler_util_test.go b/pkg/configuration/config_manager/handler_util_test.go index 0882a8b5b1c..2df019fea98 100644 --- a/pkg/configuration/config_manager/handler_util_test.go +++ b/pkg/configuration/config_manager/handler_util_test.go @@ -21,6 +21,7 @@ package configmanager import ( "context" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" "strings" "testing" @@ -32,7 +33,6 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/client" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" appsv1beta1 "github.com/apecloud/kubeblocks/apis/apps/v1beta1" cfgcore "github.com/apecloud/kubeblocks/pkg/configuration/core" cfgutil "github.com/apecloud/kubeblocks/pkg/configuration/util" @@ -147,9 +147,9 @@ var _ = Describe("Handler Util Test", func() { }} } - mockConfigSpec := func(ccName string) appsv1alpha1.ComponentConfigSpec { - return appsv1alpha1.ComponentConfigSpec{ - ComponentTemplateSpec: appsv1alpha1.ComponentTemplateSpec{ + mockConfigSpec := func(ccName string) appsv1.ComponentConfigSpec { + return appsv1.ComponentConfigSpec{ + ComponentTemplateSpec: appsv1.ComponentTemplateSpec{ Name: "test", TemplateRef: "config_template", Namespace: "default", @@ -264,8 +264,8 @@ var _ = Describe("Handler Util Test", func() { Context("TestGetSupportReloadConfigSpecs", func() { It("not support reload", func() { - configSpecs, err := GetSupportReloadConfigSpecs([]appsv1alpha1.ComponentConfigSpec{{ - ComponentTemplateSpec: appsv1alpha1.ComponentTemplateSpec{ + configSpecs, err := GetSupportReloadConfigSpecs([]appsv1.ComponentConfigSpec{{ + ComponentTemplateSpec: appsv1.ComponentTemplateSpec{ Name: "test", }}}, nil, nil) Expect(err).Should(Succeed()) @@ -273,8 +273,8 @@ var _ = Describe("Handler Util Test", func() { }) It("not ConfigConstraint ", func() { - configSpecs, err := GetSupportReloadConfigSpecs([]appsv1alpha1.ComponentConfigSpec{{ - ComponentTemplateSpec: appsv1alpha1.ComponentTemplateSpec{ + configSpecs, err := GetSupportReloadConfigSpecs([]appsv1.ComponentConfigSpec{{ + ComponentTemplateSpec: appsv1.ComponentTemplateSpec{ Name: "test", TemplateRef: "config_template", Namespace: "default", @@ -290,7 +290,7 @@ var _ = Describe("Handler Util Test", func() { }), testutil.WithTimes(1))) configSpecs, err := GetSupportReloadConfigSpecs( - []appsv1alpha1.ComponentConfigSpec{mockConfigSpec(ccName)}, + []appsv1.ComponentConfigSpec{mockConfigSpec(ccName)}, mockK8sCli.Client(), ctx) Expect(err).Should(Succeed()) @@ -310,7 +310,7 @@ var _ = Describe("Handler Util Test", func() { testutil.WithTimes(1))) configSpecs, err := GetSupportReloadConfigSpecs( - []appsv1alpha1.ComponentConfigSpec{mockConfigSpec(ccName)}, + []appsv1.ComponentConfigSpec{mockConfigSpec(ccName)}, mockK8sCli.Client(), ctx) Expect(err).Should(Succeed()) @@ -332,7 +332,7 @@ var _ = Describe("Handler Util Test", func() { testutil.WithTimes(1))) configSpecs, err := GetSupportReloadConfigSpecs( - []appsv1alpha1.ComponentConfigSpec{mockConfigSpec(ccName)}, + []appsv1.ComponentConfigSpec{mockConfigSpec(ccName)}, mockK8sCli.Client(), ctx) Expect(err).Should(Succeed()) @@ -449,8 +449,8 @@ func TestFilterSubPathVolumeMount(t *testing.T) { return ConfigSpecMeta{ConfigSpecInfo: ConfigSpecInfo{ ReloadAction: reloadAction, ReloadType: reloadType, - ConfigSpec: appsv1alpha1.ComponentConfigSpec{ - ComponentTemplateSpec: appsv1alpha1.ComponentTemplateSpec{ + ConfigSpec: appsv1.ComponentConfigSpec{ + ComponentTemplateSpec: appsv1.ComponentTemplateSpec{ VolumeName: volumeName, }}}} } diff --git a/pkg/configuration/config_manager/type.go b/pkg/configuration/config_manager/type.go index fbf877c059c..7ef426b01b6 100644 --- a/pkg/configuration/config_manager/type.go +++ b/pkg/configuration/config_manager/type.go @@ -24,7 +24,7 @@ import ( "github.com/fsnotify/fsnotify" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1beta1 "github.com/apecloud/kubeblocks/apis/apps/v1beta1" ) @@ -37,9 +37,9 @@ type ConfigHandler interface { type ConfigSpecInfo struct { *appsv1beta1.ReloadAction `json:",inline"` - ReloadType appsv1beta1.DynamicReloadType `json:"reloadType"` - ConfigSpec appsv1alpha1.ComponentConfigSpec `json:"configSpec"` - FormatterConfig appsv1beta1.FileFormatConfig `json:"formatterConfig"` + ReloadType appsv1beta1.DynamicReloadType `json:"reloadType"` + ConfigSpec appsv1.ComponentConfigSpec `json:"configSpec"` + FormatterConfig appsv1beta1.FileFormatConfig `json:"formatterConfig"` DownwardAPIOptions []appsv1beta1.DownwardAPIChangeTriggeredAction `json:"downwardAPIOptions"` @@ -65,7 +65,7 @@ type TPLScriptConfig struct { } type ConfigLazyRenderedMeta struct { - *appsv1alpha1.ComponentConfigSpec `json:",inline"` + *appsv1.ComponentConfigSpec `json:",inline"` // secondary template path Templates []string `json:"templates"` diff --git a/pkg/configuration/core/config_util.go b/pkg/configuration/core/config_util.go index 21f1e09fedf..54cc6dfceac 100644 --- a/pkg/configuration/core/config_util.go +++ b/pkg/configuration/core/config_util.go @@ -28,7 +28,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/log" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1beta1 "github.com/apecloud/kubeblocks/apis/apps/v1beta1" cfgutil "github.com/apecloud/kubeblocks/pkg/configuration/util" ) @@ -117,12 +117,12 @@ func ApplyConfigPatch(baseCfg []byte, updatedParameters map[string]*string, form return mergedConfig.Marshal() } -func NeedReloadVolume(config appsv1alpha1.ComponentConfigSpec) bool { +func NeedReloadVolume(config appsv1.ComponentConfigSpec) bool { // TODO distinguish between scripts and configuration return config.ConfigConstraintRef != "" } -func GetReloadOptions(cli client.Client, ctx context.Context, configSpecs []appsv1alpha1.ComponentConfigSpec) (*appsv1beta1.ReloadAction, *appsv1beta1.FileFormatConfig, error) { +func GetReloadOptions(cli client.Client, ctx context.Context, configSpecs []appsv1.ComponentConfigSpec) (*appsv1beta1.ReloadAction, *appsv1beta1.FileFormatConfig, error) { for _, configSpec := range configSpecs { if !NeedReloadVolume(configSpec) { continue diff --git a/pkg/configuration/core/config_util_test.go b/pkg/configuration/core/config_util_test.go index 792f1d359e4..dc5674bec33 100644 --- a/pkg/configuration/core/config_util_test.go +++ b/pkg/configuration/core/config_util_test.go @@ -29,7 +29,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" - "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1beta1 "github.com/apecloud/kubeblocks/apis/apps/v1beta1" cfgutil "github.com/apecloud/kubeblocks/pkg/configuration/util" testutil "github.com/apecloud/kubeblocks/pkg/testutil/k8s" @@ -63,7 +63,7 @@ var _ = Describe("config_util", func() { } tests := []struct { name string - tpls []v1alpha1.ComponentConfigSpec + tpls []appsv1.ComponentConfigSpec want *appsv1beta1.ReloadAction wantErr bool }{{ @@ -75,18 +75,18 @@ var _ = Describe("config_util", func() { }, { // empty config templates name: "test", - tpls: []v1alpha1.ComponentConfigSpec{}, + tpls: []appsv1.ComponentConfigSpec{}, want: nil, wantErr: false, }, { // config templates without configConstraintObj name: "test", - tpls: []v1alpha1.ComponentConfigSpec{{ - ComponentTemplateSpec: v1alpha1.ComponentTemplateSpec{ + tpls: []appsv1.ComponentConfigSpec{{ + ComponentTemplateSpec: appsv1.ComponentTemplateSpec{ Name: "for_test", }, }, { - ComponentTemplateSpec: v1alpha1.ComponentTemplateSpec{ + ComponentTemplateSpec: appsv1.ComponentTemplateSpec{ Name: "for_test2", }, }}, @@ -95,8 +95,8 @@ var _ = Describe("config_util", func() { }, { // normal name: "test", - tpls: []v1alpha1.ComponentConfigSpec{{ - ComponentTemplateSpec: v1alpha1.ComponentTemplateSpec{ + tpls: []appsv1.ComponentConfigSpec{{ + ComponentTemplateSpec: appsv1.ComponentTemplateSpec{ Name: "for_test", }, ConfigConstraintRef: "eg_v1", @@ -106,8 +106,8 @@ var _ = Describe("config_util", func() { }, { // not exist config constraint name: "test", - tpls: []v1alpha1.ComponentConfigSpec{{ - ComponentTemplateSpec: v1alpha1.ComponentTemplateSpec{ + tpls: []appsv1.ComponentConfigSpec{{ + ComponentTemplateSpec: appsv1.ComponentTemplateSpec{ Name: "for_test", }, ConfigConstraintRef: "not_exist", diff --git a/pkg/configuration/core/type.go b/pkg/configuration/core/type.go index 468e6f6b4fd..795923b9216 100644 --- a/pkg/configuration/core/type.go +++ b/pkg/configuration/core/type.go @@ -27,7 +27,7 @@ import ( "github.com/go-logr/logr" "sigs.k8s.io/controller-runtime/pkg/client" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1beta1 "github.com/apecloud/kubeblocks/apis/apps/v1beta1" "github.com/apecloud/kubeblocks/pkg/constant" ) @@ -163,7 +163,7 @@ func GenerateConstraintsUniqLabelKeyWithConfig(configKey string) string { return GenerateUniqKeyWithConfig(constant.ConfigurationConstraintsLabelPrefixKey, configKey) } -func GetInstanceCMName(obj client.Object, tpl *appsv1alpha1.ComponentTemplateSpec) string { +func GetInstanceCMName(obj client.Object, tpl *appsv1.ComponentTemplateSpec) string { return getInstanceCfgCMName(obj.GetName(), tpl.Name) } diff --git a/pkg/configuration/core/type_test.go b/pkg/configuration/core/type_test.go index a9204e84acf..9f6e91a6b1f 100644 --- a/pkg/configuration/core/type_test.go +++ b/pkg/configuration/core/type_test.go @@ -25,6 +25,7 @@ import ( "github.com/stretchr/testify/require" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" ) @@ -39,7 +40,7 @@ func TestGetInstanceName(t *testing.T) { ObjectMeta: metav1.ObjectMeta{ Name: "mycluster", }}, - &appsv1alpha1.ComponentTemplateSpec{ + &appsv1.ComponentTemplateSpec{ Name: "mysql-config", TemplateRef: "mysql-template-config", })) diff --git a/pkg/controller/builder/builder_component.go b/pkg/controller/builder/builder_component.go index a4be30cc111..8db54ff76e6 100644 --- a/pkg/controller/builder/builder_component.go +++ b/pkg/controller/builder/builder_component.go @@ -20,22 +20,22 @@ along with this program. If not, see . package builder import ( + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/util/intstr" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" - workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" ) type ComponentBuilder struct { - BaseBuilder[appsv1alpha1.Component, *appsv1alpha1.Component, ComponentBuilder] + BaseBuilder[appsv1.Component, *appsv1.Component, ComponentBuilder] } func NewComponentBuilder(namespace, name, compDef string) *ComponentBuilder { builder := &ComponentBuilder{} builder.init(namespace, name, - &appsv1alpha1.Component{ - Spec: appsv1alpha1.ComponentSpec{ + &appsv1.Component{ + Spec: appsv1.ComponentSpec{ CompDef: compDef, }, }, builder) @@ -62,7 +62,7 @@ func (builder *ComponentBuilder) SetEnv(env []corev1.EnvVar) *ComponentBuilder { return builder } -func (builder *ComponentBuilder) SetSchedulingPolicy(schedulingPolicy *appsv1alpha1.SchedulingPolicy) *ComponentBuilder { +func (builder *ComponentBuilder) SetSchedulingPolicy(schedulingPolicy *appsv1.SchedulingPolicy) *ComponentBuilder { builder.get().Spec.SchedulingPolicy = schedulingPolicy return builder } @@ -72,7 +72,7 @@ func (builder *ComponentBuilder) SetReplicas(replicas int32) *ComponentBuilder { return builder } -func (builder *ComponentBuilder) SetConfigs(configs []appsv1alpha1.ClusterComponentConfig) *ComponentBuilder { +func (builder *ComponentBuilder) SetConfigs(configs []appsv1.ClusterComponentConfig) *ComponentBuilder { builder.get().Spec.Configs = configs return builder } @@ -87,7 +87,7 @@ func (builder *ComponentBuilder) SetParallelPodManagementConcurrency(parallelPod return builder } -func (builder *ComponentBuilder) SetPodUpdatePolicy(policy *workloads.PodUpdatePolicyType) *ComponentBuilder { +func (builder *ComponentBuilder) SetPodUpdatePolicy(policy *appsv1.PodUpdatePolicyType) *ComponentBuilder { builder.get().Spec.PodUpdatePolicy = policy return builder } @@ -107,9 +107,9 @@ func (builder *ComponentBuilder) SetEnabledLogs(logNames []string) *ComponentBui return builder } -func (builder *ComponentBuilder) SetTLSConfig(enable bool, issuer *appsv1alpha1.Issuer) *ComponentBuilder { +func (builder *ComponentBuilder) SetTLSConfig(enable bool, issuer *appsv1.Issuer) *ComponentBuilder { if enable { - builder.get().Spec.TLSConfig = &appsv1alpha1.TLSConfig{ + builder.get().Spec.TLSConfig = &appsv1.TLSConfig{ Enable: enable, Issuer: issuer, } @@ -117,16 +117,15 @@ func (builder *ComponentBuilder) SetTLSConfig(enable bool, issuer *appsv1alpha1. return builder } -func (builder *ComponentBuilder) AddVolumeClaimTemplate(volumeName string, - pvcSpec appsv1alpha1.PersistentVolumeClaimSpec) *ComponentBuilder { - builder.get().Spec.VolumeClaimTemplates = append(builder.get().Spec.VolumeClaimTemplates, appsv1alpha1.ClusterComponentVolumeClaimTemplate{ +func (builder *ComponentBuilder) AddVolumeClaimTemplate(volumeName string, pvcSpec appsv1.PersistentVolumeClaimSpec) *ComponentBuilder { + builder.get().Spec.VolumeClaimTemplates = append(builder.get().Spec.VolumeClaimTemplates, appsv1.ClusterComponentVolumeClaimTemplate{ Name: volumeName, Spec: pvcSpec, }) return builder } -func (builder *ComponentBuilder) SetVolumeClaimTemplates(volumeClaimTemplates []appsv1alpha1.ClusterComponentVolumeClaimTemplate) *ComponentBuilder { +func (builder *ComponentBuilder) SetVolumeClaimTemplates(volumeClaimTemplates []appsv1.ClusterComponentVolumeClaimTemplate) *ComponentBuilder { builder.get().Spec.VolumeClaimTemplates = volumeClaimTemplates return builder } @@ -137,9 +136,9 @@ func (builder *ComponentBuilder) SetVolumes(volumes []corev1.Volume) *ComponentB } func (builder *ComponentBuilder) SetServices(services []appsv1alpha1.ClusterComponentService) *ComponentBuilder { - toCompService := func(svc appsv1alpha1.ClusterComponentService) appsv1alpha1.ComponentService { - return appsv1alpha1.ComponentService{ - Service: appsv1alpha1.Service{ + toCompService := func(svc appsv1alpha1.ClusterComponentService) appsv1.ComponentService { + return appsv1.ComponentService{ + Service: appsv1.Service{ Name: svc.Name, Annotations: svc.Annotations, Spec: corev1.ServiceSpec{ @@ -155,17 +154,17 @@ func (builder *ComponentBuilder) SetServices(services []appsv1alpha1.ClusterComp return builder } -func (builder *ComponentBuilder) SetSystemAccounts(systemAccounts []appsv1alpha1.ComponentSystemAccount) *ComponentBuilder { +func (builder *ComponentBuilder) SetSystemAccounts(systemAccounts []appsv1.ComponentSystemAccount) *ComponentBuilder { builder.get().Spec.SystemAccounts = systemAccounts return builder } -func (builder *ComponentBuilder) SetServiceRefs(serviceRefs []appsv1alpha1.ServiceRef) *ComponentBuilder { +func (builder *ComponentBuilder) SetServiceRefs(serviceRefs []appsv1.ServiceRef) *ComponentBuilder { builder.get().Spec.ServiceRefs = serviceRefs return builder } -func (builder *ComponentBuilder) SetInstances(instances []appsv1alpha1.InstanceTemplate) *ComponentBuilder { +func (builder *ComponentBuilder) SetInstances(instances []appsv1.InstanceTemplate) *ComponentBuilder { builder.get().Spec.Instances = instances return builder } diff --git a/pkg/controller/builder/builder_component_definition.go b/pkg/controller/builder/builder_component_definition.go index 6596910ea6c..92497251145 100644 --- a/pkg/controller/builder/builder_component_definition.go +++ b/pkg/controller/builder/builder_component_definition.go @@ -26,18 +26,18 @@ import ( corev1 "k8s.io/api/core/v1" rbacv1 "k8s.io/api/rbac/v1" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" ) type ComponentDefinitionBuilder struct { - BaseBuilder[appsv1alpha1.ComponentDefinition, *appsv1alpha1.ComponentDefinition, ComponentDefinitionBuilder] + BaseBuilder[appsv1.ComponentDefinition, *appsv1.ComponentDefinition, ComponentDefinitionBuilder] } func NewComponentDefinitionBuilder(name string) *ComponentDefinitionBuilder { builder := &ComponentDefinitionBuilder{} builder.init("", name, - &appsv1alpha1.ComponentDefinition{ - Spec: appsv1alpha1.ComponentDefinitionSpec{}, + &appsv1.ComponentDefinition{ + Spec: appsv1.ComponentDefinitionSpec{}, }, builder) return builder } @@ -81,22 +81,22 @@ func (builder *ComponentDefinitionBuilder) AddVolumeMounts(containerName string, return builder } -func (builder *ComponentDefinitionBuilder) AddVar(v appsv1alpha1.EnvVar) *ComponentDefinitionBuilder { +func (builder *ComponentDefinitionBuilder) AddVar(v appsv1.EnvVar) *ComponentDefinitionBuilder { if builder.get().Spec.Vars == nil { - builder.get().Spec.Vars = make([]appsv1alpha1.EnvVar, 0) + builder.get().Spec.Vars = make([]appsv1.EnvVar, 0) } builder.get().Spec.Vars = append(builder.get().Spec.Vars, v) return builder } func (builder *ComponentDefinitionBuilder) AddVolume(name string, snapshot bool, watermark int) *ComponentDefinitionBuilder { - vol := appsv1alpha1.ComponentVolume{ + vol := appsv1.ComponentVolume{ Name: name, NeedSnapshot: snapshot, HighWatermark: watermark, } if builder.get().Spec.Volumes == nil { - builder.get().Spec.Volumes = make([]appsv1alpha1.ComponentVolume, 0) + builder.get().Spec.Volumes = make([]appsv1.ComponentVolume, 0) } builder.get().Spec.Volumes = append(builder.get().Spec.Volumes, vol) return builder @@ -112,8 +112,8 @@ func (builder *ComponentDefinitionBuilder) AddService(name, serviceName string, } func (builder *ComponentDefinitionBuilder) AddServiceExt(name, serviceName string, serviceSpec corev1.ServiceSpec, roleSelector string) *ComponentDefinitionBuilder { - svc := appsv1alpha1.ComponentService{ - Service: appsv1alpha1.Service{ + svc := appsv1.ComponentService{ + Service: appsv1.Service{ Name: name, ServiceName: serviceName, Spec: serviceSpec, @@ -121,7 +121,7 @@ func (builder *ComponentDefinitionBuilder) AddServiceExt(name, serviceName strin }, } if builder.get().Spec.Services == nil { - builder.get().Spec.Services = make([]appsv1alpha1.ComponentService, 0) + builder.get().Spec.Services = make([]appsv1.ComponentService, 0) } builder.get().Spec.Services = append(builder.get().Spec.Services, svc) return builder @@ -129,8 +129,8 @@ func (builder *ComponentDefinitionBuilder) AddServiceExt(name, serviceName strin func (builder *ComponentDefinitionBuilder) AddConfigTemplate(name, configTemplateRef, configConstraintRef, namespace, volumeName string, injectEnvTo ...string) *ComponentDefinitionBuilder { - config := appsv1alpha1.ComponentConfigSpec{ - ComponentTemplateSpec: appsv1alpha1.ComponentTemplateSpec{ + config := appsv1.ComponentConfigSpec{ + ComponentTemplateSpec: appsv1.ComponentTemplateSpec{ Name: name, TemplateRef: configTemplateRef, Namespace: namespace, @@ -140,38 +140,27 @@ func (builder *ComponentDefinitionBuilder) AddConfigTemplate(name, configTemplat InjectEnvTo: injectEnvTo, } if builder.get().Spec.Configs == nil { - builder.get().Spec.Configs = make([]appsv1alpha1.ComponentConfigSpec, 0) + builder.get().Spec.Configs = make([]appsv1.ComponentConfigSpec, 0) } builder.get().Spec.Configs = append(builder.get().Spec.Configs, config) return builder } func (builder *ComponentDefinitionBuilder) AddLogConfig(name, filePathPattern string) *ComponentDefinitionBuilder { - logConfig := appsv1alpha1.LogConfig{ + logConfig := appsv1.LogConfig{ FilePathPattern: filePathPattern, Name: name, } if builder.get().Spec.LogConfigs == nil { - builder.get().Spec.LogConfigs = make([]appsv1alpha1.LogConfig, 0) + builder.get().Spec.LogConfigs = make([]appsv1.LogConfig, 0) } builder.get().Spec.LogConfigs = append(builder.get().Spec.LogConfigs, logConfig) return builder } -// func (builder *ComponentDefinitionBuilder) SetMonitor(builtIn bool, scrapePort intstr.IntOrString, scrapePath string) *ComponentDefinitionBuilder { -// builder.get().Spec.Monitor = &appsv1alpha1.MonitorConfig{ -// BuiltIn: builtIn, -// Exporter: &appsv1alpha1.ExporterConfig{ -// ScrapePort: scrapePort, -// ScrapePath: scrapePath, -// }, -// } -// return builder -// } - func (builder *ComponentDefinitionBuilder) AddScriptTemplate(name, configTemplateRef, namespace, volumeName string, mode *int32) *ComponentDefinitionBuilder { - script := appsv1alpha1.ComponentTemplateSpec{ + script := appsv1.ComponentTemplateSpec{ Name: name, TemplateRef: configTemplateRef, Namespace: namespace, @@ -179,7 +168,7 @@ func (builder *ComponentDefinitionBuilder) AddScriptTemplate(name, configTemplat DefaultMode: mode, } if builder.get().Spec.Scripts == nil { - builder.get().Spec.Scripts = make([]appsv1alpha1.ComponentTemplateSpec, 0) + builder.get().Spec.Scripts = make([]appsv1.ComponentTemplateSpec, 0) } builder.get().Spec.Scripts = append(builder.get().Spec.Scripts, script) return builder @@ -196,7 +185,7 @@ func (builder *ComponentDefinitionBuilder) SetLabels(labels map[string]string) * } func (builder *ComponentDefinitionBuilder) SetReplicasLimit(minReplicas, maxReplicas int32) *ComponentDefinitionBuilder { - builder.get().Spec.ReplicasLimit = &appsv1alpha1.ReplicasLimit{ + builder.get().Spec.ReplicasLimit = &appsv1.ReplicasLimit{ MinReplicas: minReplicas, MaxReplicas: maxReplicas, } @@ -204,31 +193,31 @@ func (builder *ComponentDefinitionBuilder) SetReplicasLimit(minReplicas, maxRepl } func (builder *ComponentDefinitionBuilder) AddSystemAccount(accountName string, initAccount bool, statement string) *ComponentDefinitionBuilder { - account := appsv1alpha1.SystemAccount{ + account := appsv1.SystemAccount{ Name: accountName, InitAccount: initAccount, Statement: statement, } if builder.get().Spec.SystemAccounts == nil { - builder.get().Spec.SystemAccounts = make([]appsv1alpha1.SystemAccount, 0) + builder.get().Spec.SystemAccounts = make([]appsv1.SystemAccount, 0) } builder.get().Spec.SystemAccounts = append(builder.get().Spec.SystemAccounts, account) return builder } -func (builder *ComponentDefinitionBuilder) SetUpdateStrategy(strategy *appsv1alpha1.UpdateStrategy) *ComponentDefinitionBuilder { +func (builder *ComponentDefinitionBuilder) SetUpdateStrategy(strategy *appsv1.UpdateStrategy) *ComponentDefinitionBuilder { builder.get().Spec.UpdateStrategy = strategy return builder } func (builder *ComponentDefinitionBuilder) AddRole(name string, serviceable, writable bool) *ComponentDefinitionBuilder { - role := appsv1alpha1.ReplicaRole{ + role := appsv1.ReplicaRole{ Name: name, Serviceable: serviceable, Writable: writable, } if builder.get().Spec.Roles == nil { - builder.get().Spec.Roles = make([]appsv1alpha1.ReplicaRole, 0) + builder.get().Spec.Roles = make([]appsv1.ReplicaRole, 0) } builder.get().Spec.Roles = append(builder.get().Spec.Roles, role) return builder diff --git a/pkg/controller/builder/builder_configuration.go b/pkg/controller/builder/builder_configuration.go index 66c4c3ec521..5dbcf5d3840 100644 --- a/pkg/controller/builder/builder_configuration.go +++ b/pkg/controller/builder/builder_configuration.go @@ -20,16 +20,17 @@ along with this program. If not, see . package builder import ( - "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" + appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" ) type ConfigurationBuilder struct { - BaseBuilder[v1alpha1.Configuration, *v1alpha1.Configuration, ConfigurationBuilder] + BaseBuilder[appsv1alpha1.Configuration, *appsv1alpha1.Configuration, ConfigurationBuilder] } func NewConfigurationBuilder(namespace, name string) *ConfigurationBuilder { builder := &ConfigurationBuilder{} - builder.init(namespace, name, &v1alpha1.Configuration{}, builder) + builder.init(namespace, name, &appsv1alpha1.Configuration{}, builder) return builder } @@ -43,11 +44,75 @@ func (c *ConfigurationBuilder) Component(component string) *ConfigurationBuilder return c } -func (c *ConfigurationBuilder) AddConfigurationItem(configSpec v1alpha1.ComponentConfigSpec) *ConfigurationBuilder { +func (c *ConfigurationBuilder) AddConfigurationItem(configSpec appsv1.ComponentConfigSpec) *ConfigurationBuilder { c.get().Spec.ConfigItemDetails = append(c.get().Spec.ConfigItemDetails, - v1alpha1.ConfigurationItemDetail{ + appsv1alpha1.ConfigurationItemDetail{ Name: configSpec.Name, - ConfigSpec: configSpec.DeepCopy(), + ConfigSpec: ToV1alpha1ConfigSpec(configSpec.DeepCopy()), }) return c } + +func ToV1ConfigSpec(spec *appsv1alpha1.ComponentConfigSpec) *appsv1.ComponentConfigSpec { + v1 := &appsv1.ComponentConfigSpec{ + ComponentTemplateSpec: appsv1.ComponentTemplateSpec{ + Name: spec.Name, + TemplateRef: spec.TemplateRef, + Namespace: spec.Namespace, + VolumeName: spec.VolumeName, + DefaultMode: spec.DefaultMode, + }, + Keys: spec.Keys, + ConfigConstraintRef: spec.ConfigConstraintRef, + AsEnvFrom: spec.AsEnvFrom, + InjectEnvTo: spec.InjectEnvTo, + } + if spec.LegacyRenderedConfigSpec != nil { + v1.LegacyRenderedConfigSpec = &appsv1.LegacyRenderedTemplateSpec{ + ConfigTemplateExtension: appsv1.ConfigTemplateExtension{ + TemplateRef: spec.LegacyRenderedConfigSpec.TemplateRef, + Namespace: spec.LegacyRenderedConfigSpec.Namespace, + Policy: appsv1.MergedPolicy(spec.LegacyRenderedConfigSpec.Policy), + }, + } + } + if spec.ReRenderResourceTypes != nil { + v1.ReRenderResourceTypes = make([]appsv1.RerenderResourceType, 0) + for _, r := range spec.ReRenderResourceTypes { + v1.ReRenderResourceTypes = append(v1.ReRenderResourceTypes, appsv1.RerenderResourceType(r)) + } + } + return v1 +} + +func ToV1alpha1ConfigSpec(spec *appsv1.ComponentConfigSpec) *appsv1alpha1.ComponentConfigSpec { + v1 := &appsv1alpha1.ComponentConfigSpec{ + ComponentTemplateSpec: appsv1alpha1.ComponentTemplateSpec{ + Name: spec.Name, + TemplateRef: spec.TemplateRef, + Namespace: spec.Namespace, + VolumeName: spec.VolumeName, + DefaultMode: spec.DefaultMode, + }, + Keys: spec.Keys, + ConfigConstraintRef: spec.ConfigConstraintRef, + AsEnvFrom: spec.AsEnvFrom, + InjectEnvTo: spec.InjectEnvTo, + } + if spec.LegacyRenderedConfigSpec != nil { + v1.LegacyRenderedConfigSpec = &appsv1alpha1.LegacyRenderedTemplateSpec{ + ConfigTemplateExtension: appsv1alpha1.ConfigTemplateExtension{ + TemplateRef: spec.LegacyRenderedConfigSpec.TemplateRef, + Namespace: spec.LegacyRenderedConfigSpec.Namespace, + Policy: appsv1alpha1.MergedPolicy(spec.LegacyRenderedConfigSpec.Policy), + }, + } + } + if spec.ReRenderResourceTypes != nil { + v1.ReRenderResourceTypes = make([]appsv1alpha1.RerenderResourceType, 0) + for _, r := range spec.ReRenderResourceTypes { + v1.ReRenderResourceTypes = append(v1.ReRenderResourceTypes, appsv1alpha1.RerenderResourceType(r)) + } + } + return v1 +} diff --git a/pkg/controller/builder/builder_monitor_service_test.go b/pkg/controller/builder/builder_monitor_service_test.go index de40bb52167..eecf097588d 100644 --- a/pkg/controller/builder/builder_monitor_service_test.go +++ b/pkg/controller/builder/builder_monitor_service_test.go @@ -19,9 +19,10 @@ package builder import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" + monitoringv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" "github.com/apecloud/kubeblocks/pkg/common" ) @@ -32,10 +33,10 @@ var _ = Describe("monitor_service builder", func() { ns = "default" ) - exporter := appsv1alpha1.Exporter{ + exporter := appsv1.Exporter{ ScrapePath: "metrics", ScrapePort: "http-metrics", - ScrapeScheme: appsv1alpha1.HTTPSProtocol, + ScrapeScheme: appsv1.HTTPSProtocol, } ncs := NewMonitorServiceBuilder(ns, name). diff --git a/pkg/controller/component/component.go b/pkg/controller/component/component.go index 49474c03979..6965cc9d44d 100644 --- a/pkg/controller/component/component.go +++ b/pkg/controller/component/component.go @@ -29,6 +29,7 @@ import ( "k8s.io/apimachinery/pkg/util/sets" "sigs.k8s.io/controller-runtime/pkg/client" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" "github.com/apecloud/kubeblocks/pkg/common" "github.com/apecloud/kubeblocks/pkg/constant" @@ -49,22 +50,22 @@ func ShortName(clusterName, compName string) (string, error) { return name, nil } -func GetClusterName(comp *appsv1alpha1.Component) (string, error) { +func GetClusterName(comp *appsv1.Component) (string, error) { return getCompLabelValue(comp, constant.AppInstanceLabelKey) } -func GetClusterUID(comp *appsv1alpha1.Component) (string, error) { +func GetClusterUID(comp *appsv1.Component) (string, error) { return getCompLabelValue(comp, constant.KBAppClusterUIDLabelKey) } // IsGenerated checks if the component is generated from legacy cluster definitions. -func IsGenerated(comp *appsv1alpha1.Component) bool { +func IsGenerated(comp *appsv1.Component) bool { return len(comp.Spec.CompDef) == 0 } // BuildComponent builds a new Component object from cluster component spec and definition. func BuildComponent(cluster *appsv1alpha1.Cluster, compSpec *appsv1alpha1.ClusterComponentSpec, - labels, annotations map[string]string) (*appsv1alpha1.Component, error) { + labels, annotations map[string]string) (*appsv1.Component, error) { compName := FullName(cluster.Name, compSpec.Name) compDefName := func() string { if strings.HasPrefix(compSpec.ComponentDef, constant.KBGeneratedVirtualCompDefPrefix) { @@ -121,14 +122,13 @@ func BuildComponent(cluster *appsv1alpha1.Cluster, compSpec *appsv1alpha1.Cluste } func getOrBuildComponentDefinition(ctx context.Context, cli client.Reader, - clusterDef *appsv1alpha1.ClusterDefinition, cluster *appsv1alpha1.Cluster, - clusterCompSpec *appsv1alpha1.ClusterComponentSpec) (*appsv1alpha1.ComponentDefinition, error) { + clusterCompSpec *appsv1alpha1.ClusterComponentSpec) (*appsv1.ComponentDefinition, error) { if len(cluster.Spec.ClusterDefRef) > 0 && len(clusterCompSpec.ComponentDefRef) > 0 && len(clusterCompSpec.ComponentDef) == 0 { return nil, fmt.Errorf("legacy cluster component definition is not supported any more") } if len(clusterCompSpec.ComponentDef) > 0 { - compDef := &appsv1alpha1.ComponentDefinition{} + compDef := &appsv1.ComponentDefinition{} if err := cli.Get(ctx, types.NamespacedName{Name: clusterCompSpec.ComponentDef}, compDef); err != nil { return nil, err } @@ -137,30 +137,7 @@ func getOrBuildComponentDefinition(ctx context.Context, cli client.Reader, return nil, fmt.Errorf("the component definition is not provided") } -func getClusterReferencedResources(ctx context.Context, cli client.Reader, - cluster *appsv1alpha1.Cluster) (*appsv1alpha1.ClusterDefinition, error) { - var ( - clusterDef *appsv1alpha1.ClusterDefinition - ) - if len(cluster.Spec.ClusterDefRef) > 0 { - clusterDef = &appsv1alpha1.ClusterDefinition{} - if err := cli.Get(ctx, types.NamespacedName{Name: cluster.Spec.ClusterDefRef}, clusterDef); err != nil { - return nil, err - } - } - if clusterDef == nil { - if len(cluster.Spec.ClusterDefRef) == 0 { - return nil, fmt.Errorf("cluster definition is needed for generated component") - } else { - return nil, fmt.Errorf("referenced cluster definition is not found: %s", cluster.Spec.ClusterDefRef) - } - } - return clusterDef, nil -} - -func getClusterCompSpec4Component(ctx context.Context, cli client.Reader, - clusterDef *appsv1alpha1.ClusterDefinition, cluster *appsv1alpha1.Cluster, - comp *appsv1alpha1.Component) (*appsv1alpha1.ClusterComponentSpec, error) { +func getClusterCompSpec4Component(ctx context.Context, cli client.Reader, cluster *appsv1alpha1.Cluster, comp *appsv1.Component) (*appsv1alpha1.ClusterComponentSpec, error) { compName, err := ShortName(cluster.Name, comp.Name) if err != nil { return nil, err @@ -175,7 +152,7 @@ func getClusterCompSpec4Component(ctx context.Context, cli client.Reader, return nil, fmt.Errorf("cluster component spec is not found for component: %s", comp.Name) } -func getCompLabelValue(comp *appsv1alpha1.Component, label string) (string, error) { +func getCompLabelValue(comp *appsv1.Component, label string) (string, error) { if comp.Labels == nil { return "", fmt.Errorf("required label %s is not provided, component: %s", label, comp.GetName()) } @@ -187,23 +164,23 @@ func getCompLabelValue(comp *appsv1alpha1.Component, label string) (string, erro } // GetCompDefByName gets the component definition by component definition name. -func GetCompDefByName(ctx context.Context, cli client.Reader, compDefName string) (*appsv1alpha1.ComponentDefinition, error) { - compDef := &appsv1alpha1.ComponentDefinition{} +func GetCompDefByName(ctx context.Context, cli client.Reader, compDefName string) (*appsv1.ComponentDefinition, error) { + compDef := &appsv1.ComponentDefinition{} if err := cli.Get(ctx, client.ObjectKey{Name: compDefName}, compDef); err != nil { return nil, err } return compDef, nil } -func GetComponentByName(ctx context.Context, cli client.Reader, namespace, fullCompName string) (*appsv1alpha1.Component, error) { - comp := &appsv1alpha1.Component{} +func GetComponentByName(ctx context.Context, cli client.Reader, namespace, fullCompName string) (*appsv1.Component, error) { + comp := &appsv1.Component{} if err := cli.Get(ctx, client.ObjectKey{Name: fullCompName, Namespace: namespace}, comp); err != nil { return nil, err } return comp, nil } -func GetCompNCompDefByName(ctx context.Context, cli client.Reader, namespace, fullCompName string) (*appsv1alpha1.Component, *appsv1alpha1.ComponentDefinition, error) { +func GetCompNCompDefByName(ctx context.Context, cli client.Reader, namespace, fullCompName string) (*appsv1.Component, *appsv1.ComponentDefinition, error) { comp, err := GetComponentByName(ctx, cli, namespace, fullCompName) if err != nil { return nil, nil, err @@ -216,8 +193,8 @@ func GetCompNCompDefByName(ctx context.Context, cli client.Reader, namespace, fu } // ListClusterComponents lists the components of the cluster. -func ListClusterComponents(ctx context.Context, cli client.Reader, cluster *appsv1alpha1.Cluster) ([]appsv1alpha1.Component, error) { - compList := &appsv1alpha1.ComponentList{} +func ListClusterComponents(ctx context.Context, cli client.Reader, cluster *appsv1alpha1.Cluster) ([]appsv1.Component, error) { + compList := &appsv1.ComponentList{} if err := cli.List(ctx, compList, client.InNamespace(cluster.Namespace), client.MatchingLabels{constant.AppInstanceLabelKey: cluster.Name}); err != nil { return nil, err } @@ -241,7 +218,7 @@ func GetClusterComponentShortNameSet(ctx context.Context, cli client.Reader, clu return compSet, nil } -func GetExporter(componentDef appsv1alpha1.ComponentDefinitionSpec) *common.Exporter { +func GetExporter(componentDef appsv1.ComponentDefinitionSpec) *common.Exporter { if componentDef.Exporter != nil { return &common.Exporter{Exporter: *componentDef.Exporter} } diff --git a/pkg/controller/component/component_test.go b/pkg/controller/component/component_test.go index 524431bd018..fbd33713681 100644 --- a/pkg/controller/component/component_test.go +++ b/pkg/controller/component/component_test.go @@ -46,7 +46,7 @@ var _ = Describe("Component", func() { ) var ( - compDef *appsv1alpha1.ComponentDefinition + compDef *appsv1.ComponentDefinition cluster *appsv1alpha1.Cluster ) @@ -61,7 +61,7 @@ var _ = Describe("Component", func() { }) - compObj := func() *appsv1alpha1.Component { + compObj := func() *appsv1.Component { comp, err := BuildComponent(cluster, &cluster.Spec.ComponentSpecs[0], nil, nil) Expect(err).Should(Succeed()) return comp @@ -207,7 +207,7 @@ func TestGetConfigSpecByName(t *testing.T) { tests := []struct { name string args args - want *appsv1alpha1.ComponentConfigSpec + want *appsv1.ComponentConfigSpec }{{ name: "test", args: args{ @@ -219,8 +219,8 @@ func TestGetConfigSpecByName(t *testing.T) { name: "test", args: args{ component: &SynthesizedComponent{ - ConfigTemplates: []appsv1alpha1.ComponentConfigSpec{{ - ComponentTemplateSpec: appsv1alpha1.ComponentTemplateSpec{ + ConfigTemplates: []appsv1.ComponentConfigSpec{{ + ComponentTemplateSpec: appsv1.ComponentTemplateSpec{ Name: "test", }}}, }, @@ -231,15 +231,15 @@ func TestGetConfigSpecByName(t *testing.T) { name: "test", args: args{ component: &SynthesizedComponent{ - ConfigTemplates: []appsv1alpha1.ComponentConfigSpec{{ - ComponentTemplateSpec: appsv1alpha1.ComponentTemplateSpec{ + ConfigTemplates: []appsv1.ComponentConfigSpec{{ + ComponentTemplateSpec: appsv1.ComponentTemplateSpec{ Name: "for-test", }}}, }, configSpec: "for-test", }, - want: &appsv1alpha1.ComponentConfigSpec{ - ComponentTemplateSpec: appsv1alpha1.ComponentTemplateSpec{ + want: &appsv1.ComponentConfigSpec{ + ComponentTemplateSpec: appsv1.ComponentTemplateSpec{ Name: "for-test", }}, }} diff --git a/pkg/controller/component/component_version.go b/pkg/controller/component/component_version.go index 5f527700235..3782881ffaa 100644 --- a/pkg/controller/component/component_version.go +++ b/pkg/controller/component/component_version.go @@ -30,11 +30,10 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" ) // CompatibleCompVersions4Definition returns all component versions that are compatible with specified component definition. -func CompatibleCompVersions4Definition(ctx context.Context, cli client.Reader, compDef *appsv1alpha1.ComponentDefinition) ([]*appsv1.ComponentVersion, error) { +func CompatibleCompVersions4Definition(ctx context.Context, cli client.Reader, compDef *appsv1.ComponentDefinition) ([]*appsv1.ComponentVersion, error) { compVersionList := &appsv1.ComponentVersionList{} labels := client.MatchingLabels{ compDef.Name: compDef.Name, @@ -87,7 +86,7 @@ func CompareServiceVersion(required, provided string) (bool, error) { // UpdateCompDefinitionImages4ServiceVersion resolves and updates images for the component definition. func UpdateCompDefinitionImages4ServiceVersion(ctx context.Context, cli client.Reader, - compDef *appsv1alpha1.ComponentDefinition, serviceVersion string) error { + compDef *appsv1.ComponentDefinition, serviceVersion string) error { compVersions, err := CompatibleCompVersions4Definition(ctx, cli, compDef) if err != nil { return err @@ -98,7 +97,7 @@ func UpdateCompDefinitionImages4ServiceVersion(ctx context.Context, cli client.R return resolveImagesWithCompVersions(compDef, compVersions, serviceVersion) } -func resolveImagesWithCompVersions(compDef *appsv1alpha1.ComponentDefinition, +func resolveImagesWithCompVersions(compDef *appsv1.ComponentDefinition, compVersions []*appsv1.ComponentVersion, serviceVersion string) error { appsInDef := covertImagesFromCompDefinition(compDef) appsByUser, err := findMatchedImagesFromCompVersions(compVersions, serviceVersion) @@ -135,7 +134,7 @@ func resolveImagesWithCompVersions(compDef *appsv1alpha1.ComponentDefinition, return nil } -func covertImagesFromCompDefinition(compDef *appsv1alpha1.ComponentDefinition) map[string]appNameVersionImage { +func covertImagesFromCompDefinition(compDef *appsv1.ComponentDefinition) map[string]appNameVersionImage { apps := make(map[string]appNameVersionImage) checkNAdd := func(c *corev1.Container) { if len(c.Image) > 0 { diff --git a/pkg/controller/component/its_convertor.go b/pkg/controller/component/its_convertor.go index 2363f902f1f..2cc9fb9e5d5 100644 --- a/pkg/controller/component/its_convertor.go +++ b/pkg/controller/component/its_convertor.go @@ -27,9 +27,10 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/intstr" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" + kbappsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" "github.com/apecloud/kubeblocks/pkg/constant" + viper "github.com/apecloud/kubeblocks/pkg/viperx" ) // BuildWorkloadFrom builds a new Component object based on SynthesizedComponent. @@ -181,7 +182,7 @@ func (c *itsOfflineInstancesConvertor) convert(args ...any) (any, error) { return offlineInstances, nil } -func AppsInstanceToWorkloadInstance(instance *appsv1alpha1.InstanceTemplate) *workloads.InstanceTemplate { +func AppsInstanceToWorkloadInstance(instance *kbappsv1.InstanceTemplate) *workloads.InstanceTemplate { if instance == nil { return nil } @@ -212,14 +213,28 @@ func AppsInstanceToWorkloadInstance(instance *appsv1alpha1.InstanceTemplate) *wo } } -func toPersistentVolumeClaims(vcts []appsv1alpha1.ClusterComponentVolumeClaimTemplate) []corev1.PersistentVolumeClaim { +func toPersistentVolumeClaims(vcts []kbappsv1.ClusterComponentVolumeClaimTemplate) []corev1.PersistentVolumeClaim { + storageClassName := func(spec kbappsv1.PersistentVolumeClaimSpec, defaultStorageClass string) *string { + if spec.StorageClassName != nil && *spec.StorageClassName != "" { + return spec.StorageClassName + } + if defaultStorageClass != "" { + return &defaultStorageClass + } + return nil + } var pvcs []corev1.PersistentVolumeClaim for _, v := range vcts { pvcs = append(pvcs, corev1.PersistentVolumeClaim{ ObjectMeta: metav1.ObjectMeta{ Name: v.Name, }, - Spec: v.Spec.ToV1PersistentVolumeClaimSpec(), + Spec: corev1.PersistentVolumeClaimSpec{ + AccessModes: v.Spec.AccessModes, + Resources: v.Spec.Resources, + StorageClassName: storageClassName(v.Spec, viper.GetString(constant.CfgKeyDefaultStorageClass)), + VolumeMode: v.Spec.VolumeMode, + }, }) } return pvcs @@ -244,11 +259,11 @@ func getMemberUpdateStrategy(synthesizedComp *SynthesizedComponent) *workloads.M bestEffortParallelUpdate = workloads.BestEffortParallelUpdateStrategy ) switch *synthesizedComp.UpdateStrategy { - case appsv1alpha1.SerialStrategy: + case kbappsv1.SerialStrategy: return &serial - case appsv1alpha1.ParallelStrategy: + case kbappsv1.ParallelStrategy: return ¶llelUpdate - case appsv1alpha1.BestEffortParallelStrategy: + case kbappsv1.BestEffortParallelStrategy: return &bestEffortParallelUpdate default: return nil @@ -287,7 +302,7 @@ func (c *itsCredentialConvertor) convert(args ...any) (any, error) { return nil, err } - credential := func(sysAccount appsv1alpha1.SystemAccount) *workloads.Credential { + credential := func(sysAccount kbappsv1.SystemAccount) *workloads.Credential { secretName := constant.GenerateAccountSecretName(synthesizeComp.ClusterName, synthesizeComp.Name, sysAccount.Name) return &workloads.Credential{ Username: workloads.CredentialVar{ @@ -333,7 +348,7 @@ func ConvertSynthesizeCompRoleToInstanceSetRole(synthesizedComp *SynthesizedComp return nil } - accessMode := func(role appsv1alpha1.ReplicaRole) workloads.AccessMode { + accessMode := func(role kbappsv1.ReplicaRole) workloads.AccessMode { switch { case role.Serviceable && role.Writable: return workloads.ReadWriteMode diff --git a/pkg/controller/component/kbagent.go b/pkg/controller/component/kbagent.go index 303b04c5f6f..90d2c3d95ff 100644 --- a/pkg/controller/component/kbagent.go +++ b/pkg/controller/component/kbagent.go @@ -28,7 +28,7 @@ import ( "k8s.io/apimachinery/pkg/util/intstr" "k8s.io/apimachinery/pkg/util/sets" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" "github.com/apecloud/kubeblocks/pkg/constant" "github.com/apecloud/kubeblocks/pkg/controller/builder" intctrlutil "github.com/apecloud/kubeblocks/pkg/controllerutil" @@ -129,11 +129,11 @@ func buildKBAgentContainer(synthesizedComp *SynthesizedComponent) error { // set kb-agent container ports to host network if synthesizedComp.HostNetwork != nil { if synthesizedComp.HostNetwork.ContainerPorts == nil { - synthesizedComp.HostNetwork.ContainerPorts = make([]appsv1alpha1.HostNetworkContainerPort, 0) + synthesizedComp.HostNetwork.ContainerPorts = make([]appsv1.HostNetworkContainerPort, 0) } synthesizedComp.HostNetwork.ContainerPorts = append( synthesizedComp.HostNetwork.ContainerPorts, - appsv1alpha1.HostNetworkContainerPort{ + appsv1.HostNetworkContainerPort{ Container: container.Name, Ports: []string{kbagent.DefaultPortName}, }) @@ -147,7 +147,7 @@ func mergedActionEnv4KBAgent(synthesizedComp *SynthesizedComponent) []corev1.Env env := make([]corev1.EnvVar, 0) envSet := sets.New[string]() - checkedAppend := func(action *appsv1alpha1.Action) { + checkedAppend := func(action *appsv1.Action) { if action != nil && action.Exec != nil { for _, e := range action.Exec.Env { if !envSet.Has(e.Name) { @@ -158,7 +158,7 @@ func mergedActionEnv4KBAgent(synthesizedComp *SynthesizedComponent) []corev1.Env } } - for _, action := range []*appsv1alpha1.Action{ + for _, action := range []*appsv1.Action{ synthesizedComp.LifecycleActions.PostProvision, synthesizedComp.LifecycleActions.PreTerminate, synthesizedComp.LifecycleActions.Switchover, @@ -228,7 +228,7 @@ func buildKBAgentStartupEnvs(synthesizedComp *SynthesizedComponent) ([]corev1.En return kbagent.BuildStartupEnv(actions, probes) } -func buildAction4KBAgent(action *appsv1alpha1.Action, name string) *proto.Action { +func buildAction4KBAgent(action *appsv1.Action, name string) *proto.Action { if action == nil || action.Exec == nil { return nil } @@ -249,7 +249,7 @@ func buildAction4KBAgent(action *appsv1alpha1.Action, name string) *proto.Action return a } -func buildProbe4KBAgent(probe *appsv1alpha1.Probe, name string) (*proto.Action, *proto.Probe) { +func buildProbe4KBAgent(probe *appsv1.Probe, name string) (*proto.Action, *proto.Probe) { if probe == nil || probe.Exec == nil { return nil, nil } @@ -295,7 +295,7 @@ func customExecActionImageNContainer(synthesizedComp *SynthesizedComponent) (str return "", nil, nil } - actions := []*appsv1alpha1.Action{ + actions := []*appsv1.Action{ synthesizedComp.LifecycleActions.PostProvision, synthesizedComp.LifecycleActions.PreTerminate, synthesizedComp.LifecycleActions.Switchover, diff --git a/pkg/controller/component/kbagent_test.go b/pkg/controller/component/kbagent_test.go index 4a6c98fb41f..94cc6a3b2ed 100644 --- a/pkg/controller/component/kbagent_test.go +++ b/pkg/controller/component/kbagent_test.go @@ -29,7 +29,7 @@ import ( corev1 "k8s.io/api/core/v1" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" kbagent "github.com/apecloud/kubeblocks/pkg/kbagent" ) @@ -83,21 +83,21 @@ var _ = Describe("kb-agent", func() { }, }, }, - LifecycleActions: &appsv1alpha1.ComponentLifecycleActions{ - PostProvision: &appsv1alpha1.Action{ - Exec: &appsv1alpha1.ExecAction{ + LifecycleActions: &appsv1.ComponentLifecycleActions{ + PostProvision: &appsv1.Action{ + Exec: &appsv1.ExecAction{ Command: []string{"echo", "hello"}, }, TimeoutSeconds: 5, - RetryPolicy: &appsv1alpha1.RetryPolicy{ + RetryPolicy: &appsv1.RetryPolicy{ MaxRetries: 5, RetryInterval: 10, }, - PreCondition: &[]appsv1alpha1.PreConditionType{appsv1alpha1.ComponentReadyPreConditionType}[0], + PreCondition: &[]appsv1.PreConditionType{appsv1.ComponentReadyPreConditionType}[0], }, - RoleProbe: &appsv1alpha1.Probe{ - Action: appsv1alpha1.Action{ - Exec: &appsv1alpha1.ExecAction{ + RoleProbe: &appsv1.Probe{ + Action: appsv1.Action{ + Exec: &appsv1.ExecAction{ Command: []string{"echo", "hello"}, }, TimeoutSeconds: 5, diff --git a/pkg/controller/component/lifecycle/kbagent.go b/pkg/controller/component/lifecycle/kbagent.go index b237b049c00..5603fbb94f0 100644 --- a/pkg/controller/component/lifecycle/kbagent.go +++ b/pkg/controller/component/lifecycle/kbagent.go @@ -29,6 +29,7 @@ import ( "k8s.io/apimachinery/pkg/types" "sigs.k8s.io/controller-runtime/pkg/client" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" "github.com/apecloud/kubeblocks/pkg/constant" @@ -131,7 +132,7 @@ func (a *kbagent) ignoreOutput(_ []byte, err error) error { return err } -func (a *kbagent) checkedCallAction(ctx context.Context, cli client.Reader, spec *appsv1alpha1.Action, lfa lifecycleAction, opts *Options) ([]byte, error) { +func (a *kbagent) checkedCallAction(ctx context.Context, cli client.Reader, spec *appsv1.Action, lfa lifecycleAction, opts *Options) ([]byte, error) { if spec == nil || spec.Exec == nil { return nil, errors.Wrap(ErrActionNotDefined, lfa.name()) } @@ -142,25 +143,25 @@ func (a *kbagent) checkedCallAction(ctx context.Context, cli client.Reader, spec return a.callAction(ctx, cli, spec, lfa, opts) } -func (a *kbagent) checkedCallProbe(ctx context.Context, cli client.Reader, spec *appsv1alpha1.Probe, lfa lifecycleAction, opts *Options) ([]byte, error) { +func (a *kbagent) checkedCallProbe(ctx context.Context, cli client.Reader, spec *appsv1.Probe, lfa lifecycleAction, opts *Options) ([]byte, error) { if spec == nil || spec.Exec == nil { return nil, errors.Wrap(ErrActionNotDefined, lfa.name()) } return a.checkedCallAction(ctx, cli, &spec.Action, lfa, opts) } -func (a *kbagent) precondition(ctx context.Context, cli client.Reader, spec *appsv1alpha1.Action) error { +func (a *kbagent) precondition(ctx context.Context, cli client.Reader, spec *appsv1.Action) error { if spec.PreCondition == nil { return nil } switch *spec.PreCondition { - case appsv1alpha1.ImmediatelyPreConditionType: + case appsv1.ImmediatelyPreConditionType: return nil - case appsv1alpha1.RuntimeReadyPreConditionType: + case appsv1.RuntimeReadyPreConditionType: return a.runtimeReadyCheck(ctx, cli) - case appsv1alpha1.ComponentReadyPreConditionType: + case appsv1.ComponentReadyPreConditionType: return a.compReadyCheck(ctx, cli) - case appsv1alpha1.ClusterReadyPreConditionType: + case appsv1.ClusterReadyPreConditionType: return a.clusterReadyCheck(ctx, cli) default: return fmt.Errorf("unknown precondition type %s", *spec.PreCondition) @@ -177,11 +178,11 @@ func (a *kbagent) clusterReadyCheck(ctx context.Context, cli client.Reader) erro func (a *kbagent) compReadyCheck(ctx context.Context, cli client.Reader) error { ready := func(object client.Object) bool { - comp := object.(*appsv1alpha1.Component) - return comp.Status.Phase == appsv1alpha1.RunningClusterCompPhase + comp := object.(*appsv1.Component) + return comp.Status.Phase == appsv1.RunningClusterCompPhase } compName := constant.GenerateClusterComponentName(a.synthesizedComp.ClusterName, a.synthesizedComp.Name) - return a.readyCheck(ctx, cli, compName, "component", &appsv1alpha1.Component{}, ready) + return a.readyCheck(ctx, cli, compName, "component", &appsv1.Component{}, ready) } func (a *kbagent) runtimeReadyCheck(ctx context.Context, cli client.Reader) error { @@ -207,7 +208,7 @@ func (a *kbagent) readyCheck(ctx context.Context, cli client.Reader, name, kind return nil } -func (a *kbagent) callAction(ctx context.Context, cli client.Reader, spec *appsv1alpha1.Action, lfa lifecycleAction, opts *Options) ([]byte, error) { +func (a *kbagent) callAction(ctx context.Context, cli client.Reader, spec *appsv1.Action, lfa lifecycleAction, opts *Options) ([]byte, error) { req, err1 := a.buildActionRequest(ctx, cli, lfa, opts) if err1 != nil { return nil, err1 @@ -268,7 +269,7 @@ func (a *kbagent) templateVarsParameters() (map[string]string, error) { return m, nil } -func (a *kbagent) callActionWithSelector(ctx context.Context, spec *appsv1alpha1.Action, lfa lifecycleAction, req *proto.ActionRequest) ([]byte, error) { +func (a *kbagent) callActionWithSelector(ctx context.Context, spec *appsv1.Action, lfa lifecycleAction, req *proto.ActionRequest) ([]byte, error) { pods, err := a.selectTargetPods(spec) if err != nil { return nil, err @@ -308,7 +309,7 @@ func (a *kbagent) callActionWithSelector(ctx context.Context, spec *appsv1alpha1 return output, nil } -func (a *kbagent) selectTargetPods(spec *appsv1alpha1.Action) ([]*corev1.Pod, error) { +func (a *kbagent) selectTargetPods(spec *appsv1.Action) ([]*corev1.Pod, error) { if spec.Exec == nil || len(spec.Exec.TargetPodSelector) == 0 { return []*corev1.Pod{a.pod}, nil } @@ -336,13 +337,13 @@ func (a *kbagent) selectTargetPods(spec *appsv1alpha1.Action) ([]*corev1.Pod, er } switch spec.Exec.TargetPodSelector { - case appsv1alpha1.AnyReplica: + case appsv1.AnyReplica: return anyPod(), nil - case appsv1alpha1.AllReplicas: + case appsv1.AllReplicas: return allPods(), nil - case appsv1alpha1.RoleSelector: + case appsv1.RoleSelector: return podsWithRole(), nil - case appsv1alpha1.OrdinalSelector: + case appsv1.OrdinalSelector: return nil, fmt.Errorf("ordinal selector is not supported") default: return nil, fmt.Errorf("unknown pod selector: %s", spec.Exec.TargetPodSelector) diff --git a/pkg/controller/component/lifecycle/lfa_component.go b/pkg/controller/component/lifecycle/lfa_component.go index 8a7600e974c..ccdbaf73f95 100644 --- a/pkg/controller/component/lifecycle/lfa_component.go +++ b/pkg/controller/component/lifecycle/lfa_component.go @@ -25,7 +25,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" "github.com/apecloud/kubeblocks/pkg/constant" "github.com/apecloud/kubeblocks/pkg/controller/component" "github.com/apecloud/kubeblocks/pkg/controller/model" @@ -39,7 +39,7 @@ type postProvision struct { namespace string clusterName string compName string - action *appsv1alpha1.Action + action *appsv1.Action } var _ lifecycleAction = &postProvision{} @@ -56,7 +56,7 @@ type preTerminate struct { namespace string clusterName string compName string - action *appsv1alpha1.Action + action *appsv1.Action } var _ lifecycleAction = &preTerminate{} @@ -116,7 +116,7 @@ func hackParameters4Comp(ctx context.Context, cli client.Reader, namespace, clus scalingInComp = "KB_CLUSTER_COMPONENT_IS_SCALING_IN" ) - compList := &appsv1alpha1.ComponentList{} + compList := &appsv1.ComponentList{} if err := cli.List(ctx, compList, client.InNamespace(namespace), client.MatchingLabels{constant.AppInstanceLabelKey: clusterName}); err != nil { return nil, err } diff --git a/pkg/controller/component/lifecycle/lfa_member.go b/pkg/controller/component/lifecycle/lfa_member.go index 20d9d913258..185380ac4fb 100644 --- a/pkg/controller/component/lifecycle/lfa_member.go +++ b/pkg/controller/component/lifecycle/lfa_member.go @@ -26,6 +26,7 @@ import ( corev1 "k8s.io/api/core/v1" "sigs.k8s.io/controller-runtime/pkg/client" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" "github.com/apecloud/kubeblocks/pkg/constant" "github.com/apecloud/kubeblocks/pkg/controller/component" @@ -56,7 +57,7 @@ type switchover struct { namespace string clusterName string compName string - roles []appsv1alpha1.ReplicaRole + roles []appsv1.ReplicaRole candidate string } diff --git a/pkg/controller/component/lifecycle/lifecycle.go b/pkg/controller/component/lifecycle/lifecycle.go index 4a49e8d7fdb..bc8e6c39369 100644 --- a/pkg/controller/component/lifecycle/lifecycle.go +++ b/pkg/controller/component/lifecycle/lifecycle.go @@ -26,14 +26,14 @@ import ( corev1 "k8s.io/api/core/v1" "sigs.k8s.io/controller-runtime/pkg/client" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" "github.com/apecloud/kubeblocks/pkg/controller/component" ) type Options struct { NonBlocking *bool TimeoutSeconds *int32 - RetryPolicy *appsv1alpha1.RetryPolicy + RetryPolicy *appsv1.RetryPolicy } type Lifecycle interface { diff --git a/pkg/controller/component/lifecycle/lifecycle_test.go b/pkg/controller/component/lifecycle/lifecycle_test.go index 02cd5b228a7..5b9e74142e4 100644 --- a/pkg/controller/component/lifecycle/lifecycle_test.go +++ b/pkg/controller/component/lifecycle/lifecycle_test.go @@ -23,6 +23,7 @@ import ( "context" "errors" "fmt" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" "reflect" "strings" @@ -120,20 +121,20 @@ var _ = Describe("lifecycle", func() { }, }, }, - LifecycleActions: &appsv1alpha1.ComponentLifecycleActions{ - PostProvision: &appsv1alpha1.Action{ - Exec: &appsv1alpha1.ExecAction{ + LifecycleActions: &appsv1.ComponentLifecycleActions{ + PostProvision: &appsv1.Action{ + Exec: &appsv1.ExecAction{ Command: []string{"/bin/bash", "-c", "echo -n post-provision"}, }, TimeoutSeconds: 5, - RetryPolicy: &appsv1alpha1.RetryPolicy{ + RetryPolicy: &appsv1.RetryPolicy{ MaxRetries: 5, RetryInterval: 10, }, }, - RoleProbe: &appsv1alpha1.Probe{ - Action: appsv1alpha1.Action{ - Exec: &appsv1alpha1.ExecAction{ + RoleProbe: &appsv1.Probe{ + Action: appsv1.Action{ + Exec: &appsv1.ExecAction{ Command: []string{"/bin/bash", "-c", "echo -n role-probe"}, }, TimeoutSeconds: 5, @@ -422,7 +423,7 @@ var _ = Describe("lifecycle", func() { }) It("precondition", func() { - clusterReady := appsv1alpha1.ClusterReadyPreConditionType + clusterReady := appsv1.ClusterReadyPreConditionType synthesizedComp.LifecycleActions.PostProvision.PreCondition = &clusterReady lifecycle, err := New(synthesizedComp, nil, pods...) @@ -455,7 +456,7 @@ var _ = Describe("lifecycle", func() { }) It("precondition - fail", func() { - clusterReady := appsv1alpha1.ClusterReadyPreConditionType + clusterReady := appsv1.ClusterReadyPreConditionType synthesizedComp.LifecycleActions.PostProvision.PreCondition = &clusterReady lifecycle, err := New(synthesizedComp, nil, pods...) @@ -483,7 +484,7 @@ var _ = Describe("lifecycle", func() { }) It("pod selector - any", func() { - synthesizedComp.LifecycleActions.PostProvision.Exec.TargetPodSelector = appsv1alpha1.AnyReplica + synthesizedComp.LifecycleActions.PostProvision.Exec.TargetPodSelector = appsv1.AnyReplica pods = []*corev1.Pod{ { ObjectMeta: metav1.ObjectMeta{ @@ -537,7 +538,7 @@ var _ = Describe("lifecycle", func() { }) It("pod selector - role", func() { - synthesizedComp.LifecycleActions.PostProvision.Exec.TargetPodSelector = appsv1alpha1.RoleSelector + synthesizedComp.LifecycleActions.PostProvision.Exec.TargetPodSelector = appsv1.RoleSelector synthesizedComp.LifecycleActions.PostProvision.Exec.MatchingKey = "leader" pods = []*corev1.Pod{ { @@ -594,7 +595,7 @@ var _ = Describe("lifecycle", func() { }) It("pod selector - has no matched", func() { - synthesizedComp.LifecycleActions.PostProvision.Exec.TargetPodSelector = appsv1alpha1.RoleSelector + synthesizedComp.LifecycleActions.PostProvision.Exec.TargetPodSelector = appsv1.RoleSelector synthesizedComp.LifecycleActions.PostProvision.Exec.MatchingKey = "leader" pods = []*corev1.Pod{ { diff --git a/pkg/controller/component/service_descriptor_utils.go b/pkg/controller/component/service_descriptor_utils.go index dcd59b7c258..86c6b58956d 100644 --- a/pkg/controller/component/service_descriptor_utils.go +++ b/pkg/controller/component/service_descriptor_utils.go @@ -31,13 +31,12 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" "github.com/apecloud/kubeblocks/pkg/constant" "github.com/apecloud/kubeblocks/pkg/controller/builder" ) func buildServiceReferences(ctx context.Context, cli client.Reader, - synthesizedComp *SynthesizedComponent, compDef *appsv1alpha1.ComponentDefinition, comp *appsv1alpha1.Component) error { + synthesizedComp *SynthesizedComponent, compDef *appsv1.ComponentDefinition, comp *appsv1.Component) error { if err := buildServiceReferencesWithoutResolve(ctx, cli, synthesizedComp, compDef, comp); err != nil { return err } @@ -45,12 +44,12 @@ func buildServiceReferences(ctx context.Context, cli client.Reader, } func buildServiceReferencesWithoutResolve(ctx context.Context, cli client.Reader, - synthesizedComp *SynthesizedComponent, compDef *appsv1alpha1.ComponentDefinition, comp *appsv1alpha1.Component) error { + synthesizedComp *SynthesizedComponent, compDef *appsv1.ComponentDefinition, comp *appsv1.Component) error { if compDef == nil || comp == nil || len(compDef.Spec.ServiceRefDeclarations) == 0 { return nil } - serviceRefs := map[string]*appsv1alpha1.ServiceRef{} + serviceRefs := map[string]*appsv1.ServiceRef{} for i, serviceRef := range comp.Spec.ServiceRefs { serviceRefs[serviceRef.Name] = &comp.Spec.ServiceRefs[i] } @@ -91,7 +90,7 @@ func buildServiceReferencesWithoutResolve(ctx context.Context, cli client.Reader } func handleServiceRefFromCluster(ctx context.Context, cli client.Reader, namespace string, - serviceRef appsv1alpha1.ServiceRef, serviceRefDecl appsv1alpha1.ServiceRefDeclaration, legacy bool) (*appsv1.ServiceDescriptor, error) { + serviceRef appsv1.ServiceRef, serviceRefDecl appsv1.ServiceRefDeclaration, legacy bool) (*appsv1.ServiceDescriptor, error) { resolver := referencedVars if legacy { resolver = referencedVars4Legacy @@ -113,7 +112,7 @@ func handleServiceRefFromCluster(ctx context.Context, cli client.Reader, namespa return b.GetObject(), nil } -func referencedVars(ctx context.Context, cli client.Reader, namespace string, serviceRef appsv1alpha1.ServiceRef) ([]*appsv1.CredentialVar, error) { +func referencedVars(ctx context.Context, cli client.Reader, namespace string, serviceRef appsv1.ServiceRef) ([]*appsv1.CredentialVar, error) { var ( vars = []*appsv1.CredentialVar{nil, nil, nil, nil, nil} err error @@ -130,7 +129,7 @@ func referencedVars(ctx context.Context, cli client.Reader, namespace string, se } func referencedServiceVars(ctx context.Context, cli client.Reader, namespace string, - serviceRef appsv1alpha1.ServiceRef) (*appsv1.CredentialVar, *appsv1.CredentialVar, *appsv1.CredentialVar, error) { + serviceRef appsv1.ServiceRef) (*appsv1.CredentialVar, *appsv1.CredentialVar, *appsv1.CredentialVar, error) { var ( selector = serviceRef.ClusterServiceSelector host, port *appsv1.CredentialVar @@ -177,7 +176,7 @@ func referencedServiceVars(ctx context.Context, cli client.Reader, namespace str } func referencedCredentialVars(ctx context.Context, cli client.Reader, namespace string, - serviceRef appsv1alpha1.ServiceRef) (*appsv1.CredentialVar, *appsv1.CredentialVar, error) { + serviceRef appsv1.ServiceRef) (*appsv1.CredentialVar, *appsv1.CredentialVar, error) { var ( selector = serviceRef.ClusterServiceSelector vars = []*appsv1.CredentialVar{nil, nil} @@ -220,7 +219,7 @@ func referencedCredentialVars(ctx context.Context, cli client.Reader, namespace return vars[0], vars[1], nil } -func referencedVars4Legacy(ctx context.Context, cli client.Reader, namespace string, serviceRef appsv1alpha1.ServiceRef) ([]*appsv1.CredentialVar, error) { +func referencedVars4Legacy(ctx context.Context, cli client.Reader, namespace string, serviceRef appsv1.ServiceRef) ([]*appsv1.CredentialVar, error) { secret := &corev1.Secret{} secretKey := types.NamespacedName{ Namespace: func() string { @@ -265,9 +264,9 @@ func referencedVars4Legacy(ctx context.Context, cli client.Reader, namespace str // handleServiceRefFromServiceDescriptor handles the service reference is provided by external ServiceDescriptor object. func handleServiceRefFromServiceDescriptor(ctx context.Context, cli client.Reader, namespace string, - serviceRef appsv1alpha1.ServiceRef, serviceRefDecl appsv1alpha1.ServiceRefDeclaration) (*appsv1.ServiceDescriptor, error) { + serviceRef appsv1.ServiceRef, serviceRefDecl appsv1.ServiceRefDeclaration) (*appsv1.ServiceDescriptor, error) { // verify service kind and version - verifyServiceKindAndVersion := func(serviceDescriptor appsv1.ServiceDescriptor, _ ...appsv1alpha1.ServiceRefDeclarationSpec) bool { + verifyServiceKindAndVersion := func(serviceDescriptor appsv1.ServiceDescriptor, _ ...appsv1.ServiceRefDeclarationSpec) bool { for _, serviceRefDeclSpec := range serviceRefDecl.ServiceRefDeclarationSpecs { if getWellKnownServiceKindAliasMapping(serviceRefDeclSpec.ServiceKind) != getWellKnownServiceKindAliasMapping(serviceDescriptor.Spec.ServiceKind) { continue diff --git a/pkg/controller/component/service_descriptor_utils_test.go b/pkg/controller/component/service_descriptor_utils_test.go index 5da22e782bb..23194435164 100644 --- a/pkg/controller/component/service_descriptor_utils_test.go +++ b/pkg/controller/component/service_descriptor_utils_test.go @@ -30,7 +30,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/client" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" "github.com/apecloud/kubeblocks/pkg/constant" "github.com/apecloud/kubeblocks/pkg/generics" testapps "github.com/apecloud/kubeblocks/pkg/testutil/apps" @@ -145,13 +145,12 @@ var _ = Describe("build service references", func() { ) var ( - compDef *appsv1alpha1.ComponentDefinition - comp *appsv1alpha1.Component - synthesizedComp *SynthesizedComponent - - serviceRefDeclaration = appsv1alpha1.ServiceRefDeclaration{ + compDef *appsv1.ComponentDefinition + comp *appsv1.Component + synthesizedComp *SynthesizedComponent + serviceRefDeclaration = appsv1.ServiceRefDeclaration{ Name: etcd, - ServiceRefDeclarationSpecs: []appsv1alpha1.ServiceRefDeclarationSpec{ + ServiceRefDeclarationSpecs: []appsv1.ServiceRefDeclarationSpec{ { ServiceKind: etcd, ServiceVersion: etcdVersion, @@ -161,21 +160,21 @@ var _ = Describe("build service references", func() { ) BeforeEach(func() { - compDef = &appsv1alpha1.ComponentDefinition{ + compDef = &appsv1.ComponentDefinition{ ObjectMeta: metav1.ObjectMeta{ Name: "compdef", }, - Spec: appsv1alpha1.ComponentDefinitionSpec{ - ServiceRefDeclarations: []appsv1alpha1.ServiceRefDeclaration{serviceRefDeclaration}, + Spec: appsv1.ComponentDefinitionSpec{ + ServiceRefDeclarations: []appsv1.ServiceRefDeclaration{serviceRefDeclaration}, }, } - comp = &appsv1alpha1.Component{ + comp = &appsv1.Component{ ObjectMeta: metav1.ObjectMeta{ Namespace: namespace, Name: "comp", }, - Spec: appsv1alpha1.ComponentSpec{ - ServiceRefs: []appsv1alpha1.ServiceRef{}, + Spec: appsv1.ComponentSpec{ + ServiceRefs: []appsv1.ServiceRef{}, }, } synthesizedComp = &SynthesizedComponent{ @@ -203,12 +202,12 @@ var _ = Describe("build service references", func() { }) It("service vars - cluster service", func() { - comp.Spec.ServiceRefs = []appsv1alpha1.ServiceRef{ + comp.Spec.ServiceRefs = []appsv1.ServiceRef{ { Name: serviceRefDeclaration.Name, - ClusterServiceSelector: &appsv1alpha1.ServiceRefClusterSelector{ + ClusterServiceSelector: &appsv1.ServiceRefClusterSelector{ Cluster: etcdCluster, - Service: &appsv1alpha1.ServiceRefServiceSelector{ + Service: &appsv1.ServiceRefServiceSelector{ Service: "client", Port: "client", }, @@ -255,12 +254,12 @@ var _ = Describe("build service references", func() { }) It("service vars - component service", func() { - comp.Spec.ServiceRefs = []appsv1alpha1.ServiceRef{ + comp.Spec.ServiceRefs = []appsv1.ServiceRef{ { Name: serviceRefDeclaration.Name, - ClusterServiceSelector: &appsv1alpha1.ServiceRefClusterSelector{ + ClusterServiceSelector: &appsv1.ServiceRefClusterSelector{ Cluster: etcdCluster, - Service: &appsv1alpha1.ServiceRefServiceSelector{ + Service: &appsv1.ServiceRefServiceSelector{ Component: etcdComponent, Service: "", // default service Port: "peer", @@ -308,12 +307,12 @@ var _ = Describe("build service references", func() { }) It("service vars - pod service", func() { - comp.Spec.ServiceRefs = []appsv1alpha1.ServiceRef{ + comp.Spec.ServiceRefs = []appsv1.ServiceRef{ { Name: serviceRefDeclaration.Name, - ClusterServiceSelector: &appsv1alpha1.ServiceRefClusterSelector{ + ClusterServiceSelector: &appsv1.ServiceRefClusterSelector{ Cluster: etcdCluster, - Service: &appsv1alpha1.ServiceRefServiceSelector{ + Service: &appsv1.ServiceRefServiceSelector{ Component: etcdComponent, Service: "peer", Port: "peer", @@ -348,23 +347,23 @@ var _ = Describe("build service references", func() { newPodService(0), newPodService(1), newPodService(2), - &appsv1alpha1.Component{ + &appsv1.Component{ ObjectMeta: metav1.ObjectMeta{ Namespace: namespace, Name: FullName(etcdCluster, etcdComponent), }, - Spec: appsv1alpha1.ComponentSpec{ + Spec: appsv1.ComponentSpec{ CompDef: "test-compdef", }, }, - &appsv1alpha1.ComponentDefinition{ + &appsv1.ComponentDefinition{ ObjectMeta: metav1.ObjectMeta{ Name: "test-compdef", }, - Spec: appsv1alpha1.ComponentDefinitionSpec{ - Services: []appsv1alpha1.ComponentService{ + Spec: appsv1.ComponentDefinitionSpec{ + Services: []appsv1.ComponentService{ { - Service: appsv1alpha1.Service{ + Service: appsv1.Service{ Name: "peer", ServiceName: "peer", }, @@ -398,13 +397,13 @@ var _ = Describe("build service references", func() { }) It("credential vars - same namespace", func() { - comp.Spec.ServiceRefs = []appsv1alpha1.ServiceRef{ + comp.Spec.ServiceRefs = []appsv1.ServiceRef{ { Name: serviceRefDeclaration.Name, Namespace: namespace, - ClusterServiceSelector: &appsv1alpha1.ServiceRefClusterSelector{ + ClusterServiceSelector: &appsv1.ServiceRefClusterSelector{ Cluster: etcdCluster, - Credential: &appsv1alpha1.ServiceRefCredentialSelector{ + Credential: &appsv1.ServiceRefCredentialSelector{ Component: etcdComponent, Name: "default", }, @@ -451,13 +450,13 @@ var _ = Describe("build service references", func() { }) It("credential vars - different namespace", func() { - comp.Spec.ServiceRefs = []appsv1alpha1.ServiceRef{ + comp.Spec.ServiceRefs = []appsv1.ServiceRef{ { Name: serviceRefDeclaration.Name, Namespace: "external", - ClusterServiceSelector: &appsv1alpha1.ServiceRefClusterSelector{ + ClusterServiceSelector: &appsv1.ServiceRefClusterSelector{ Cluster: etcdCluster, - Credential: &appsv1alpha1.ServiceRefCredentialSelector{ + Credential: &appsv1.ServiceRefCredentialSelector{ Component: etcdComponent, Name: "default", }, diff --git a/pkg/controller/component/synthesize_component.go b/pkg/controller/component/synthesize_component.go index a067feca4be..bff94fe5956 100644 --- a/pkg/controller/component/synthesize_component.go +++ b/pkg/controller/component/synthesize_component.go @@ -31,10 +31,11 @@ import ( "k8s.io/apimachinery/pkg/util/sets" "sigs.k8s.io/controller-runtime/pkg/client" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" "github.com/apecloud/kubeblocks/pkg/constant" - "github.com/apecloud/kubeblocks/pkg/controller/scheduling" intctrlutil "github.com/apecloud/kubeblocks/pkg/controllerutil" + viper "github.com/apecloud/kubeblocks/pkg/viperx" ) var ( @@ -45,32 +46,28 @@ var ( func BuildSynthesizedComponent(reqCtx intctrlutil.RequestCtx, cli client.Reader, cluster *appsv1alpha1.Cluster, - compDef *appsv1alpha1.ComponentDefinition, - comp *appsv1alpha1.Component) (*SynthesizedComponent, error) { - return buildSynthesizedComponent(reqCtx, cli, compDef, comp, nil, cluster, nil) + compDef *appsv1.ComponentDefinition, + comp *appsv1.Component) (*SynthesizedComponent, error) { + return buildSynthesizedComponent(reqCtx, cli, compDef, comp, cluster, nil) } // BuildSynthesizedComponent4Generated builds SynthesizedComponent for generated Component which w/o ComponentDefinition. func BuildSynthesizedComponent4Generated(reqCtx intctrlutil.RequestCtx, cli client.Reader, cluster *appsv1alpha1.Cluster, - comp *appsv1alpha1.Component) (*appsv1alpha1.ComponentDefinition, *SynthesizedComponent, error) { - clusterDef, err := getClusterReferencedResources(reqCtx.Ctx, cli, cluster) - if err != nil { - return nil, nil, err - } - clusterCompSpec, err := getClusterCompSpec4Component(reqCtx.Ctx, cli, clusterDef, cluster, comp) + comp *appsv1.Component) (*appsv1.ComponentDefinition, *SynthesizedComponent, error) { + clusterCompSpec, err := getClusterCompSpec4Component(reqCtx.Ctx, cli, cluster, comp) if err != nil { return nil, nil, err } if clusterCompSpec == nil { return nil, nil, fmt.Errorf("cluster component spec is not found: %s", comp.Name) } - compDef, err := getOrBuildComponentDefinition(reqCtx.Ctx, cli, clusterDef, cluster, clusterCompSpec) + compDef, err := getOrBuildComponentDefinition(reqCtx.Ctx, cli, cluster, clusterCompSpec) if err != nil { return nil, nil, err } - synthesizedComp, err := buildSynthesizedComponent(reqCtx, cli, compDef, comp, clusterDef, cluster, clusterCompSpec) + synthesizedComp, err := buildSynthesizedComponent(reqCtx, cli, compDef, comp, cluster, clusterCompSpec) if err != nil { return nil, nil, err } @@ -86,11 +83,7 @@ func BuildSynthesizedComponentWrapper(reqCtx intctrlutil.RequestCtx, if clusterCompSpec == nil { return nil, fmt.Errorf("cluster component spec is not provided") } - clusterDef, err := getClusterReferencedResources(reqCtx.Ctx, cli, cluster) - if err != nil { - return nil, err - } - compDef, err := getOrBuildComponentDefinition(reqCtx.Ctx, cli, clusterDef, cluster, clusterCompSpec) + compDef, err := getOrBuildComponentDefinition(reqCtx.Ctx, cli, cluster, clusterCompSpec) if err != nil { return nil, err } @@ -98,7 +91,7 @@ func BuildSynthesizedComponentWrapper(reqCtx intctrlutil.RequestCtx, if err != nil { return nil, err } - return buildSynthesizedComponent(reqCtx, cli, compDef, comp, clusterDef, cluster, clusterCompSpec) + return buildSynthesizedComponent(reqCtx, cli, compDef, comp, cluster, clusterCompSpec) } // buildSynthesizedComponent builds a new SynthesizedComponent object, which is a mixture of component-related configs from ComponentDefinition and Component. @@ -106,9 +99,8 @@ func BuildSynthesizedComponentWrapper(reqCtx intctrlutil.RequestCtx, // TODO: remove @reqCtx & @cli func buildSynthesizedComponent(reqCtx intctrlutil.RequestCtx, cli client.Reader, - compDef *appsv1alpha1.ComponentDefinition, - comp *appsv1alpha1.Component, - clusterDef *appsv1alpha1.ClusterDefinition, + compDef *appsv1.ComponentDefinition, + comp *appsv1.Component, cluster *appsv1alpha1.Cluster, clusterCompSpec *appsv1alpha1.ClusterComponentSpec) (*SynthesizedComponent, error) { if compDef == nil || comp == nil { @@ -178,10 +170,7 @@ func buildSynthesizedComponent(reqCtx intctrlutil.RequestCtx, } // build scheduling policy for workload - if err = buildSchedulingPolicy(synthesizeComp, comp); err != nil { - reqCtx.Log.Error(err, "failed to build scheduling policy") - return nil, err - } + buildSchedulingPolicy(synthesizeComp, comp) // update resources buildAndUpdateResources(synthesizeComp, comp) @@ -223,7 +212,7 @@ func buildSynthesizedComponent(reqCtx intctrlutil.RequestCtx, return synthesizeComp, nil } -func clusterGeneration(cluster *appsv1alpha1.Cluster, comp *appsv1alpha1.Component) string { +func clusterGeneration(cluster *appsv1alpha1.Cluster, comp *appsv1.Component) string { if comp != nil && comp.Annotations != nil { if generation, ok := comp.Annotations[constant.KubeBlocksGenerationKey]; ok { return generation @@ -273,7 +262,7 @@ func buildComp2CompDefs(ctx context.Context, cli client.Reader, cluster *appsv1a } // buildLabelsAndAnnotations builds labels and annotations for synthesizedComponent. -func buildLabelsAndAnnotations(compDef *appsv1alpha1.ComponentDefinition, comp *appsv1alpha1.Component, synthesizeComp *SynthesizedComponent) { +func buildLabelsAndAnnotations(compDef *appsv1.ComponentDefinition, comp *appsv1.Component, synthesizeComp *SynthesizedComponent) { replaceEnvPlaceholderTokens := func(clusterName, uid, componentName string, kvMap map[string]string) map[string]string { replacedMap := make(map[string]string, len(kvMap)) builtInEnvMap := GetReplacementMapForBuiltInEnv(clusterName, uid, componentName) @@ -309,7 +298,7 @@ func buildLabelsAndAnnotations(compDef *appsv1alpha1.ComponentDefinition, comp * } } -func mergeUserDefinedEnv(synthesizedComp *SynthesizedComponent, comp *appsv1alpha1.Component) error { +func mergeUserDefinedEnv(synthesizedComp *SynthesizedComponent, comp *appsv1.Component) error { if comp == nil || len(comp.Spec.Env) == 0 { return nil } @@ -331,13 +320,13 @@ func mergeUserDefinedEnv(synthesizedComp *SynthesizedComponent, comp *appsv1alph return nil } -func mergeSystemAccounts(compDefAccounts []appsv1alpha1.SystemAccount, - compAccounts []appsv1alpha1.ComponentSystemAccount) []appsv1alpha1.SystemAccount { +func mergeSystemAccounts(compDefAccounts []appsv1.SystemAccount, + compAccounts []appsv1.ComponentSystemAccount) []appsv1.SystemAccount { if len(compAccounts) == 0 { return compDefAccounts } - override := func(compAccount appsv1alpha1.ComponentSystemAccount, idx int) { + override := func(compAccount appsv1.ComponentSystemAccount, idx int) { if compAccount.PasswordConfig != nil { compDefAccounts[idx].PasswordGenerationPolicy = *compAccount.PasswordConfig } @@ -360,35 +349,25 @@ func mergeSystemAccounts(compDefAccounts []appsv1alpha1.SystemAccount, return compDefAccounts } -func buildSchedulingPolicy(synthesizedComp *SynthesizedComponent, comp *appsv1alpha1.Component) error { - var ( - schedulingPolicy = comp.Spec.SchedulingPolicy - err error - ) - if schedulingPolicy == nil { - // for compatibility, we need to build scheduling policy from component's affinity and tolerations - schedulingPolicy, err = scheduling.BuildSchedulingPolicy4Component(synthesizedComp.ClusterName, - synthesizedComp.Name, comp.Spec.Affinity, comp.Spec.Tolerations) - if err != nil { - return err - } +func buildSchedulingPolicy(synthesizedComp *SynthesizedComponent, comp *appsv1.Component) { + if comp.Spec.SchedulingPolicy != nil { + schedulingPolicy := comp.Spec.SchedulingPolicy + synthesizedComp.PodSpec.SchedulerName = schedulingPolicy.SchedulerName + synthesizedComp.PodSpec.NodeSelector = schedulingPolicy.NodeSelector + synthesizedComp.PodSpec.NodeName = schedulingPolicy.NodeName + synthesizedComp.PodSpec.Affinity = schedulingPolicy.Affinity + synthesizedComp.PodSpec.Tolerations = schedulingPolicy.Tolerations + synthesizedComp.PodSpec.TopologySpreadConstraints = schedulingPolicy.TopologySpreadConstraints } - synthesizedComp.PodSpec.SchedulerName = schedulingPolicy.SchedulerName - synthesizedComp.PodSpec.NodeSelector = schedulingPolicy.NodeSelector - synthesizedComp.PodSpec.NodeName = schedulingPolicy.NodeName - synthesizedComp.PodSpec.Affinity = schedulingPolicy.Affinity - synthesizedComp.PodSpec.Tolerations = schedulingPolicy.Tolerations - synthesizedComp.PodSpec.TopologySpreadConstraints = schedulingPolicy.TopologySpreadConstraints - return nil } -func buildVolumeClaimTemplates(synthesizeComp *SynthesizedComponent, comp *appsv1alpha1.Component) { +func buildVolumeClaimTemplates(synthesizeComp *SynthesizedComponent, comp *appsv1.Component) { if comp.Spec.VolumeClaimTemplates != nil { synthesizeComp.VolumeClaimTemplates = toVolumeClaimTemplates(&comp.Spec) } } -func mergeUserDefinedVolumes(synthesizedComp *SynthesizedComponent, comp *appsv1alpha1.Component) error { +func mergeUserDefinedVolumes(synthesizedComp *SynthesizedComponent, comp *appsv1.Component) error { if comp == nil { return nil } @@ -408,7 +387,7 @@ func mergeUserDefinedVolumes(synthesizedComp *SynthesizedComponent, comp *appsv1 volumes[vct.Name] = true } - checkConfigNScriptTemplate := func(tpl appsv1alpha1.ComponentTemplateSpec) error { + checkConfigNScriptTemplate := func(tpl appsv1.ComponentTemplateSpec) error { if volumes[tpl.VolumeName] { return fmt.Errorf("duplicated volume %s for template %s", tpl.VolumeName, tpl.Name) } @@ -444,7 +423,7 @@ func mergeUserDefinedVolumes(synthesizedComp *SynthesizedComponent, comp *appsv1 } // limitSharedMemoryVolumeSize limits the shared memory volume size to memory requests/limits. -func limitSharedMemoryVolumeSize(synthesizeComp *SynthesizedComponent, comp *appsv1alpha1.Component) { +func limitSharedMemoryVolumeSize(synthesizeComp *SynthesizedComponent, comp *appsv1.Component) { shm := defaultShmQuantity if comp.Spec.Resources.Limits != nil { if comp.Spec.Resources.Limits.Memory().Cmp(shm) > 0 { @@ -470,37 +449,51 @@ func limitSharedMemoryVolumeSize(synthesizeComp *SynthesizedComponent, comp *app } } -func toVolumeClaimTemplates(compSpec *appsv1alpha1.ComponentSpec) []corev1.PersistentVolumeClaimTemplate { +func toVolumeClaimTemplates(compSpec *appsv1.ComponentSpec) []corev1.PersistentVolumeClaimTemplate { + storageClassName := func(spec appsv1.PersistentVolumeClaimSpec, defaultStorageClass string) *string { + if spec.StorageClassName != nil && *spec.StorageClassName != "" { + return spec.StorageClassName + } + if defaultStorageClass != "" { + return &defaultStorageClass + } + return nil + } var ts []corev1.PersistentVolumeClaimTemplate for _, t := range compSpec.VolumeClaimTemplates { ts = append(ts, corev1.PersistentVolumeClaimTemplate{ ObjectMeta: metav1.ObjectMeta{ Name: t.Name, }, - Spec: t.Spec.ToV1PersistentVolumeClaimSpec(), + Spec: corev1.PersistentVolumeClaimSpec{ + AccessModes: t.Spec.AccessModes, + Resources: t.Spec.Resources, + StorageClassName: storageClassName(t.Spec, viper.GetString(constant.CfgKeyDefaultStorageClass)), + VolumeMode: t.Spec.VolumeMode, + }, }) } return ts } // buildAndUpdateResources updates podSpec resources from component -func buildAndUpdateResources(synthesizeComp *SynthesizedComponent, comp *appsv1alpha1.Component) { +func buildAndUpdateResources(synthesizeComp *SynthesizedComponent, comp *appsv1.Component) { if comp.Spec.Resources.Requests != nil || comp.Spec.Resources.Limits != nil { synthesizeComp.PodSpec.Containers[0].Resources = comp.Spec.Resources } } -func buildComponentServices(synthesizeComp *SynthesizedComponent, comp *appsv1alpha1.Component) { +func buildComponentServices(synthesizeComp *SynthesizedComponent, comp *appsv1.Component) { if len(synthesizeComp.ComponentServices) == 0 || len(comp.Spec.Services) == 0 { return } - services := map[string]appsv1alpha1.ComponentService{} + services := map[string]appsv1.ComponentService{} for i, svc := range comp.Spec.Services { services[svc.Name] = comp.Spec.Services[i] } - override := func(svc *appsv1alpha1.ComponentService) { + override := func(svc *appsv1.ComponentService) { svc1, ok := services[svc.Name] if ok { svc.Spec.Type = svc1.Spec.Type @@ -516,12 +509,12 @@ func buildComponentServices(synthesizeComp *SynthesizedComponent, comp *appsv1al } } -func overrideConfigTemplates(synthesizedComp *SynthesizedComponent, comp *appsv1alpha1.Component) error { +func overrideConfigTemplates(synthesizedComp *SynthesizedComponent, comp *appsv1.Component) error { if comp == nil || len(comp.Spec.Configs) == 0 { return nil } - templates := make(map[string]*appsv1alpha1.ComponentConfigSpec) + templates := make(map[string]*appsv1.ComponentConfigSpec) for i, template := range synthesizedComp.ConfigTemplates { templates[template.Name] = &synthesizedComp.ConfigTemplates[i] } @@ -566,14 +559,14 @@ func buildServiceAccountName(synthesizeComp *SynthesizedComponent) { synthesizeComp.PodSpec.ServiceAccountName = synthesizeComp.ServiceAccountName } -func buildRuntimeClassName(synthesizeComp *SynthesizedComponent, comp *appsv1alpha1.Component) { +func buildRuntimeClassName(synthesizeComp *SynthesizedComponent, comp *appsv1.Component) { if comp.Spec.RuntimeClassName == nil { return } synthesizeComp.PodSpec.RuntimeClassName = comp.Spec.RuntimeClassName } -func buildCompatibleHorizontalScalePolicy(compDef *appsv1alpha1.ComponentDefinition, synthesizeComp *SynthesizedComponent) { +func buildCompatibleHorizontalScalePolicy(compDef *appsv1.ComponentDefinition, synthesizeComp *SynthesizedComponent) { if compDef.Annotations != nil { templateName, ok := compDef.Annotations[constant.HorizontalScaleBackupPolicyTemplateKey] if ok { @@ -612,7 +605,7 @@ func ReplaceNamedVars(namedValuesMap map[string]string, targetVar string, limits return targetVar } -func GetConfigSpecByName(synthesizedComp *SynthesizedComponent, configSpec string) *appsv1alpha1.ComponentConfigSpec { +func GetConfigSpecByName(synthesizedComp *SynthesizedComponent, configSpec string) *appsv1.ComponentConfigSpec { for i := range synthesizedComp.ConfigTemplates { template := &synthesizedComp.ConfigTemplates[i] if template.Name == configSpec { diff --git a/pkg/controller/component/synthesize_component_test.go b/pkg/controller/component/synthesize_component_test.go index 5866622b2f3..ce9acd44a71 100644 --- a/pkg/controller/component/synthesize_component_test.go +++ b/pkg/controller/component/synthesize_component_test.go @@ -27,7 +27,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/client" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" "github.com/apecloud/kubeblocks/pkg/constant" intctrlutil "github.com/apecloud/kubeblocks/pkg/controllerutil" ) @@ -39,8 +39,8 @@ var _ = Describe("synthesized component", func() { Log: logger, } cli client.Reader - compDef *appsv1alpha1.ComponentDefinition - comp *appsv1alpha1.Component + compDef *appsv1.ComponentDefinition + comp *appsv1.Component ) cleanEnv := func() { @@ -70,21 +70,21 @@ var _ = Describe("synthesized component", func() { Context("config template", func() { BeforeEach(func() { - compDef = &appsv1alpha1.ComponentDefinition{ + compDef = &appsv1.ComponentDefinition{ ObjectMeta: metav1.ObjectMeta{ Name: "test-compdef", }, - Spec: appsv1alpha1.ComponentDefinitionSpec{ - Configs: []appsv1alpha1.ComponentConfigSpec{ + Spec: appsv1.ComponentDefinitionSpec{ + Configs: []appsv1.ComponentConfigSpec{ { - ComponentTemplateSpec: appsv1alpha1.ComponentTemplateSpec{ + ComponentTemplateSpec: appsv1.ComponentTemplateSpec{ Name: "app", TemplateRef: "app", VolumeName: "app", }, }, { - ComponentTemplateSpec: appsv1alpha1.ComponentTemplateSpec{ + ComponentTemplateSpec: appsv1.ComponentTemplateSpec{ Name: "external", VolumeName: "external", }, @@ -92,7 +92,7 @@ var _ = Describe("synthesized component", func() { }, }, } - comp = &appsv1alpha1.Component{ + comp = &appsv1.Component{ ObjectMeta: metav1.ObjectMeta{ Name: "test-cluster-comp", Labels: map[string]string{ @@ -103,14 +103,14 @@ var _ = Describe("synthesized component", func() { constant.KubeBlocksGenerationKey: "1", }, }, - Spec: appsv1alpha1.ComponentSpec{ - Configs: []appsv1alpha1.ClusterComponentConfig{}, + Spec: appsv1.ComponentSpec{ + Configs: []appsv1.ClusterComponentConfig{}, }, } }) It("comp def", func() { - synthesizedComp, err := buildSynthesizedComponent(reqCtx, cli, compDef, comp, nil, nil, nil) + synthesizedComp, err := buildSynthesizedComponent(reqCtx, cli, compDef, comp, nil, nil) Expect(err).Should(BeNil()) Expect(synthesizedComp).ShouldNot(BeNil()) @@ -118,9 +118,9 @@ var _ = Describe("synthesized component", func() { }) It("w/ comp override - ok", func() { - comp.Spec.Configs = append(comp.Spec.Configs, appsv1alpha1.ClusterComponentConfig{ + comp.Spec.Configs = append(comp.Spec.Configs, appsv1.ClusterComponentConfig{ Name: func() *string { name := "external"; return &name }(), - ClusterComponentConfigSource: appsv1alpha1.ClusterComponentConfigSource{ + ClusterComponentConfigSource: appsv1.ClusterComponentConfigSource{ ConfigMap: &corev1.ConfigMapVolumeSource{ LocalObjectReference: corev1.LocalObjectReference{ Name: "external-cm", @@ -128,7 +128,7 @@ var _ = Describe("synthesized component", func() { }, }, }) - synthesizedComp, err := buildSynthesizedComponent(reqCtx, cli, compDef, comp, nil, nil, nil) + synthesizedComp, err := buildSynthesizedComponent(reqCtx, cli, compDef, comp, nil, nil) Expect(err).Should(BeNil()) Expect(synthesizedComp).ShouldNot(BeNil()) @@ -140,9 +140,9 @@ var _ = Describe("synthesized component", func() { }) It("w/ comp override - not defined", func() { - comp.Spec.Configs = append(comp.Spec.Configs, appsv1alpha1.ClusterComponentConfig{ + comp.Spec.Configs = append(comp.Spec.Configs, appsv1.ClusterComponentConfig{ Name: func() *string { name := "not-defined"; return &name }(), - ClusterComponentConfigSource: appsv1alpha1.ClusterComponentConfigSource{ + ClusterComponentConfigSource: appsv1.ClusterComponentConfigSource{ ConfigMap: &corev1.ConfigMapVolumeSource{ LocalObjectReference: corev1.LocalObjectReference{ Name: "external-cm", @@ -150,16 +150,16 @@ var _ = Describe("synthesized component", func() { }, }, }) - _, err := buildSynthesizedComponent(reqCtx, cli, compDef, comp, nil, nil, nil) + _, err := buildSynthesizedComponent(reqCtx, cli, compDef, comp, nil, nil) Expect(err).ShouldNot(BeNil()) Expect(err.Error()).Should(ContainSubstring("not defined in definition")) }) It("w/ comp override - both specified", func() { compDef.Spec.Configs[1].TemplateRef = "external" - comp.Spec.Configs = append(comp.Spec.Configs, appsv1alpha1.ClusterComponentConfig{ + comp.Spec.Configs = append(comp.Spec.Configs, appsv1.ClusterComponentConfig{ Name: func() *string { name := "external"; return &name }(), - ClusterComponentConfigSource: appsv1alpha1.ClusterComponentConfigSource{ + ClusterComponentConfigSource: appsv1.ClusterComponentConfigSource{ ConfigMap: &corev1.ConfigMapVolumeSource{ LocalObjectReference: corev1.LocalObjectReference{ Name: "external-cm", @@ -167,17 +167,17 @@ var _ = Describe("synthesized component", func() { }, }, }) - _, err := buildSynthesizedComponent(reqCtx, cli, compDef, comp, nil, nil, nil) + _, err := buildSynthesizedComponent(reqCtx, cli, compDef, comp, nil, nil) Expect(err).ShouldNot(BeNil()) Expect(err.Error()).Should(ContainSubstring("partial overriding is not supported")) }) It("w/ comp override - both not specified", func() { - comp.Spec.Configs = append(comp.Spec.Configs, appsv1alpha1.ClusterComponentConfig{ + comp.Spec.Configs = append(comp.Spec.Configs, appsv1.ClusterComponentConfig{ Name: func() *string { name := "external"; return &name }(), - ClusterComponentConfigSource: appsv1alpha1.ClusterComponentConfigSource{}, + ClusterComponentConfigSource: appsv1.ClusterComponentConfigSource{}, }) - _, err := buildSynthesizedComponent(reqCtx, cli, compDef, comp, nil, nil, nil) + _, err := buildSynthesizedComponent(reqCtx, cli, compDef, comp, nil, nil) Expect(err).ShouldNot(BeNil()) Expect(err.Error()).Should(ContainSubstring("there is no content provided for config template")) }) @@ -185,11 +185,11 @@ var _ = Describe("synthesized component", func() { Context("env", func() { BeforeEach(func() { - compDef = &appsv1alpha1.ComponentDefinition{ + compDef = &appsv1.ComponentDefinition{ ObjectMeta: metav1.ObjectMeta{ Name: "test-compdef", }, - Spec: appsv1alpha1.ComponentDefinitionSpec{ + Spec: appsv1.ComponentDefinitionSpec{ Runtime: corev1.PodSpec{ Containers: []corev1.Container{ { @@ -205,7 +205,7 @@ var _ = Describe("synthesized component", func() { }, }, } - comp = &appsv1alpha1.Component{ + comp = &appsv1.Component{ ObjectMeta: metav1.ObjectMeta{ Name: "test-cluster-comp", Labels: map[string]string{ @@ -216,7 +216,7 @@ var _ = Describe("synthesized component", func() { constant.KubeBlocksGenerationKey: "1", }, }, - Spec: appsv1alpha1.ComponentSpec{ + Spec: appsv1.ComponentSpec{ Env: []corev1.EnvVar{ { Name: "ukey", @@ -230,13 +230,13 @@ var _ = Describe("synthesized component", func() { It("duplicated", func() { comp.Spec.Env = append(comp.Spec.Env, comp.Spec.Env[0]) - _, err := buildSynthesizedComponent(reqCtx, cli, compDef, comp, nil, nil, nil) + _, err := buildSynthesizedComponent(reqCtx, cli, compDef, comp, nil, nil) Expect(err).ShouldNot(BeNil()) Expect(err.Error()).Should(ContainSubstring("duplicated user-defined env var")) }) It("ok", func() { - synthesizedComp, err := buildSynthesizedComponent(reqCtx, cli, compDef, comp, nil, nil, nil) + synthesizedComp, err := buildSynthesizedComponent(reqCtx, cli, compDef, comp, nil, nil) Expect(err).Should(BeNil()) Expect(synthesizedComp).ShouldNot(BeNil()) Expect(synthesizedComp.PodSpec.Containers[0].Env).Should(HaveLen(2)) @@ -246,11 +246,11 @@ var _ = Describe("synthesized component", func() { Context("volumes", func() { BeforeEach(func() { - compDef = &appsv1alpha1.ComponentDefinition{ + compDef = &appsv1.ComponentDefinition{ ObjectMeta: metav1.ObjectMeta{ Name: "test-compdef", }, - Spec: appsv1alpha1.ComponentDefinitionSpec{ + Spec: appsv1.ComponentDefinitionSpec{ Runtime: corev1.PodSpec{ Volumes: []corev1.Volume{ { @@ -279,7 +279,7 @@ var _ = Describe("synthesized component", func() { }, }, } - comp = &appsv1alpha1.Component{ + comp = &appsv1.Component{ ObjectMeta: metav1.ObjectMeta{ Name: "test-cluster-comp", Labels: map[string]string{ @@ -290,7 +290,7 @@ var _ = Describe("synthesized component", func() { constant.KubeBlocksGenerationKey: "1", }, }, - Spec: appsv1alpha1.ComponentSpec{ + Spec: appsv1.ComponentSpec{ Volumes: []corev1.Volume{ { Name: "data", @@ -309,7 +309,7 @@ var _ = Describe("synthesized component", func() { It("duplicated", func() { comp.Spec.Volumes = append(comp.Spec.Volumes, comp.Spec.Volumes[0]) - _, err := buildSynthesizedComponent(reqCtx, cli, compDef, comp, nil, nil, nil) + _, err := buildSynthesizedComponent(reqCtx, cli, compDef, comp, nil, nil) Expect(err).ShouldNot(BeNil()) Expect(err.Error()).Should(ContainSubstring("duplicated volume")) }) @@ -317,7 +317,7 @@ var _ = Describe("synthesized component", func() { It("duplicated with definition", func() { comp.Spec.Volumes = append(comp.Spec.Volumes, compDef.Spec.Runtime.Volumes[0]) - _, err := buildSynthesizedComponent(reqCtx, cli, compDef, comp, nil, nil, nil) + _, err := buildSynthesizedComponent(reqCtx, cli, compDef, comp, nil, nil) Expect(err).ShouldNot(BeNil()) Expect(err.Error()).Should(ContainSubstring("duplicated volume")) }) @@ -326,13 +326,13 @@ var _ = Describe("synthesized component", func() { // volumes := comp.Spec.Volumes // comp.Spec.Volumes = comp.Spec.Volumes[0:1] // - // _, err := buildSynthesizedComponent(reqCtx, cli, compDef, comp, nil, nil, nil) + // _, err := buildSynthesizedComponent(reqCtx, cli, compDef, comp, nil, nil) // Expect(err).ShouldNot(BeNil()) // Expect(err.Error()).Should(And(ContainSubstring("volumes should be provided for mounts"), ContainSubstring(volumes[1].Name))) // }) It("ok", func() { - synthesizedComp, err := buildSynthesizedComponent(reqCtx, cli, compDef, comp, nil, nil, nil) + synthesizedComp, err := buildSynthesizedComponent(reqCtx, cli, compDef, comp, nil, nil) Expect(err).Should(BeNil()) Expect(synthesizedComp).ShouldNot(BeNil()) Expect(synthesizedComp.PodSpec.Volumes).Should(HaveLen(4)) diff --git a/pkg/controller/component/type.go b/pkg/controller/component/type.go index 1c99de3dd78..31103681990 100644 --- a/pkg/controller/component/type.go +++ b/pkg/controller/component/type.go @@ -26,8 +26,6 @@ import ( "k8s.io/apimachinery/pkg/util/intstr" kbappsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" - workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" ) type SynthesizedComponent struct { @@ -45,35 +43,35 @@ type SynthesizedComponent struct { Resources corev1.ResourceRequirements `json:"resources,omitempty"` PodSpec *corev1.PodSpec `json:"podSpec,omitempty"` VolumeClaimTemplates []corev1.PersistentVolumeClaimTemplate `json:"volumeClaimTemplates,omitempty"` - LogConfigs []appsv1alpha1.LogConfig `json:"logConfigs,omitempty"` - ConfigTemplates []appsv1alpha1.ComponentConfigSpec `json:"configTemplates,omitempty"` - ScriptTemplates []appsv1alpha1.ComponentTemplateSpec `json:"scriptTemplates,omitempty"` - TLSConfig *appsv1alpha1.TLSConfig `json:"tlsConfig"` + LogConfigs []kbappsv1.LogConfig `json:"logConfigs,omitempty"` + ConfigTemplates []kbappsv1.ComponentConfigSpec `json:"configTemplates,omitempty"` + ScriptTemplates []kbappsv1.ComponentTemplateSpec `json:"scriptTemplates,omitempty"` + TLSConfig *kbappsv1.TLSConfig `json:"tlsConfig"` ServiceAccountName string `json:"serviceAccountName,omitempty"` ServiceReferences map[string]*kbappsv1.ServiceDescriptor `json:"serviceReferences,omitempty"` UserDefinedLabels map[string]string UserDefinedAnnotations map[string]string - TemplateVars map[string]any `json:"templateVars,omitempty"` - EnvVars []corev1.EnvVar `json:"envVars,omitempty"` - EnvFromSources []corev1.EnvFromSource `json:"envFromSources,omitempty"` - Instances []appsv1alpha1.InstanceTemplate `json:"instances,omitempty"` - OfflineInstances []string `json:"offlineInstances,omitempty"` - Roles []appsv1alpha1.ReplicaRole `json:"roles,omitempty"` - Labels map[string]string `json:"labels,omitempty"` - Annotations map[string]string `json:"annotations,omitempty"` - UpdateStrategy *appsv1alpha1.UpdateStrategy `json:"updateStrategy,omitempty"` - PodManagementPolicy *appsv1.PodManagementPolicyType `json:"podManagementPolicy,omitempty"` - ParallelPodManagementConcurrency *intstr.IntOrString `json:"parallelPodManagementConcurrency,omitempty"` - PodUpdatePolicy *workloads.PodUpdatePolicyType `json:"podUpdatePolicy,omitempty"` - PolicyRules []rbacv1.PolicyRule `json:"policyRules,omitempty"` - LifecycleActions *appsv1alpha1.ComponentLifecycleActions `json:"lifecycleActions,omitempty"` - SystemAccounts []appsv1alpha1.SystemAccount `json:"systemAccounts,omitempty"` - Volumes []appsv1alpha1.ComponentVolume `json:"volumes,omitempty"` - HostNetwork *appsv1alpha1.HostNetwork `json:"hostNetwork,omitempty"` - ComponentServices []appsv1alpha1.ComponentService `json:"componentServices,omitempty"` - MinReadySeconds int32 `json:"minReadySeconds,omitempty"` - Sidecars []string `json:"sidecars,omitempty"` - DisableExporter *bool `json:"disableExporter,omitempty"` + TemplateVars map[string]any `json:"templateVars,omitempty"` + EnvVars []corev1.EnvVar `json:"envVars,omitempty"` + EnvFromSources []corev1.EnvFromSource `json:"envFromSources,omitempty"` + Instances []kbappsv1.InstanceTemplate `json:"instances,omitempty"` + OfflineInstances []string `json:"offlineInstances,omitempty"` + Roles []kbappsv1.ReplicaRole `json:"roles,omitempty"` + Labels map[string]string `json:"labels,omitempty"` + Annotations map[string]string `json:"annotations,omitempty"` + UpdateStrategy *kbappsv1.UpdateStrategy `json:"updateStrategy,omitempty"` + PodManagementPolicy *appsv1.PodManagementPolicyType `json:"podManagementPolicy,omitempty"` + ParallelPodManagementConcurrency *intstr.IntOrString `json:"parallelPodManagementConcurrency,omitempty"` + PodUpdatePolicy *kbappsv1.PodUpdatePolicyType `json:"podUpdatePolicy,omitempty"` + PolicyRules []rbacv1.PolicyRule `json:"policyRules,omitempty"` + LifecycleActions *kbappsv1.ComponentLifecycleActions `json:"lifecycleActions,omitempty"` + SystemAccounts []kbappsv1.SystemAccount `json:"systemAccounts,omitempty"` + Volumes []kbappsv1.ComponentVolume `json:"volumes,omitempty"` + HostNetwork *kbappsv1.HostNetwork `json:"hostNetwork,omitempty"` + ComponentServices []kbappsv1.ComponentService `json:"componentServices,omitempty"` + MinReadySeconds int32 `json:"minReadySeconds,omitempty"` + Sidecars []string `json:"sidecars,omitempty"` + DisableExporter *bool `json:"disableExporter,omitempty"` Stop *bool // TODO(xingran): The following fields will be deprecated after KubeBlocks version 0.8.0 diff --git a/pkg/controller/component/utils.go b/pkg/controller/component/utils.go index 05bb2da6134..0153817fd59 100644 --- a/pkg/controller/component/utils.go +++ b/pkg/controller/component/utils.go @@ -27,7 +27,7 @@ import ( "k8s.io/apimachinery/pkg/types" "sigs.k8s.io/controller-runtime/pkg/client" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" "github.com/apecloud/kubeblocks/pkg/constant" "github.com/apecloud/kubeblocks/pkg/controller/multicluster" intctrlutil "github.com/apecloud/kubeblocks/pkg/controllerutil" @@ -59,7 +59,7 @@ func isHostNetworkEnabled(ctx context.Context, cli client.Reader, synthesizedCom Namespace: synthesizedComp.Namespace, Name: constant.GenerateClusterComponentName(synthesizedComp.ClusterName, compName), } - comp := &appsv1alpha1.Component{} + comp := &appsv1.Component{} if err := cli.Get(ctx, compKey, comp, inDataContext()); err != nil { return false, err } @@ -69,7 +69,7 @@ func isHostNetworkEnabled(ctx context.Context, cli client.Reader, synthesizedCom // check the component definition that whether it has the host-network capability if len(comp.Spec.CompDef) > 0 { - compDef := &appsv1alpha1.ComponentDefinition{} + compDef := &appsv1.ComponentDefinition{} if err := cli.Get(ctx, types.NamespacedName{Name: comp.Spec.CompDef}, compDef); err != nil { return false, err } @@ -80,7 +80,7 @@ func isHostNetworkEnabled(ctx context.Context, cli client.Reader, synthesizedCom return false, nil } -func hasHostNetworkCapability(synthesizedComp *SynthesizedComponent, compDef *appsv1alpha1.ComponentDefinition) bool { +func hasHostNetworkCapability(synthesizedComp *SynthesizedComponent, compDef *appsv1.ComponentDefinition) bool { switch { case synthesizedComp != nil: return synthesizedComp.HostNetwork != nil diff --git a/pkg/controller/component/vars.go b/pkg/controller/component/vars.go index 644404e300f..7388e37ec05 100644 --- a/pkg/controller/component/vars.go +++ b/pkg/controller/component/vars.go @@ -40,7 +40,6 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" "github.com/apecloud/kubeblocks/pkg/common" "github.com/apecloud/kubeblocks/pkg/constant" @@ -61,11 +60,11 @@ func VarReferenceRegExp() *regexp.Regexp { } // ResolveTemplateNEnvVars resolves all built-in and user-defined vars for config template and Env usage. -func ResolveTemplateNEnvVars(ctx context.Context, cli client.Reader, synthesizedComp *SynthesizedComponent, definedVars []appsv1alpha1.EnvVar) (map[string]any, []corev1.EnvVar, error) { +func ResolveTemplateNEnvVars(ctx context.Context, cli client.Reader, synthesizedComp *SynthesizedComponent, definedVars []appsv1.EnvVar) (map[string]any, []corev1.EnvVar, error) { return resolveTemplateNEnvVars(ctx, cli, synthesizedComp, definedVars, false) } -func ResolveEnvVars4LegacyCluster(ctx context.Context, cli client.Reader, synthesizedComp *SynthesizedComponent, definedVars []appsv1alpha1.EnvVar) (map[string]any, []corev1.EnvVar, error) { +func ResolveEnvVars4LegacyCluster(ctx context.Context, cli client.Reader, synthesizedComp *SynthesizedComponent, definedVars []appsv1.EnvVar) (map[string]any, []corev1.EnvVar, error) { return resolveTemplateNEnvVars(ctx, cli, synthesizedComp, definedVars, true) } @@ -105,7 +104,7 @@ func InjectEnvVars4Containers(synthesizedComp *SynthesizedComponent, envVars []c } func resolveTemplateNEnvVars(ctx context.Context, cli client.Reader, synthesizedComp *SynthesizedComponent, - definedVars []appsv1alpha1.EnvVar, legacy bool) (map[string]any, []corev1.EnvVar, error) { + definedVars []appsv1.EnvVar, legacy bool) (map[string]any, []corev1.EnvVar, error) { templateVars, envVars, err := resolveNewTemplateNEnvVars(ctx, cli, synthesizedComp, definedVars) if err != nil { return nil, nil, err @@ -134,7 +133,7 @@ func resolveTemplateNEnvVars(ctx context.Context, cli client.Reader, synthesized } func resolveNewTemplateNEnvVars(ctx context.Context, cli client.Reader, synthesizedComp *SynthesizedComponent, - definedVars []appsv1alpha1.EnvVar) ([]corev1.EnvVar, []corev1.EnvVar, error) { + definedVars []appsv1.EnvVar) ([]corev1.EnvVar, []corev1.EnvVar, error) { vars, credentialVars, err := resolveBuiltinNObjectRefVars(ctx, cli, synthesizedComp, definedVars) if err != nil { return nil, nil, err @@ -156,7 +155,7 @@ func buildLegacyImplicitEnvVars(synthesizedComp *SynthesizedComponent, legacy bo } func resolveBuiltinNObjectRefVars(ctx context.Context, cli client.Reader, synthesizedComp *SynthesizedComponent, - definedVars []appsv1alpha1.EnvVar) ([]corev1.EnvVar, []corev1.EnvVar, error) { + definedVars []appsv1.EnvVar) ([]corev1.EnvVar, []corev1.EnvVar, error) { vars := builtinTemplateVars(synthesizedComp, definedVars) vars1, vars2, err := resolveClusterObjectRefVars(ctx, cli, synthesizedComp, definedVars) if err != nil { @@ -169,7 +168,7 @@ func resolveBuiltinNObjectRefVars(ctx context.Context, cli client.Reader, synthe return vars, vars2, nil } -func builtinTemplateVars(synthesizedComp *SynthesizedComponent, definedVars []appsv1alpha1.EnvVar) []corev1.EnvVar { +func builtinTemplateVars(synthesizedComp *SynthesizedComponent, definedVars []appsv1.EnvVar) []corev1.EnvVar { if synthesizedComp != nil { // keep those vars to be compatible with legacy. defined := sets.New[string]() @@ -397,7 +396,7 @@ func buildEnv4UserDefined(annotations map[string]string) ([]corev1.EnvVar, error return vars, nil } -func evaluateObjectVarsExpression(definedVars []appsv1alpha1.EnvVar, credentialVars []corev1.EnvVar, vars *[]corev1.EnvVar) error { +func evaluateObjectVarsExpression(definedVars []appsv1.EnvVar, credentialVars []corev1.EnvVar, vars *[]corev1.EnvVar) error { var ( isValues = make(map[string]bool) values = make(map[string]string) @@ -417,7 +416,7 @@ func evaluateObjectVarsExpression(definedVars []appsv1alpha1.EnvVar, credentialV } } - evaluable := func(v appsv1alpha1.EnvVar) bool { + evaluable := func(v appsv1.EnvVar) bool { if v.Expression == nil || len(*v.Expression) == 0 { return false } @@ -443,7 +442,7 @@ func evaluateObjectVarsExpression(definedVars []appsv1alpha1.EnvVar, credentialV values[normalize(name)] = value } - eval := func(v appsv1alpha1.EnvVar) error { + eval := func(v appsv1.EnvVar) error { if !evaluable(v) { return nil } @@ -468,7 +467,7 @@ func evaluateObjectVarsExpression(definedVars []appsv1alpha1.EnvVar, credentialV } func resolveClusterObjectRefVars(ctx context.Context, cli client.Reader, synthesizedComp *SynthesizedComponent, - definedVars []appsv1alpha1.EnvVar) ([]corev1.EnvVar, []corev1.EnvVar, error) { + definedVars []appsv1.EnvVar) ([]corev1.EnvVar, []corev1.EnvVar, error) { if synthesizedComp == nil { return nil, nil, nil } @@ -493,7 +492,7 @@ func resolveClusterObjectRefVars(ctx context.Context, cli client.Reader, synthes // resolveClusterObjectVarRef resolves vars referred from cluster objects, returns the resolved non-credential and credential vars respectively. func resolveClusterObjectVarRef(ctx context.Context, cli client.Reader, synthesizedComp *SynthesizedComponent, - defineKey string, source appsv1alpha1.VarSource, ext ...any) ([]corev1.EnvVar, []corev1.EnvVar, error) { + defineKey string, source appsv1.VarSource, ext ...any) ([]corev1.EnvVar, []corev1.EnvVar, error) { switch { case source.ConfigMapKeyRef != nil: return resolveConfigMapKeyRef(ctx, cli, synthesizedComp, defineKey, *source.ConfigMapKeyRef) @@ -593,8 +592,8 @@ func resolveNativeObjectKey(ctx context.Context, cli client.Reader, synthesizedC } func resolveHostNetworkVarRef(ctx context.Context, cli client.Reader, synthesizedComp *SynthesizedComponent, - defineKey string, selector appsv1alpha1.HostNetworkVarSelector, ext ...any) ([]corev1.EnvVar, []corev1.EnvVar, error) { - var resolveFunc func(context.Context, client.Reader, *SynthesizedComponent, string, appsv1alpha1.HostNetworkVarSelector) ([]*corev1.EnvVar, []*corev1.EnvVar, error) + defineKey string, selector appsv1.HostNetworkVarSelector, ext ...any) ([]corev1.EnvVar, []corev1.EnvVar, error) { + var resolveFunc func(context.Context, client.Reader, *SynthesizedComponent, string, appsv1.HostNetworkVarSelector) ([]*corev1.EnvVar, []*corev1.EnvVar, error) switch { case selector.Container != nil && selector.Container.Port != nil: resolveFunc = resolveHostNetworkPortRef @@ -604,7 +603,7 @@ func resolveHostNetworkVarRef(ctx context.Context, cli client.Reader, synthesize v1, _, err := resolveFunc(ctx, cli, synthesizedComp, defineKey, selector) // HACK: back-off to use v.Value if specified if v1 == nil && err == nil && len(ext) > 0 { - v := ext[0].(appsv1alpha1.EnvVar) + v := ext[0].(appsv1.EnvVar) if len(v.Value) > 0 { v1 = []*corev1.EnvVar{{Name: v.Name, Value: v.Value}} } @@ -613,7 +612,7 @@ func resolveHostNetworkVarRef(ctx context.Context, cli client.Reader, synthesize } func resolveHostNetworkPortRef(ctx context.Context, cli client.Reader, synthesizedComp *SynthesizedComponent, - defineKey string, selector appsv1alpha1.HostNetworkVarSelector) ([]*corev1.EnvVar, []*corev1.EnvVar, error) { + defineKey string, selector appsv1.HostNetworkVarSelector) ([]*corev1.EnvVar, []*corev1.EnvVar, error) { resolvePort := func(obj any) (*corev1.EnvVar, *corev1.EnvVar, error) { compName := obj.(string) port, _ := getHostNetworkPort(ctx, cli, synthesizedComp.ClusterName, compName, selector.Container.Name, selector.Container.Port.Name) @@ -629,8 +628,8 @@ func resolveHostNetworkPortRef(ctx context.Context, cli client.Reader, synthesiz } func resolveServiceVarRef(ctx context.Context, cli client.Reader, synthesizedComp *SynthesizedComponent, - defineKey string, selector appsv1alpha1.ServiceVarSelector) ([]corev1.EnvVar, []corev1.EnvVar, error) { - var resolveFunc func(context.Context, client.Reader, *SynthesizedComponent, string, appsv1alpha1.ServiceVarSelector) ([]*corev1.EnvVar, []*corev1.EnvVar, error) + defineKey string, selector appsv1.ServiceVarSelector) ([]corev1.EnvVar, []corev1.EnvVar, error) { + var resolveFunc func(context.Context, client.Reader, *SynthesizedComponent, string, appsv1.ServiceVarSelector) ([]*corev1.EnvVar, []*corev1.EnvVar, error) switch { case selector.ServiceType != nil: resolveFunc = resolveServiceTypeRef @@ -654,7 +653,7 @@ type resolvedServiceObj struct { } func resolveServiceTypeRef(ctx context.Context, cli client.Reader, synthesizedComp *SynthesizedComponent, - defineKey string, selector appsv1alpha1.ServiceVarSelector) ([]*corev1.EnvVar, []*corev1.EnvVar, error) { + defineKey string, selector appsv1.ServiceVarSelector) ([]*corev1.EnvVar, []*corev1.EnvVar, error) { resolveServiceType := func(obj any) (*corev1.EnvVar, *corev1.EnvVar, error) { robj := obj.(*resolvedServiceObj) services := []*corev1.Service{robj.service} @@ -673,7 +672,7 @@ func resolveServiceTypeRef(ctx context.Context, cli client.Reader, synthesizedCo } func resolveServiceHostRef(ctx context.Context, cli client.Reader, synthesizedComp *SynthesizedComponent, - defineKey string, selector appsv1alpha1.ServiceVarSelector) ([]*corev1.EnvVar, []*corev1.EnvVar, error) { + defineKey string, selector appsv1.ServiceVarSelector) ([]*corev1.EnvVar, []*corev1.EnvVar, error) { resolveHost := func(obj any) (*corev1.EnvVar, *corev1.EnvVar, error) { return &corev1.EnvVar{Name: defineKey, Value: composeHostValueFromServices(obj)}, nil, nil } @@ -697,7 +696,7 @@ func composeHostValueFromServices(obj any) string { } func resolveServicePortRef(ctx context.Context, cli client.Reader, synthesizedComp *SynthesizedComponent, - defineKey string, selector appsv1alpha1.ServiceVarSelector) ([]*corev1.EnvVar, []*corev1.EnvVar, error) { + defineKey string, selector appsv1.ServiceVarSelector) ([]*corev1.EnvVar, []*corev1.EnvVar, error) { resolvePort := func(obj any) (*corev1.EnvVar, *corev1.EnvVar, error) { port := composePortValueFromServices(obj, selector.Port.Name) if port == nil { @@ -742,7 +741,7 @@ func composePortValueFromServices(obj any, targetPortName string) *string { } func resolveServiceLoadBalancerRef(ctx context.Context, cli client.Reader, synthesizedComp *SynthesizedComponent, - defineKey string, selector appsv1alpha1.ServiceVarSelector) ([]*corev1.EnvVar, []*corev1.EnvVar, error) { + defineKey string, selector appsv1.ServiceVarSelector) ([]*corev1.EnvVar, []*corev1.EnvVar, error) { resolveLoadBalancer := func(obj any) (*corev1.EnvVar, *corev1.EnvVar, error) { points := composeLoadBalancerValueFromServices(obj) if points == nil { @@ -815,7 +814,7 @@ func composeNamedValueFromServices(obj any, selector func([]*corev1.Service) map } func resolveServiceHostOrLoadBalancerRefAdaptive(ctx context.Context, cli client.Reader, synthesizedComp *SynthesizedComponent, - defineKey string, selector appsv1alpha1.ServiceVarSelector) ([]*corev1.EnvVar, []*corev1.EnvVar, error) { + defineKey string, selector appsv1.ServiceVarSelector) ([]*corev1.EnvVar, []*corev1.EnvVar, error) { host := func(obj any) (*corev1.EnvVar, *corev1.EnvVar, error) { return &corev1.EnvVar{Name: defineKey, Value: composeHostValueFromServices(obj)}, nil, nil } @@ -849,8 +848,8 @@ func resolveServiceHostOrLoadBalancerRefAdaptive(ctx context.Context, cli client } func resolveCredentialVarRef(ctx context.Context, cli client.Reader, synthesizedComp *SynthesizedComponent, - defineKey string, selector appsv1alpha1.CredentialVarSelector) ([]corev1.EnvVar, []corev1.EnvVar, error) { - var resolveFunc func(context.Context, client.Reader, *SynthesizedComponent, string, appsv1alpha1.CredentialVarSelector) ([]*corev1.EnvVar, []*corev1.EnvVar, error) + defineKey string, selector appsv1.CredentialVarSelector) ([]corev1.EnvVar, []corev1.EnvVar, error) { + var resolveFunc func(context.Context, client.Reader, *SynthesizedComponent, string, appsv1.CredentialVarSelector) ([]*corev1.EnvVar, []*corev1.EnvVar, error) switch { case selector.Username != nil: resolveFunc = resolveCredentialUsernameRef @@ -863,7 +862,7 @@ func resolveCredentialVarRef(ctx context.Context, cli client.Reader, synthesized } func resolveCredentialUsernameRef(ctx context.Context, cli client.Reader, synthesizedComp *SynthesizedComponent, - defineKey string, selector appsv1alpha1.CredentialVarSelector) ([]*corev1.EnvVar, []*corev1.EnvVar, error) { + defineKey string, selector appsv1.CredentialVarSelector) ([]*corev1.EnvVar, []*corev1.EnvVar, error) { resolveUsername := func(obj any) (*corev1.EnvVar, *corev1.EnvVar, error) { secret := obj.(*corev1.Secret) if secret.Data != nil { @@ -887,7 +886,7 @@ func resolveCredentialUsernameRef(ctx context.Context, cli client.Reader, synthe } func resolveCredentialPasswordRef(ctx context.Context, cli client.Reader, synthesizedComp *SynthesizedComponent, - defineKey string, selector appsv1alpha1.CredentialVarSelector) ([]*corev1.EnvVar, []*corev1.EnvVar, error) { + defineKey string, selector appsv1.CredentialVarSelector) ([]*corev1.EnvVar, []*corev1.EnvVar, error) { resolvePassword := func(obj any) (*corev1.EnvVar, *corev1.EnvVar, error) { secret := obj.(*corev1.Secret) if secret.Data != nil { @@ -911,8 +910,8 @@ func resolveCredentialPasswordRef(ctx context.Context, cli client.Reader, synthe } func resolveServiceRefVarRef(ctx context.Context, cli client.Reader, synthesizedComp *SynthesizedComponent, - defineKey string, selector appsv1alpha1.ServiceRefVarSelector) ([]corev1.EnvVar, []corev1.EnvVar, error) { - var resolveFunc func(context.Context, client.Reader, *SynthesizedComponent, string, appsv1alpha1.ServiceRefVarSelector) ([]*corev1.EnvVar, []*corev1.EnvVar, error) + defineKey string, selector appsv1.ServiceRefVarSelector) ([]corev1.EnvVar, []corev1.EnvVar, error) { + var resolveFunc func(context.Context, client.Reader, *SynthesizedComponent, string, appsv1.ServiceRefVarSelector) ([]*corev1.EnvVar, []*corev1.EnvVar, error) switch { case selector.Endpoint != nil: resolveFunc = resolveServiceRefEndpointRef @@ -931,7 +930,7 @@ func resolveServiceRefVarRef(ctx context.Context, cli client.Reader, synthesized } func resolveServiceRefEndpointRef(ctx context.Context, cli client.Reader, synthesizedComp *SynthesizedComponent, - defineKey string, selector appsv1alpha1.ServiceRefVarSelector) ([]*corev1.EnvVar, []*corev1.EnvVar, error) { + defineKey string, selector appsv1.ServiceRefVarSelector) ([]*corev1.EnvVar, []*corev1.EnvVar, error) { resolveEndpoint := func(obj any) (*corev1.EnvVar, *corev1.EnvVar, error) { sd := obj.(*appsv1.ServiceDescriptor) if sd.Spec.Endpoint == nil { @@ -946,7 +945,7 @@ func resolveServiceRefEndpointRef(ctx context.Context, cli client.Reader, synthe } func resolveServiceRefHostRef(ctx context.Context, cli client.Reader, synthesizedComp *SynthesizedComponent, - defineKey string, selector appsv1alpha1.ServiceRefVarSelector) ([]*corev1.EnvVar, []*corev1.EnvVar, error) { + defineKey string, selector appsv1.ServiceRefVarSelector) ([]*corev1.EnvVar, []*corev1.EnvVar, error) { resolveHost := func(obj any) (*corev1.EnvVar, *corev1.EnvVar, error) { sd := obj.(*appsv1.ServiceDescriptor) if sd.Spec.Host == nil { @@ -961,7 +960,7 @@ func resolveServiceRefHostRef(ctx context.Context, cli client.Reader, synthesize } func resolveServiceRefPortRef(ctx context.Context, cli client.Reader, synthesizedComp *SynthesizedComponent, - defineKey string, selector appsv1alpha1.ServiceRefVarSelector) ([]*corev1.EnvVar, []*corev1.EnvVar, error) { + defineKey string, selector appsv1.ServiceRefVarSelector) ([]*corev1.EnvVar, []*corev1.EnvVar, error) { resolvePort := func(obj any) (*corev1.EnvVar, *corev1.EnvVar, error) { sd := obj.(*appsv1.ServiceDescriptor) if sd.Spec.Port == nil { @@ -976,7 +975,7 @@ func resolveServiceRefPortRef(ctx context.Context, cli client.Reader, synthesize } func resolveServiceRefUsernameRef(ctx context.Context, cli client.Reader, synthesizedComp *SynthesizedComponent, - defineKey string, selector appsv1alpha1.ServiceRefVarSelector) ([]*corev1.EnvVar, []*corev1.EnvVar, error) { + defineKey string, selector appsv1.ServiceRefVarSelector) ([]*corev1.EnvVar, []*corev1.EnvVar, error) { resolveUsername := func(obj any) (*corev1.EnvVar, *corev1.EnvVar, error) { sd := obj.(*appsv1.ServiceDescriptor) if sd.Spec.Auth == nil || sd.Spec.Auth.Username == nil { @@ -993,7 +992,7 @@ func resolveServiceRefUsernameRef(ctx context.Context, cli client.Reader, synthe } func resolveServiceRefPasswordRef(ctx context.Context, cli client.Reader, synthesizedComp *SynthesizedComponent, - defineKey string, selector appsv1alpha1.ServiceRefVarSelector) ([]*corev1.EnvVar, []*corev1.EnvVar, error) { + defineKey string, selector appsv1.ServiceRefVarSelector) ([]*corev1.EnvVar, []*corev1.EnvVar, error) { resolvePassword := func(obj any) (*corev1.EnvVar, *corev1.EnvVar, error) { sd := obj.(*appsv1.ServiceDescriptor) if sd.Spec.Auth == nil || sd.Spec.Auth.Password == nil { @@ -1010,7 +1009,7 @@ func resolveServiceRefPasswordRef(ctx context.Context, cli client.Reader, synthe } func resolveHostNetworkVarRefLow(ctx context.Context, cli client.Reader, synthesizedComp *SynthesizedComponent, - selector appsv1alpha1.HostNetworkVarSelector, option *appsv1alpha1.VarOption, resolveVar func(any) (*corev1.EnvVar, *corev1.EnvVar, error)) ([]*corev1.EnvVar, []*corev1.EnvVar, error) { + selector appsv1.HostNetworkVarSelector, option *appsv1.VarOption, resolveVar func(any) (*corev1.EnvVar, *corev1.EnvVar, error)) ([]*corev1.EnvVar, []*corev1.EnvVar, error) { resolveObjs := func() (map[string]any, error) { getter := func(compName string) (any, error) { enabled, err := isHostNetworkEnabled(ctx, cli, synthesizedComp, compName) @@ -1028,7 +1027,7 @@ func resolveHostNetworkVarRefLow(ctx context.Context, cli client.Reader, synthes } func resolveServiceVarRefLow(ctx context.Context, cli client.Reader, synthesizedComp *SynthesizedComponent, - selector appsv1alpha1.ServiceVarSelector, option *appsv1alpha1.VarOption, resolveVar func(any) (*corev1.EnvVar, *corev1.EnvVar, error)) ([]*corev1.EnvVar, []*corev1.EnvVar, error) { + selector appsv1.ServiceVarSelector, option *appsv1.VarOption, resolveVar func(any) (*corev1.EnvVar, *corev1.EnvVar, error)) ([]*corev1.EnvVar, []*corev1.EnvVar, error) { resolveObjs := func() (map[string]any, error) { headlessGetter := func(compName string) (any, error) { return headlessCompServiceGetter(ctx, cli, synthesizedComp.Namespace, synthesizedComp.ClusterName, compName) @@ -1120,7 +1119,7 @@ func headlessCompServiceGetter(ctx context.Context, cli client.Reader, namespace } func resolveCredentialVarRefLow(ctx context.Context, cli client.Reader, synthesizedComp *SynthesizedComponent, - selector appsv1alpha1.CredentialVarSelector, option *appsv1alpha1.VarOption, resolveVar func(any) (*corev1.EnvVar, *corev1.EnvVar, error)) ([]*corev1.EnvVar, []*corev1.EnvVar, error) { + selector appsv1.CredentialVarSelector, option *appsv1.VarOption, resolveVar func(any) (*corev1.EnvVar, *corev1.EnvVar, error)) ([]*corev1.EnvVar, []*corev1.EnvVar, error) { resolveObjs := func() (map[string]any, error) { getter := func(compName string) (any, error) { key := types.NamespacedName{ @@ -1137,7 +1136,7 @@ func resolveCredentialVarRefLow(ctx context.Context, cli client.Reader, synthesi } func resolveServiceRefVarRefLow(ctx context.Context, cli client.Reader, synthesizedComp *SynthesizedComponent, - selector appsv1alpha1.ServiceRefVarSelector, option *appsv1alpha1.VarOption, resolveVar func(any) (*corev1.EnvVar, *corev1.EnvVar, error)) ([]*corev1.EnvVar, []*corev1.EnvVar, error) { + selector appsv1.ServiceRefVarSelector, option *appsv1.VarOption, resolveVar func(any) (*corev1.EnvVar, *corev1.EnvVar, error)) ([]*corev1.EnvVar, []*corev1.EnvVar, error) { resolveObjs := func() (map[string]any, error) { getter := func(compName string) (any, error) { if compName == synthesizedComp.Name { @@ -1155,8 +1154,8 @@ func resolveServiceRefVarRefLow(ctx context.Context, cli client.Reader, synthesi } func resolveComponentVarRef(ctx context.Context, cli client.Reader, synthesizedComp *SynthesizedComponent, - defineKey string, selector appsv1alpha1.ComponentVarSelector) ([]corev1.EnvVar, []corev1.EnvVar, error) { - var resolveFunc func(context.Context, client.Reader, *SynthesizedComponent, string, appsv1alpha1.ComponentVarSelector) ([]*corev1.EnvVar, []*corev1.EnvVar, error) + defineKey string, selector appsv1.ComponentVarSelector) ([]corev1.EnvVar, []corev1.EnvVar, error) { + var resolveFunc func(context.Context, client.Reader, *SynthesizedComponent, string, appsv1.ComponentVarSelector) ([]*corev1.EnvVar, []*corev1.EnvVar, error) switch { case selector.ComponentName != nil || selector.ShortName != nil: resolveFunc = resolveComponentNameRef @@ -1173,9 +1172,9 @@ func resolveComponentVarRef(ctx context.Context, cli client.Reader, synthesizedC } func resolveComponentNameRef(ctx context.Context, cli client.Reader, synthesizedComp *SynthesizedComponent, - defineKey string, selector appsv1alpha1.ComponentVarSelector) ([]*corev1.EnvVar, []*corev1.EnvVar, error) { + defineKey string, selector appsv1.ComponentVarSelector) ([]*corev1.EnvVar, []*corev1.EnvVar, error) { resolveComponentName := func(obj any) (*corev1.EnvVar, *corev1.EnvVar, error) { - comp := obj.(*appsv1alpha1.Component) + comp := obj.(*appsv1.Component) name := comp.Name if selector.ShortName != nil { name = synthesizedComp.Name @@ -1186,18 +1185,18 @@ func resolveComponentNameRef(ctx context.Context, cli client.Reader, synthesized } func resolveComponentReplicasRef(ctx context.Context, cli client.Reader, synthesizedComp *SynthesizedComponent, - defineKey string, selector appsv1alpha1.ComponentVarSelector) ([]*corev1.EnvVar, []*corev1.EnvVar, error) { + defineKey string, selector appsv1.ComponentVarSelector) ([]*corev1.EnvVar, []*corev1.EnvVar, error) { resolveReplicas := func(obj any) (*corev1.EnvVar, *corev1.EnvVar, error) { - comp := obj.(*appsv1alpha1.Component) + comp := obj.(*appsv1.Component) return &corev1.EnvVar{Name: defineKey, Value: strconv.Itoa(int(comp.Spec.Replicas))}, nil, nil } return resolveComponentVarRefLow(ctx, cli, synthesizedComp, selector, selector.Replicas, resolveReplicas) } func resolveComponentPodsRef(ctx context.Context, cli client.Reader, synthesizedComp *SynthesizedComponent, - defineKey string, selector appsv1alpha1.ComponentVarSelector) ([]*corev1.EnvVar, []*corev1.EnvVar, error) { + defineKey string, selector appsv1.ComponentVarSelector) ([]*corev1.EnvVar, []*corev1.EnvVar, error) { resolvePods := func(obj any) (*corev1.EnvVar, *corev1.EnvVar, error) { - comp := obj.(*appsv1alpha1.Component) + comp := obj.(*appsv1.Component) var templates []instanceset.InstanceTemplate for i := range comp.Spec.Instances { templates = append(templates, &comp.Spec.Instances[i]) @@ -1221,12 +1220,12 @@ func resolveComponentPodsRef(ctx context.Context, cli client.Reader, synthesized } func resolveComponentPodsForRoleRef(ctx context.Context, cli client.Reader, synthesizedComp *SynthesizedComponent, - defineKey string, selector appsv1alpha1.ComponentVarSelector) ([]*corev1.EnvVar, []*corev1.EnvVar, error) { + defineKey string, selector appsv1.ComponentVarSelector) ([]*corev1.EnvVar, []*corev1.EnvVar, error) { resolvePodsForRole := func(obj any) (*corev1.EnvVar, *corev1.EnvVar, error) { var ( namespace = synthesizedComp.Namespace clusterName = synthesizedComp.ClusterName - comp = obj.(*appsv1alpha1.Component) + comp = obj.(*appsv1.Component) compName, _ = ShortName(clusterName, comp.Name) ) pods, err := ListOwnedPods(ctx, cli, namespace, clusterName, compName) @@ -1269,14 +1268,14 @@ func resolveComponentPodsForRoleRef(ctx context.Context, cli client.Reader, synt } func resolveComponentVarRefLow(ctx context.Context, cli client.Reader, synthesizedComp *SynthesizedComponent, - selector appsv1alpha1.ComponentVarSelector, option *appsv1alpha1.VarOption, resolveVar func(any) (*corev1.EnvVar, *corev1.EnvVar, error)) ([]*corev1.EnvVar, []*corev1.EnvVar, error) { + selector appsv1.ComponentVarSelector, option *appsv1.VarOption, resolveVar func(any) (*corev1.EnvVar, *corev1.EnvVar, error)) ([]*corev1.EnvVar, []*corev1.EnvVar, error) { resolveObjs := func() (map[string]any, error) { getter := func(compName string) (any, error) { key := types.NamespacedName{ Namespace: synthesizedComp.Namespace, Name: constant.GenerateClusterComponentName(synthesizedComp.ClusterName, compName), } - obj := &appsv1alpha1.Component{} + obj := &appsv1.Component{} err := cli.Get(ctx, key, obj, inDataContext()) return obj, err } @@ -1286,7 +1285,7 @@ func resolveComponentVarRefLow(ctx context.Context, cli client.Reader, synthesiz } func resolveClusterVarRef(ctx context.Context, cli client.Reader, synthesizedComp *SynthesizedComponent, - defineKey string, selector appsv1alpha1.ClusterVarSelector) ([]corev1.EnvVar, []corev1.EnvVar, error) { + defineKey string, selector appsv1.ClusterVarSelector) ([]corev1.EnvVar, []corev1.EnvVar, error) { switch { case selector.Namespace != nil: return []corev1.EnvVar{{Name: defineKey, Value: synthesizedComp.Namespace}}, nil, nil @@ -1300,7 +1299,7 @@ func resolveClusterVarRef(ctx context.Context, cli client.Reader, synthesizedCom } func resolveReferentObjects(synthesizedComp *SynthesizedComponent, - objRef appsv1alpha1.ClusterObjectReference, getter func(string) (any, error)) (map[string]any, error) { + objRef appsv1.ClusterObjectReference, getter func(string) (any, error)) (map[string]any, error) { compNames, err := resolveReferentComponents(synthesizedComp, objRef) if err != nil { if apierrors.IsNotFound(err) { @@ -1324,7 +1323,7 @@ func resolveReferentObjects(synthesizedComp *SynthesizedComponent, return objs, nil } -func resolveReferentComponents(synthesizedComp *SynthesizedComponent, objRef appsv1alpha1.ClusterObjectReference) ([]string, error) { +func resolveReferentComponents(synthesizedComp *SynthesizedComponent, objRef appsv1.ClusterObjectReference) ([]string, error) { // nolint:gocritic compDefMatched := func(def, defRef string) bool { return strings.HasPrefix(def, defRef) // prefix match @@ -1355,13 +1354,13 @@ func resolveReferentComponents(synthesizedComp *SynthesizedComponent, objRef app } } -func resolveClusterObjectVars(kind string, objRef appsv1alpha1.ClusterObjectReference, option *appsv1alpha1.VarOption, +func resolveClusterObjectVars(kind string, objRef appsv1.ClusterObjectReference, option *appsv1.VarOption, resolveObjs func() (map[string]any, error), resolveVar func(any) (*corev1.EnvVar, *corev1.EnvVar, error)) ([]*corev1.EnvVar, []*corev1.EnvVar, error) { objOptional := func() bool { return objRef.Optional != nil && *objRef.Optional } varOptional := func() bool { - return option != nil && *option == appsv1alpha1.VarOptional + return option != nil && *option == appsv1.VarOptional } objs, err := resolveObjs() @@ -1398,13 +1397,13 @@ func resolveClusterObjectVars(kind string, objRef appsv1alpha1.ClusterObjectRefe return handleMultipleClusterObjectVars(objRef, vars1, vars2) } -func handleMultipleClusterObjectVars(objRef appsv1alpha1.ClusterObjectReference, +func handleMultipleClusterObjectVars(objRef appsv1.ClusterObjectReference, vars1 map[string]*corev1.EnvVar, vars2 map[string]*corev1.EnvVar) ([]*corev1.EnvVar, []*corev1.EnvVar, error) { strategy := objRef.MultipleClusterObjectOption.Strategy switch strategy { - case appsv1alpha1.MultipleClusterObjectStrategyIndividual: + case appsv1.MultipleClusterObjectStrategyIndividual: return handleMultipleClusterObjectVarsIndividual(vars1, vars2) - case appsv1alpha1.MultipleClusterObjectStrategyCombined: + case appsv1.MultipleClusterObjectStrategyCombined: return handleMultipleClusterObjectVarsCombined(objRef, vars1, vars2) default: return nil, nil, fmt.Errorf("unknown multiple cluster objects strategy: %s", strategy) @@ -1438,7 +1437,7 @@ func handleMultipleClusterObjectVarsIndividual(vars1, vars2 map[string]*corev1.E return buildIndividualVars(vars1), buildIndividualVars(vars2), nil } -func handleMultipleClusterObjectVarsCombined(objRef appsv1alpha1.ClusterObjectReference, +func handleMultipleClusterObjectVarsCombined(objRef appsv1.ClusterObjectReference, vars1, vars2 map[string]*corev1.EnvVar) ([]*corev1.EnvVar, []*corev1.EnvVar, error) { value1, value2, err := multipleClusterObjectVarsCombinedValue(objRef, vars1, vars2) if err != nil { @@ -1471,7 +1470,7 @@ func handleMultipleClusterObjectVarsCombined(objRef appsv1alpha1.ClusterObjectRe return combinedVars(vars1, value1), combinedVars(vars2, value2), nil } -func multipleClusterObjectVarsCombinedValue(objRef appsv1alpha1.ClusterObjectReference, +func multipleClusterObjectVarsCombinedValue(objRef appsv1.ClusterObjectReference, vars1, vars2 map[string]*corev1.EnvVar) (*string, *string, error) { var ( pairDelimiter = "," diff --git a/pkg/controller/component/vars_test.go b/pkg/controller/component/vars_test.go index 4d98b153dcb..66468f3f8b1 100644 --- a/pkg/controller/component/vars_test.go +++ b/pkg/controller/component/vars_test.go @@ -187,7 +187,7 @@ var _ = Describe("vars", func() { }) It("TLS env vars", func() { - synthesizedComp.TLSConfig = &appsv1alpha1.TLSConfig{ + synthesizedComp.TLSConfig = &appsv1.TLSConfig{ Enable: true, } _, envVars, err := ResolveTemplateNEnvVars(testCtx.Ctx, testCtx.Cli, synthesizedComp, nil) @@ -402,7 +402,7 @@ var _ = Describe("vars", func() { Expect(err.Error()).Should(And(ContainSubstring("has no HostNetwork"), ContainSubstring("found when resolving vars"))) By("has no host-network enabled") - synthesizedComp.HostNetwork = &appsv1alpha1.HostNetwork{} + synthesizedComp.HostNetwork = &appsv1.HostNetwork{} _, _, err = ResolveTemplateNEnvVars(ctx, testCtx.Cli, synthesizedComp, vars) Expect(err).ShouldNot(Succeed()) Expect(err.Error()).Should(And(ContainSubstring("has no HostNetwork"), ContainSubstring("found when resolving vars"))) @@ -465,26 +465,26 @@ var _ = Describe("vars", func() { ) BeforeEach(func() { - comp := &appsv1alpha1.Component{ + comp := &appsv1.Component{ ObjectMeta: metav1.ObjectMeta{ Namespace: synthesizedComp.Namespace, Name: FullName(synthesizedComp.ClusterName, synthesizedComp.Name), }, - Spec: appsv1alpha1.ComponentSpec{ + Spec: appsv1.ComponentSpec{ CompDef: synthesizedComp.CompDefName, }, } - compDef := &appsv1alpha1.ComponentDefinition{ + compDef := &appsv1.ComponentDefinition{ ObjectMeta: metav1.ObjectMeta{ Name: synthesizedComp.CompDefName, }, - Spec: appsv1alpha1.ComponentDefinitionSpec{ - Services: []appsv1alpha1.ComponentService{}, + Spec: appsv1.ComponentDefinitionSpec{ + Services: []appsv1.ComponentService{}, }, } for _, name := range []string{"non-exist", "service", "service-wo-port-name", "pod-service", "lb", "advertised"} { - compDef.Spec.Services = append(compDef.Spec.Services, appsv1alpha1.ComponentService{ - Service: appsv1alpha1.Service{ + compDef.Spec.Services = append(compDef.Spec.Services, appsv1.ComponentService{ + Service: appsv1.Service{ Name: name, ServiceName: name, }, @@ -497,17 +497,17 @@ var _ = Describe("vars", func() { }) It("non-exist service - optional", func() { - vars := []appsv1alpha1.EnvVar{ + vars := []appsv1.EnvVar{ { Name: "non-exist-service-var", - ValueFrom: &appsv1alpha1.VarSource{ - ServiceVarRef: &appsv1alpha1.ServiceVarSelector{ - ClusterObjectReference: appsv1alpha1.ClusterObjectReference{ + ValueFrom: &appsv1.VarSource{ + ServiceVarRef: &appsv1.ServiceVarSelector{ + ClusterObjectReference: appsv1.ClusterObjectReference{ Name: "non-exist", Optional: optional(), }, - ServiceVars: appsv1alpha1.ServiceVars{ - Host: &appsv1alpha1.VarOptional, + ServiceVars: appsv1.ServiceVars{ + Host: &appsv1.VarOptional, }, }, }, @@ -520,17 +520,17 @@ var _ = Describe("vars", func() { }) It("non-exist service - required", func() { - vars := []appsv1alpha1.EnvVar{ + vars := []appsv1.EnvVar{ { Name: "non-exist-service-var", - ValueFrom: &appsv1alpha1.VarSource{ - ServiceVarRef: &appsv1alpha1.ServiceVarSelector{ - ClusterObjectReference: appsv1alpha1.ClusterObjectReference{ + ValueFrom: &appsv1.VarSource{ + ServiceVarRef: &appsv1.ServiceVarSelector{ + ClusterObjectReference: appsv1.ClusterObjectReference{ Name: "non-exist", Optional: required(), }, - ServiceVars: appsv1alpha1.ServiceVars{ - Host: &appsv1alpha1.VarRequired, + ServiceVars: appsv1.ServiceVars{ + Host: &appsv1.VarRequired, }, }, }, @@ -698,25 +698,25 @@ var _ = Describe("vars", func() { svcName := constant.GenerateComponentServiceName(synthesizedComp.ClusterName, synthesizedComp.Name, "quorum") svcPort := 3306 - compDef := reader.objs[1].(*appsv1alpha1.ComponentDefinition) - compDef.Spec.Services = append(compDef.Spec.Services, appsv1alpha1.ComponentService{ - Service: appsv1alpha1.Service{ + compDef := reader.objs[1].(*appsv1.ComponentDefinition) + compDef.Spec.Services = append(compDef.Spec.Services, appsv1.ComponentService{ + Service: appsv1.Service{ Name: "client", // name and service name are different ServiceName: "quorum", }, }) - vars := []appsv1alpha1.EnvVar{ + vars := []appsv1.EnvVar{ { Name: "service-host", - ValueFrom: &appsv1alpha1.VarSource{ - ServiceVarRef: &appsv1alpha1.ServiceVarSelector{ - ClusterObjectReference: appsv1alpha1.ClusterObjectReference{ + ValueFrom: &appsv1.VarSource{ + ServiceVarRef: &appsv1.ServiceVarSelector{ + ClusterObjectReference: appsv1.ClusterObjectReference{ Name: "client", // should use the service.name Optional: required(), }, - ServiceVars: appsv1alpha1.ServiceVars{ - Host: &appsv1alpha1.VarRequired, + ServiceVars: appsv1.ServiceVars{ + Host: &appsv1.VarRequired, }, }, }, @@ -1620,17 +1620,17 @@ var _ = Describe("vars", func() { Context("component vars", func() { It("non-exist component with optional", func() { - vars := []appsv1alpha1.EnvVar{ + vars := []appsv1.EnvVar{ { Name: "non-exist-component-var", - ValueFrom: &appsv1alpha1.VarSource{ - ComponentVarRef: &appsv1alpha1.ComponentVarSelector{ - ClusterObjectReference: appsv1alpha1.ClusterObjectReference{ + ValueFrom: &appsv1.VarSource{ + ComponentVarRef: &appsv1.ComponentVarSelector{ + ClusterObjectReference: appsv1.ClusterObjectReference{ Name: "non-exist", Optional: optional(), }, - ComponentVars: appsv1alpha1.ComponentVars{ - Replicas: &appsv1alpha1.VarOptional, + ComponentVars: appsv1.ComponentVars{ + Replicas: &appsv1.VarOptional, }, }, }, @@ -1643,17 +1643,17 @@ var _ = Describe("vars", func() { }) It("non-exist component with required", func() { - vars := []appsv1alpha1.EnvVar{ + vars := []appsv1.EnvVar{ { Name: "non-exist-component-var", - ValueFrom: &appsv1alpha1.VarSource{ - ComponentVarRef: &appsv1alpha1.ComponentVarSelector{ - ClusterObjectReference: appsv1alpha1.ClusterObjectReference{ + ValueFrom: &appsv1.VarSource{ + ComponentVarRef: &appsv1.ComponentVarSelector{ + ClusterObjectReference: appsv1.ClusterObjectReference{ Name: "non-exist", Optional: required(), }, - ComponentVars: appsv1alpha1.ComponentVars{ - Replicas: &appsv1alpha1.VarRequired, + ComponentVars: appsv1.ComponentVars{ + Replicas: &appsv1.VarRequired, }, }, }, @@ -1664,73 +1664,73 @@ var _ = Describe("vars", func() { }) It("ok", func() { - vars := []appsv1alpha1.EnvVar{ + vars := []appsv1.EnvVar{ { Name: "name", - ValueFrom: &appsv1alpha1.VarSource{ - ComponentVarRef: &appsv1alpha1.ComponentVarSelector{ - ClusterObjectReference: appsv1alpha1.ClusterObjectReference{ + ValueFrom: &appsv1.VarSource{ + ComponentVarRef: &appsv1.ComponentVarSelector{ + ClusterObjectReference: appsv1.ClusterObjectReference{ CompDef: synthesizedComp.CompDefName, Optional: required(), }, - ComponentVars: appsv1alpha1.ComponentVars{ - ComponentName: &appsv1alpha1.VarRequired, + ComponentVars: appsv1.ComponentVars{ + ComponentName: &appsv1.VarRequired, }, }, }, }, { Name: "shortName", - ValueFrom: &appsv1alpha1.VarSource{ - ComponentVarRef: &appsv1alpha1.ComponentVarSelector{ - ClusterObjectReference: appsv1alpha1.ClusterObjectReference{ + ValueFrom: &appsv1.VarSource{ + ComponentVarRef: &appsv1.ComponentVarSelector{ + ClusterObjectReference: appsv1.ClusterObjectReference{ CompDef: synthesizedComp.CompDefName, Optional: required(), }, - ComponentVars: appsv1alpha1.ComponentVars{ - ShortName: &appsv1alpha1.VarRequired, + ComponentVars: appsv1.ComponentVars{ + ShortName: &appsv1.VarRequired, }, }, }, }, { Name: "replicas", - ValueFrom: &appsv1alpha1.VarSource{ - ComponentVarRef: &appsv1alpha1.ComponentVarSelector{ - ClusterObjectReference: appsv1alpha1.ClusterObjectReference{ + ValueFrom: &appsv1.VarSource{ + ComponentVarRef: &appsv1.ComponentVarSelector{ + ClusterObjectReference: appsv1.ClusterObjectReference{ CompDef: synthesizedComp.CompDefName, Optional: required(), }, - ComponentVars: appsv1alpha1.ComponentVars{ - Replicas: &appsv1alpha1.VarRequired, + ComponentVars: appsv1.ComponentVars{ + Replicas: &appsv1.VarRequired, }, }, }, }, { Name: "podNames", - ValueFrom: &appsv1alpha1.VarSource{ - ComponentVarRef: &appsv1alpha1.ComponentVarSelector{ - ClusterObjectReference: appsv1alpha1.ClusterObjectReference{ + ValueFrom: &appsv1.VarSource{ + ComponentVarRef: &appsv1.ComponentVarSelector{ + ClusterObjectReference: appsv1.ClusterObjectReference{ CompDef: synthesizedComp.CompDefName, Optional: required(), }, - ComponentVars: appsv1alpha1.ComponentVars{ - PodNames: &appsv1alpha1.VarRequired, + ComponentVars: appsv1.ComponentVars{ + PodNames: &appsv1.VarRequired, }, }, }, }, { Name: "podFQDNs", - ValueFrom: &appsv1alpha1.VarSource{ - ComponentVarRef: &appsv1alpha1.ComponentVarSelector{ - ClusterObjectReference: appsv1alpha1.ClusterObjectReference{ + ValueFrom: &appsv1.VarSource{ + ComponentVarRef: &appsv1.ComponentVarSelector{ + ClusterObjectReference: appsv1.ClusterObjectReference{ CompDef: synthesizedComp.CompDefName, Optional: required(), }, - ComponentVars: appsv1alpha1.ComponentVars{ - PodFQDNs: &appsv1alpha1.VarRequired, + ComponentVars: appsv1.ComponentVars{ + PodFQDNs: &appsv1.VarRequired, }, }, }, @@ -1776,12 +1776,12 @@ var _ = Describe("vars", func() { reader := &mockReader{ cli: testCtx.Cli, objs: []client.Object{ - &appsv1alpha1.Component{ + &appsv1.Component{ ObjectMeta: metav1.ObjectMeta{ Namespace: testCtx.DefaultNamespace, Name: constant.GenerateClusterComponentName(synthesizedComp.ClusterName, synthesizedComp.Name), }, - Spec: appsv1alpha1.ComponentSpec{ + Spec: appsv1.ComponentSpec{ CompDef: synthesizedComp.CompDefName, Replicas: 3, }, @@ -1903,26 +1903,26 @@ var _ = Describe("vars", func() { ) BeforeEach(func() { - comp := &appsv1alpha1.Component{ + comp := &appsv1.Component{ ObjectMeta: metav1.ObjectMeta{ Namespace: synthesizedComp.Namespace, Name: FullName(synthesizedComp.ClusterName, synthesizedComp.Name), }, - Spec: appsv1alpha1.ComponentSpec{ + Spec: appsv1.ComponentSpec{ CompDef: synthesizedComp.CompDefName, }, } - compDef := &appsv1alpha1.ComponentDefinition{ + compDef := &appsv1.ComponentDefinition{ ObjectMeta: metav1.ObjectMeta{ Name: synthesizedComp.CompDefName, }, - Spec: appsv1alpha1.ComponentDefinitionSpec{ - Services: []appsv1alpha1.ComponentService{}, + Spec: appsv1.ComponentDefinitionSpec{ + Services: []appsv1.ComponentService{}, }, } for _, name := range []string{"service"} { - compDef.Spec.Services = append(compDef.Spec.Services, appsv1alpha1.ComponentService{ - Service: appsv1alpha1.Service{ + compDef.Spec.Services = append(compDef.Spec.Services, appsv1.ComponentService{ + Service: appsv1.Service{ Name: name, ServiceName: name, }, @@ -2117,26 +2117,26 @@ var _ = Describe("vars", func() { } for _, name := range []string{compName1, compName2, compName3} { - comp := &appsv1alpha1.Component{ + comp := &appsv1.Component{ ObjectMeta: metav1.ObjectMeta{ Namespace: synthesizedComp.Namespace, Name: FullName(synthesizedComp.ClusterName, name), }, - Spec: appsv1alpha1.ComponentSpec{ + Spec: appsv1.ComponentSpec{ CompDef: synthesizedComp.CompDefName, }, } - compDef := &appsv1alpha1.ComponentDefinition{ + compDef := &appsv1.ComponentDefinition{ ObjectMeta: metav1.ObjectMeta{ Name: synthesizedComp.CompDefName, }, - Spec: appsv1alpha1.ComponentDefinitionSpec{ - Services: []appsv1alpha1.ComponentService{}, + Spec: appsv1.ComponentDefinitionSpec{ + Services: []appsv1.ComponentService{}, }, } for _, name := range []string{"service", svcName1, svcName2} { - compDef.Spec.Services = append(compDef.Spec.Services, appsv1alpha1.ComponentService{ - Service: appsv1alpha1.Service{ + compDef.Spec.Services = append(compDef.Spec.Services, appsv1.ComponentService{ + Service: appsv1.Service{ Name: name, ServiceName: name, }, @@ -2147,18 +2147,18 @@ var _ = Describe("vars", func() { }) It("w/o option - ref self", func() { - vars := []appsv1alpha1.EnvVar{ + vars := []appsv1.EnvVar{ { Name: "service-host", - ValueFrom: &appsv1alpha1.VarSource{ - ServiceVarRef: &appsv1alpha1.ServiceVarSelector{ - ClusterObjectReference: appsv1alpha1.ClusterObjectReference{ + ValueFrom: &appsv1.VarSource{ + ServiceVarRef: &appsv1.ServiceVarSelector{ + ClusterObjectReference: appsv1.ClusterObjectReference{ CompDef: synthesizedComp.CompDefName, // same as synthesizedComp Name: "service", Optional: required(), }, - ServiceVars: appsv1alpha1.ServiceVars{ - Host: &appsv1alpha1.VarRequired, + ServiceVars: appsv1.ServiceVars{ + Host: &appsv1.VarRequired, }, }, }, diff --git a/pkg/controller/component/workload_utils.go b/pkg/controller/component/workload_utils.go index 8e5b15e3de7..8204adf5d34 100644 --- a/pkg/controller/component/workload_utils.go +++ b/pkg/controller/component/workload_utils.go @@ -22,6 +22,7 @@ package component import ( "context" "fmt" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" "maps" "reflect" "strconv" @@ -129,7 +130,7 @@ func listObjWithLabelsInNamespace[T generics.Object, PT generics.PObject[T], L g // GenerateAllPodNames generate all pod names for a component. func GenerateAllPodNames( compReplicas int32, - instances []appsv1alpha1.InstanceTemplate, + instances []appsv1.InstanceTemplate, offlineInstances []string, clusterName, fullCompName string) ([]string, error) { @@ -145,7 +146,7 @@ func GenerateAllPodNames( // and return a set which key is the pod name and value is a template name. func GenerateAllPodNamesToSet( compReplicas int32, - instances []appsv1alpha1.InstanceTemplate, + instances []appsv1.InstanceTemplate, offlineInstances []string, clusterName, fullCompName string) (map[string]string, error) { diff --git a/pkg/controller/configuration/annotation_utils.go b/pkg/controller/configuration/annotation_utils.go index 067a4536f5c..a014293cb63 100644 --- a/pkg/controller/configuration/annotation_utils.go +++ b/pkg/controller/configuration/annotation_utils.go @@ -21,7 +21,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" "github.com/apecloud/kubeblocks/pkg/configuration/core" cfgutil "github.com/apecloud/kubeblocks/pkg/configuration/util" "github.com/apecloud/kubeblocks/pkg/constant" @@ -29,7 +29,7 @@ import ( ) // BuildConfigConstraintLabels builds config constraints labels for object -func BuildConfigConstraintLabels(object client.Object, configSpecs []appsv1alpha1.ComponentConfigSpec) { +func BuildConfigConstraintLabels(object client.Object, configSpecs []appsv1.ComponentConfigSpec) { asMapLabels := make(map[string]string) for _, configSpec := range configSpecs { asMapLabels[core.GenerateTPLUniqLabelKeyWithConfig(configSpec.Name)] = configSpec.TemplateRef diff --git a/pkg/controller/configuration/config_utils.go b/pkg/controller/configuration/config_utils.go index d58f8a4426f..d7dd8976dd0 100644 --- a/pkg/controller/configuration/config_utils.go +++ b/pkg/controller/configuration/config_utils.go @@ -30,6 +30,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/log" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" cfgcm "github.com/apecloud/kubeblocks/pkg/configuration/config_manager" "github.com/apecloud/kubeblocks/pkg/configuration/core" @@ -61,7 +62,7 @@ func createConfigObjects(cli client.Client, ctx context.Context, objs []client.O // buildConfigManagerWithComponent build the configmgr sidecar container and update it // into PodSpec if configuration reload option is on -func buildConfigManagerWithComponent(podSpec *corev1.PodSpec, configSpecs []appsv1alpha1.ComponentConfigSpec, +func buildConfigManagerWithComponent(podSpec *corev1.PodSpec, configSpecs []appsv1.ComponentConfigSpec, ctx context.Context, cli client.Client, cluster *appsv1alpha1.Cluster, synthesizedComp *component.SynthesizedComponent) error { var err error var buildParams *cfgcm.CfgManagerBuildParams @@ -165,9 +166,9 @@ func updateCfgManagerVolumes(podSpec *corev1.PodSpec, configManager *cfgcm.CfgMa } } -func getUsingVolumesByConfigSpecs(podSpec *corev1.PodSpec, configSpecs []appsv1alpha1.ComponentConfigSpec) ([]corev1.VolumeMount, []appsv1alpha1.ComponentConfigSpec) { +func getUsingVolumesByConfigSpecs(podSpec *corev1.PodSpec, configSpecs []appsv1.ComponentConfigSpec) ([]corev1.VolumeMount, []appsv1.ComponentConfigSpec) { // Ignore useless configTemplate - usingConfigSpecs := make([]appsv1alpha1.ComponentConfigSpec, 0, len(configSpecs)) + usingConfigSpecs := make([]appsv1.ComponentConfigSpec, 0, len(configSpecs)) config2Containers := make(map[string][]*corev1.Container) for _, configSpec := range configSpecs { usingContainers := intctrlutil.GetPodContainerWithVolumeMount(podSpec, configSpec.VolumeName) @@ -301,7 +302,7 @@ func enableVScaleTrigger(configSpec *appsv1alpha1.ComponentConfigSpec) bool { return validRerenderResources(configSpec) && slices.Contains(configSpec.ReRenderResourceTypes, appsv1alpha1.ComponentVScaleType) } -func configSetFromComponent(templates []appsv1alpha1.ComponentConfigSpec) []string { +func configSetFromComponent(templates []appsv1.ComponentConfigSpec) []string { configSet := make([]string, 0) for _, template := range templates { configSet = append(configSet, template.Name) diff --git a/pkg/controller/configuration/configuration_test.go b/pkg/controller/configuration/configuration_test.go index 6b69c1c505c..253438d1377 100644 --- a/pkg/controller/configuration/configuration_test.go +++ b/pkg/controller/configuration/configuration_test.go @@ -28,6 +28,7 @@ import ( "k8s.io/apimachinery/pkg/types" "sigs.k8s.io/controller-runtime/pkg/client" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" "github.com/apecloud/kubeblocks/pkg/controller/component" intctrlutil "github.com/apecloud/kubeblocks/pkg/controllerutil" @@ -46,7 +47,7 @@ const ( testConfigContent = "test-config-content" ) -func allFieldsCompDefObj(create bool) *appsv1alpha1.ComponentDefinition { +func allFieldsCompDefObj(create bool) *appsv1.ComponentDefinition { compDef := testapps.NewComponentDefinitionFactory(compDefName). SetDefaultSpec(). AddConfigTemplate(configTemplateName, mysqlConfigName, mysqlConfigConstraintName, testCtx.DefaultNamespace, testapps.ConfVolumeName). @@ -58,7 +59,7 @@ func allFieldsCompDefObj(create bool) *appsv1alpha1.ComponentDefinition { return compDef } -func newAllFieldsClusterObj(compDef *appsv1alpha1.ComponentDefinition, create bool) (*appsv1alpha1.Cluster, *appsv1alpha1.ComponentDefinition, types.NamespacedName) { +func newAllFieldsClusterObj(compDef *appsv1.ComponentDefinition, create bool) (*appsv1alpha1.Cluster, *appsv1.ComponentDefinition, types.NamespacedName) { // setup Cluster obj requires default ComponentDefinition object if compDef == nil { compDef = allFieldsCompDefObj(create) @@ -78,7 +79,7 @@ func newAllFieldsClusterObj(compDef *appsv1alpha1.ComponentDefinition, create bo return clusterObj, compDef, key } -func newAllFieldsSynthesizedComponent(compDef *appsv1alpha1.ComponentDefinition, cluster *appsv1alpha1.Cluster) *component.SynthesizedComponent { +func newAllFieldsSynthesizedComponent(compDef *appsv1.ComponentDefinition, cluster *appsv1alpha1.Cluster) *component.SynthesizedComponent { reqCtx := intctrlutil.RequestCtx{ Ctx: testCtx.Ctx, Log: logger, @@ -93,12 +94,12 @@ func newAllFieldsSynthesizedComponent(compDef *appsv1alpha1.ComponentDefinition, addTestVolumeMount(synthesizeComp.PodSpec, mysqlCompName) if len(synthesizeComp.ConfigTemplates) > 0 { configSpec := &synthesizeComp.ConfigTemplates[0] - configSpec.ReRenderResourceTypes = []appsv1alpha1.RerenderResourceType{appsv1alpha1.ComponentVScaleType, appsv1alpha1.ComponentHScaleType} + configSpec.ReRenderResourceTypes = []appsv1.RerenderResourceType{appsv1.ComponentVScaleType, appsv1.ComponentHScaleType} } return synthesizeComp } -func newAllFieldsComponent(cluster *appsv1alpha1.Cluster) *appsv1alpha1.Component { +func newAllFieldsComponent(cluster *appsv1alpha1.Cluster) *appsv1.Component { comp, _ := component.BuildComponent(cluster, &cluster.Spec.ComponentSpecs[0], nil, nil) return comp } diff --git a/pkg/controller/configuration/envfrom_utils.go b/pkg/controller/configuration/envfrom_utils.go index 102b43dd890..f1fb66bfcfc 100644 --- a/pkg/controller/configuration/envfrom_utils.go +++ b/pkg/controller/configuration/envfrom_utils.go @@ -27,6 +27,7 @@ import ( apierrors "k8s.io/apimachinery/pkg/api/errors" "sigs.k8s.io/controller-runtime/pkg/client" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" appsv1beta1 "github.com/apecloud/kubeblocks/apis/apps/v1beta1" "github.com/apecloud/kubeblocks/pkg/configuration/core" @@ -42,18 +43,18 @@ func injectTemplateEnvFrom(cluster *appsv1alpha1.Cluster, component *component.S var err error var cm *corev1.ConfigMap - injectConfigmap := func(envMap map[string]string, configSpec appsv1alpha1.ComponentConfigSpec, cmName string) error { + injectConfigmap := func(envMap map[string]string, configSpec appsv1.ComponentConfigSpec, cmName string) error { envConfigMap, err := createEnvFromConfigmap(cluster, component.Name, configSpec, client.ObjectKeyFromObject(cm), envMap, ctx, cli) if err != nil { return core.WrapError(err, "failed to generate env configmap[%s]", cmName) } - injectEnvFrom(podSpec.Containers, configSpec.ContainersInjectedTo(), envConfigMap.Name) - injectEnvFrom(podSpec.InitContainers, configSpec.ContainersInjectedTo(), envConfigMap.Name) + injectEnvFrom(podSpec.Containers, containersInjectedTo(configSpec), envConfigMap.Name) + injectEnvFrom(podSpec.InitContainers, containersInjectedTo(configSpec), envConfigMap.Name) return nil } for _, template := range component.ConfigTemplates { - if !template.InjectEnvEnabled() || template.ConfigConstraintRef == "" { + if !InjectEnvEnabled(template) || template.ConfigConstraintRef == "" { continue } cmName := core.GetComponentCfgName(cluster.Name, component.Name, template.Name) @@ -78,7 +79,7 @@ func injectTemplateEnvFrom(cluster *appsv1alpha1.Cluster, component *component.S return nil } -func getConfigConstraint(template appsv1alpha1.ComponentConfigSpec, cli client.Client, ctx context.Context) (*appsv1beta1.ConfigConstraintSpec, error) { +func getConfigConstraint(template appsv1.ComponentConfigSpec, cli client.Client, ctx context.Context) (*appsv1beta1.ConfigConstraintSpec, error) { ccKey := client.ObjectKey{ Namespace: "", Name: template.ConfigConstraintRef, @@ -127,7 +128,7 @@ func fetchConfigmap(localObjs []client.Object, cmName, namespace string, cli cli return cmObj, nil } -func createEnvFromConfigmap(cluster *appsv1alpha1.Cluster, componentName string, template appsv1alpha1.ComponentConfigSpec, originKey client.ObjectKey, envMap map[string]string, ctx context.Context, cli client.Client) (*corev1.ConfigMap, error) { +func createEnvFromConfigmap(cluster *appsv1alpha1.Cluster, componentName string, template appsv1.ComponentConfigSpec, originKey client.ObjectKey, envMap map[string]string, ctx context.Context, cli client.Client) (*corev1.ConfigMap, error) { cmKey := client.ObjectKey{ Name: core.GenerateEnvFromName(originKey.Name), Namespace: originKey.Namespace, @@ -188,7 +189,7 @@ func fromFileContent(format *appsv1beta1.FileFormatConfig, configContext string) return envMap, nil } -func fromConfigSpec(configSpec appsv1alpha1.ComponentConfigSpec, cm *corev1.ConfigMap) []string { +func fromConfigSpec(configSpec appsv1.ComponentConfigSpec, cm *corev1.ConfigMap) []string { keys := configSpec.Keys if len(keys) == 0 { keys = cfgutil.ToSet(cm.Data).AsSlice() @@ -196,8 +197,8 @@ func fromConfigSpec(configSpec appsv1alpha1.ComponentConfigSpec, cm *corev1.Conf return keys } -func SyncEnvConfigmap(configSpec appsv1alpha1.ComponentConfigSpec, cmObj *corev1.ConfigMap, cc *appsv1beta1.ConfigConstraintSpec, cli client.Client, ctx context.Context) error { - if !configSpec.InjectEnvEnabled() || cc == nil || cc.FileFormatConfig == nil { +func SyncEnvConfigmap(configSpec appsv1.ComponentConfigSpec, cmObj *corev1.ConfigMap, cc *appsv1beta1.ConfigConstraintSpec, cli client.Client, ctx context.Context) error { + if !InjectEnvEnabled(configSpec) || cc == nil || cc.FileFormatConfig == nil { return nil } envMap, err := fromConfigmapFiles(fromConfigSpec(configSpec, cmObj), cmObj, cc.FileFormatConfig) @@ -228,3 +229,14 @@ func updateEnvFromConfigmap(origObj client.ObjectKey, envMap map[string]string, } return nil } + +func InjectEnvEnabled(spec appsv1.ComponentConfigSpec) bool { + return len(spec.AsEnvFrom) > 0 || len(spec.InjectEnvTo) > 0 +} + +func containersInjectedTo(spec appsv1.ComponentConfigSpec) []string { + if len(spec.InjectEnvTo) != 0 { + return spec.InjectEnvTo + } + return spec.AsEnvFrom +} diff --git a/pkg/controller/configuration/envfrom_utils_test.go b/pkg/controller/configuration/envfrom_utils_test.go index 9e2d94fc18b..4b5e0c581bc 100644 --- a/pkg/controller/configuration/envfrom_utils_test.go +++ b/pkg/controller/configuration/envfrom_utils_test.go @@ -26,6 +26,7 @@ import ( corev1 "k8s.io/api/core/v1" "sigs.k8s.io/controller-runtime/pkg/client" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" appsv1beta1 "github.com/apecloud/kubeblocks/apis/apps/v1beta1" "github.com/apecloud/kubeblocks/pkg/configuration/core" @@ -43,7 +44,7 @@ var _ = Describe("ConfigEnvFrom test", func() { ) var ( - compDef *appsv1alpha1.ComponentDefinition + compDef *appsv1.ComponentDefinition cluster *appsv1alpha1.Cluster k8sMockClient *testutil.K8sClientMockHelper diff --git a/pkg/controller/configuration/operator.go b/pkg/controller/configuration/operator.go index 1cbffd7bf9c..863f818fee8 100644 --- a/pkg/controller/configuration/operator.go +++ b/pkg/controller/configuration/operator.go @@ -23,6 +23,7 @@ import ( corev1 "k8s.io/api/core/v1" "sigs.k8s.io/controller-runtime/pkg/client" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" "github.com/apecloud/kubeblocks/pkg/controller/component" ) @@ -33,7 +34,7 @@ type configOperator struct { func NewConfigReconcileTask(resourceCtx *ResourceCtx, cluster *appsv1alpha1.Cluster, - component *appsv1alpha1.Component, + component *appsv1.Component, synthesizedComponent *component.SynthesizedComponent, podSpec *corev1.PodSpec, localObjs []client.Object, @@ -59,11 +60,11 @@ func (c *configOperator) Reconcile() error { return NewCreatePipeline(c.ReconcileCtx). Prepare(). - RenderScriptTemplate(). // render scriptTemplate into ConfigMap - UpdateConfiguration(). // create or update Configuration - Configuration(). // fetch the latest Configuration - CreateConfigTemplate(). // render configTemplate into ConfigMap (only for the first time) - UpdatePodVolumes(). // update podSpec.Volumes + RenderScriptTemplate(). // render scriptTemplate into ConfigMap + UpdateConfiguration(). // create or update Configuration + Configuration(). // fetch the latest Configuration + CreateConfigTemplate(). // render configTemplate into ConfigMap (only for the first time) + UpdatePodVolumes(). // update podSpec.Volumes BuildConfigManagerSidecar(). // build configManager sidecar and update podSpec.Containers and podSpec.InitContainers UpdateConfigRelatedObject(). // handle InjectEnvTo, and create or update ConfigMaps UpdateConfigurationStatus(). // update ConfigurationItemStatus revision and phase etc. diff --git a/pkg/controller/configuration/operator_test.go b/pkg/controller/configuration/operator_test.go index 147c74790e7..07a23dbbd58 100644 --- a/pkg/controller/configuration/operator_test.go +++ b/pkg/controller/configuration/operator_test.go @@ -28,6 +28,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/client" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" appsv1beta1 "github.com/apecloud/kubeblocks/apis/apps/v1beta1" cfgcore "github.com/apecloud/kubeblocks/pkg/configuration/core" @@ -40,8 +41,8 @@ import ( var _ = Describe("ConfigurationOperatorTest", func() { var clusterObj *appsv1alpha1.Cluster - var compDefObj *appsv1alpha1.ComponentDefinition - var componentObj *appsv1alpha1.Component + var compDefObj *appsv1.ComponentDefinition + var componentObj *appsv1.Component var synthesizedComponent *component.SynthesizedComponent var configMapObj *corev1.ConfigMap var scriptsObj *corev1.ConfigMap diff --git a/pkg/controller/configuration/patch_merger.go b/pkg/controller/configuration/patch_merger.go index e648930b585..d71e94f8396 100644 --- a/pkg/controller/configuration/patch_merger.go +++ b/pkg/controller/configuration/patch_merger.go @@ -20,13 +20,14 @@ along with this program. If not, see . package configuration import ( + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" appsv1beta1 "github.com/apecloud/kubeblocks/apis/apps/v1beta1" "github.com/apecloud/kubeblocks/pkg/configuration/core" intctrlutil "github.com/apecloud/kubeblocks/pkg/controllerutil" ) -func DoMerge(baseData map[string]string, patch map[string]appsv1alpha1.ConfigParams, cc *appsv1beta1.ConfigConstraint, configSpec appsv1alpha1.ComponentConfigSpec) (map[string]string, error) { +func DoMerge(baseData map[string]string, patch map[string]appsv1alpha1.ConfigParams, cc *appsv1beta1.ConfigConstraint, configSpec appsv1.ComponentConfigSpec) (map[string]string, error) { var ( updatedFiles = make(map[string]string, len(patch)) updatedParams = make([]core.ParamPairs, 0, len(patch)) @@ -50,7 +51,7 @@ func mergeUpdatedParams(base map[string]string, updatedFiles map[string]string, updatedParams []core.ParamPairs, cc *appsv1beta1.ConfigConstraint, - tpl appsv1alpha1.ComponentConfigSpec) (map[string]string, error) { + tpl appsv1.ComponentConfigSpec) (map[string]string, error) { updatedConfig := base // merge updated files into configmap diff --git a/pkg/controller/configuration/pipeline.go b/pkg/controller/configuration/pipeline.go index ace142b2d84..42ff08f03ba 100644 --- a/pkg/controller/configuration/pipeline.go +++ b/pkg/controller/configuration/pipeline.go @@ -26,6 +26,7 @@ import ( apierrors "k8s.io/apimachinery/pkg/api/errors" "sigs.k8s.io/controller-runtime/pkg/client" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" "github.com/apecloud/kubeblocks/pkg/configuration/core" cfgutil "github.com/apecloud/kubeblocks/pkg/configuration/util" @@ -39,7 +40,7 @@ type ReconcileCtx struct { *ResourceCtx Cluster *appsv1alpha1.Cluster - Component *appsv1alpha1.Component + Component *appsv1.Component SynthesizedComponent *component.SynthesizedComponent PodSpec *corev1.PodSpec @@ -60,7 +61,7 @@ type updatePipeline struct { item appsv1alpha1.ConfigurationItemDetail itemStatus *appsv1alpha1.ConfigurationItemDetailStatus - configSpec *appsv1alpha1.ComponentConfigSpec + configSpec *appsv1.ComponentConfigSpec // replace of ConfigMapObj // originalCM *corev1.ConfigMap newCM *corev1.ConfigMap @@ -75,7 +76,7 @@ func NewCreatePipeline(ctx ReconcileCtx) *pipeline { return p.Init(ctx.ResourceCtx, p) } -func NewReconcilePipeline(ctx ReconcileCtx, item appsv1alpha1.ConfigurationItemDetail, itemStatus *appsv1alpha1.ConfigurationItemDetailStatus, configSpec *appsv1alpha1.ComponentConfigSpec) *updatePipeline { +func NewReconcilePipeline(ctx ReconcileCtx, item appsv1alpha1.ConfigurationItemDetail, itemStatus *appsv1alpha1.ConfigurationItemDetailStatus, configSpec *appsv1.ComponentConfigSpec) *updatePipeline { p := &updatePipeline{ reconcile: true, item: item, @@ -274,7 +275,7 @@ func (p *updatePipeline) PrepareForTemplate() *updatePipeline { return p.Wrap(buildTemplate) } -func (p *updatePipeline) ConfigSpec() *appsv1alpha1.ComponentConfigSpec { +func (p *updatePipeline) ConfigSpec() *appsv1.ComponentConfigSpec { return p.configSpec } @@ -305,7 +306,7 @@ func (p *updatePipeline) RerenderTemplate() *updatePipeline { } func (p *updatePipeline) ApplyParameters() *updatePipeline { - patchMerge := func(p *updatePipeline, spec appsv1alpha1.ComponentConfigSpec, cm *corev1.ConfigMap, item appsv1alpha1.ConfigurationItemDetail) error { + patchMerge := func(p *updatePipeline, spec appsv1.ComponentConfigSpec, cm *corev1.ConfigMap, item appsv1alpha1.ConfigurationItemDetail) error { if p.isDone() || len(item.ConfigFileParams) == 0 { return nil } diff --git a/pkg/controller/configuration/pipeline_test.go b/pkg/controller/configuration/pipeline_test.go index 40a99f2f783..f41dfd0d4fd 100644 --- a/pkg/controller/configuration/pipeline_test.go +++ b/pkg/controller/configuration/pipeline_test.go @@ -31,6 +31,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/client" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" appsv1beta1 "github.com/apecloud/kubeblocks/apis/apps/v1beta1" cfgcore "github.com/apecloud/kubeblocks/pkg/configuration/core" @@ -45,8 +46,8 @@ var _ = Describe("ConfigurationPipelineTest", func() { const testConfigFile = "postgresql.conf" var clusterObj *appsv1alpha1.Cluster - var componentObj *appsv1alpha1.Component - var compDefObj *appsv1alpha1.ComponentDefinition + var componentObj *appsv1.Component + var compDefObj *appsv1.ComponentDefinition var synthesizedComponent *component.SynthesizedComponent var configMapObj *corev1.ConfigMap var configConstraint *appsv1beta1.ConfigConstraint diff --git a/pkg/controller/configuration/resource_wrapper.go b/pkg/controller/configuration/resource_wrapper.go index 0dd0f4bd944..f00feae5ba7 100644 --- a/pkg/controller/configuration/resource_wrapper.go +++ b/pkg/controller/configuration/resource_wrapper.go @@ -28,6 +28,7 @@ import ( "k8s.io/apimachinery/pkg/types" "sigs.k8s.io/controller-runtime/pkg/client" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" appsv1beta1 "github.com/apecloud/kubeblocks/apis/apps/v1beta1" cfgcore "github.com/apecloud/kubeblocks/pkg/configuration/core" @@ -51,12 +52,12 @@ type ResourceFetcher[T any] struct { *ResourceCtx ClusterObj *appsv1alpha1.Cluster - ComponentObj *appsv1alpha1.Component - ComponentDefObj *appsv1alpha1.ComponentDefinition + ComponentObj *appsv1.Component + ComponentDefObj *appsv1.ComponentDefinition ClusterComObj *appsv1alpha1.ClusterComponentSpec // Deprecated: this API will be removed from version 0.9.0 - ClusterDefObj *appsv1alpha1.ClusterDefinition + ClusterDefObj *appsv1.ClusterDefinition ConfigMapObj *corev1.ConfigMap ConfigurationObj *appsv1alpha1.Configuration @@ -95,7 +96,7 @@ func (r *ResourceFetcher[T]) ComponentAndComponentDef() *T { Name: constant.GenerateClusterComponentName(r.ClusterName, r.ComponentName), } return r.Wrap(func() error { - r.ComponentObj = &appsv1alpha1.Component{} + r.ComponentObj = &appsv1.Component{} err := r.Client.Get(r.Context, componentKey, r.ComponentObj) if apierrors.IsNotFound(err) { return nil @@ -110,11 +111,11 @@ func (r *ResourceFetcher[T]) ComponentAndComponentDef() *T { compDefKey := types.NamespacedName{ Name: r.ComponentObj.Spec.CompDef, } - r.ComponentDefObj = &appsv1alpha1.ComponentDefinition{} + r.ComponentDefObj = &appsv1.ComponentDefinition{} if err := r.Client.Get(r.Context, compDefKey, r.ComponentDefObj); err != nil { return err } - if r.ComponentDefObj.Status.Phase != appsv1alpha1.AvailablePhase { + if r.ComponentDefObj.Status.Phase != appsv1.AvailablePhase { return fmt.Errorf("ComponentDefinition referenced is unavailable: %s", r.ComponentDefObj.Name) } return nil @@ -129,7 +130,7 @@ func (r *ResourceFetcher[T]) ClusterDef() *T { Name: r.ClusterObj.Spec.ClusterDefRef, } return r.Wrap(func() error { - r.ClusterDefObj = &appsv1alpha1.ClusterDefinition{} + r.ClusterDefObj = &appsv1.ClusterDefinition{} return r.Client.Get(r.Context, clusterDefKey, r.ClusterDefObj) }) } diff --git a/pkg/controller/configuration/template_merger.go b/pkg/controller/configuration/template_merger.go index b26b30a032c..cbfd9c2a8bf 100644 --- a/pkg/controller/configuration/template_merger.go +++ b/pkg/controller/configuration/template_merger.go @@ -24,6 +24,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" appsv1beta1 "github.com/apecloud/kubeblocks/apis/apps/v1beta1" "github.com/apecloud/kubeblocks/pkg/configuration/core" @@ -39,8 +40,8 @@ type TemplateMerger interface { } type mergeContext struct { - template appsv1alpha1.ConfigTemplateExtension - configSpec appsv1alpha1.ComponentConfigSpec + template appsv1.ConfigTemplateExtension + configSpec appsv1.ComponentConfigSpec ccSpec *appsv1beta1.ConfigConstraintSpec builder *configTemplateBuilder @@ -119,7 +120,7 @@ func (c *configOnlyAddMerger) Merge(baseData map[string]string, updatedData map[ return nil, core.MakeError("not implemented") } -func NewTemplateMerger(template appsv1alpha1.ConfigTemplateExtension, ctx context.Context, cli client.Client, builder *configTemplateBuilder, configSpec appsv1alpha1.ComponentConfigSpec, ccSpec *appsv1beta1.ConfigConstraintSpec) (TemplateMerger, error) { +func NewTemplateMerger(template appsv1.ConfigTemplateExtension, ctx context.Context, cli client.Client, builder *configTemplateBuilder, configSpec appsv1.ComponentConfigSpec, ccSpec *appsv1beta1.ConfigConstraintSpec) (TemplateMerger, error) { templateData := &mergeContext{ configSpec: configSpec, template: template, @@ -147,7 +148,7 @@ func NewTemplateMerger(template appsv1alpha1.ConfigTemplateExtension, ctx contex func mergerConfigTemplate(template *appsv1alpha1.LegacyRenderedTemplateSpec, builder *configTemplateBuilder, - configSpec appsv1alpha1.ComponentConfigSpec, + configSpec appsv1.ComponentConfigSpec, baseData map[string]string, ctx context.Context, cli client.Client) (map[string]string, error) { if configSpec.ConfigConstraintRef == "" { diff --git a/pkg/controller/configuration/template_merger_test.go b/pkg/controller/configuration/template_merger_test.go index 5077b471397..35cffe27fb7 100644 --- a/pkg/controller/configuration/template_merger_test.go +++ b/pkg/controller/configuration/template_merger_test.go @@ -29,6 +29,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/client" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" appsv1beta1 "github.com/apecloud/kubeblocks/apis/apps/v1beta1" cfgcore "github.com/apecloud/kubeblocks/pkg/configuration/core" @@ -72,7 +73,7 @@ max_connections=666 var ( mockClient *testutil.K8sClientMockHelper templateBuilder *configTemplateBuilder - configSpec appsv1alpha1.ComponentConfigSpec + configSpec appsv1.ComponentConfigSpec configConstraintObj *appsv1beta1.ConfigConstraint baseCMObject *corev1.ConfigMap @@ -101,8 +102,8 @@ max_connections=666 updatedCMObject.SetName(updatedCMName) updatedCMObject.SetNamespace("default") - configSpec = appsv1alpha1.ComponentConfigSpec{ - ComponentTemplateSpec: appsv1alpha1.ComponentTemplateSpec{ + configSpec = appsv1.ComponentConfigSpec{ + ComponentTemplateSpec: appsv1.ComponentTemplateSpec{ Name: testConfigSpecName, TemplateRef: baseCMObject.GetName(), Namespace: "default", diff --git a/pkg/controller/configuration/template_wrapper.go b/pkg/controller/configuration/template_wrapper.go index c217a5aecc5..4daaf9e388d 100644 --- a/pkg/controller/configuration/template_wrapper.go +++ b/pkg/controller/configuration/template_wrapper.go @@ -31,6 +31,7 @@ import ( "k8s.io/apimachinery/pkg/runtime/schema" "sigs.k8s.io/controller-runtime/pkg/client" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" appsv1beta1 "github.com/apecloud/kubeblocks/apis/apps/v1beta1" "github.com/apecloud/kubeblocks/pkg/configuration/core" @@ -48,18 +49,18 @@ type templateRenderValidator = func(map[string]string) error type renderWrapper struct { templateBuilder *configTemplateBuilder - volumes map[string]appsv1alpha1.ComponentTemplateSpec + volumes map[string]appsv1.ComponentTemplateSpec templateAnnotations map[string]string renderedObjs []client.Object ctx context.Context cli client.Client cluster *appsv1alpha1.Cluster - component *appsv1alpha1.Component + component *appsv1.Component } func newTemplateRenderWrapper(ctx context.Context, cli client.Client, templateBuilder *configTemplateBuilder, - cluster *appsv1alpha1.Cluster, component *appsv1alpha1.Component) renderWrapper { + cluster *appsv1alpha1.Cluster, component *appsv1.Component) renderWrapper { return renderWrapper{ ctx: ctx, cli: cli, @@ -68,7 +69,7 @@ func newTemplateRenderWrapper(ctx context.Context, cli client.Client, templateBu templateBuilder: templateBuilder, templateAnnotations: make(map[string]string), - volumes: make(map[string]appsv1alpha1.ComponentTemplateSpec), + volumes: make(map[string]appsv1.ComponentTemplateSpec), } } @@ -166,7 +167,7 @@ func updateConfigMetaForCM(newCMObj *corev1.ConfigMap, item *appsv1alpha1.Config return } -func applyUpdatedParameters(item *appsv1alpha1.ConfigurationItemDetail, cm *corev1.ConfigMap, configSpec appsv1alpha1.ComponentConfigSpec, cli client.Client, ctx context.Context) (err error) { +func applyUpdatedParameters(item *appsv1alpha1.ConfigurationItemDetail, cm *corev1.ConfigMap, configSpec appsv1.ComponentConfigSpec, cli client.Client, ctx context.Context) (err error) { var newData map[string]string var configConstraint *appsv1beta1.ConfigConstraint @@ -189,7 +190,7 @@ func applyUpdatedParameters(item *appsv1alpha1.ConfigurationItemDetail, cm *core func (wrapper *renderWrapper) rerenderConfigTemplate(cluster *appsv1alpha1.Cluster, component *component.SynthesizedComponent, - configSpec appsv1alpha1.ComponentConfigSpec, + configSpec appsv1.ComponentConfigSpec, item *appsv1alpha1.ConfigurationItemDetail, ) (*corev1.ConfigMap, error) { cmName := core.GetComponentCfgName(cluster.Name, component.Name, configSpec.Name) @@ -251,7 +252,7 @@ func (wrapper *renderWrapper) renderScriptTemplate(cluster *appsv1alpha1.Cluster return nil } -func (wrapper *renderWrapper) addRenderedObject(templateSpec appsv1alpha1.ComponentTemplateSpec, cm *corev1.ConfigMap, configuration *appsv1alpha1.Configuration) (err error) { +func (wrapper *renderWrapper) addRenderedObject(templateSpec appsv1.ComponentTemplateSpec, cm *corev1.ConfigMap, configuration *appsv1alpha1.Configuration) (err error) { // The owner of the configmap object is a cluster, // in order to manage the life cycle of configmap if configuration != nil { @@ -268,7 +269,7 @@ func (wrapper *renderWrapper) addRenderedObject(templateSpec appsv1alpha1.Compon return nil } -func (wrapper *renderWrapper) addVolumeMountMeta(templateSpec appsv1alpha1.ComponentTemplateSpec, object client.Object, rendered bool) { +func (wrapper *renderWrapper) addVolumeMountMeta(templateSpec appsv1.ComponentTemplateSpec, object client.Object, rendered bool) { wrapper.volumes[object.GetName()] = templateSpec if rendered { wrapper.renderedObjs = append(wrapper.renderedObjs, object) @@ -310,7 +311,7 @@ func findMatchedLocalObject(localObjs []client.Object, objKey client.ObjectKey, return nil } -func UpdateCMConfigSpecLabels(cm *corev1.ConfigMap, configSpec appsv1alpha1.ComponentConfigSpec) { +func UpdateCMConfigSpecLabels(cm *corev1.ConfigMap, configSpec appsv1.ComponentConfigSpec) { if cm.Labels == nil { cm.Labels = make(map[string]string) } @@ -332,7 +333,7 @@ func generateConfigMapFromTpl(cluster *appsv1alpha1.Cluster, tplBuilder *configTemplateBuilder, cmName string, configConstraintName string, - templateSpec appsv1alpha1.ComponentTemplateSpec, + templateSpec appsv1.ComponentTemplateSpec, ctx context.Context, cli client.Client, dataValidator templateRenderValidator) (*corev1.ConfigMap, error) { // Render config template by TplEngine @@ -355,7 +356,7 @@ func generateConfigMapFromTpl(cluster *appsv1alpha1.Cluster, // renderConfigMapTemplate renders config file using template engine func renderConfigMapTemplate( templateBuilder *configTemplateBuilder, - templateSpec appsv1alpha1.ComponentTemplateSpec, + templateSpec appsv1.ComponentTemplateSpec, ctx context.Context, cli client.Client) (map[string]string, error) { cmObj := &corev1.ConfigMap{} @@ -393,7 +394,7 @@ func fetchConfigConstraint(ccName string, ctx context.Context, cli client.Client // validateRenderedData validates config file against constraint func validateRenderedData( renderedData map[string]string, - configSpec appsv1alpha1.ComponentConfigSpec, + configSpec appsv1.ComponentConfigSpec, ctx context.Context, cli client.Client) error { if configSpec.ConfigConstraintRef == "" { @@ -406,7 +407,7 @@ func validateRenderedData( return validateRawData(renderedData, configSpec, &configConstraint.Spec) } -func validateRawData(renderedData map[string]string, configSpec appsv1alpha1.ComponentConfigSpec, cc *appsv1beta1.ConfigConstraintSpec) error { +func validateRawData(renderedData map[string]string, configSpec appsv1.ComponentConfigSpec, cc *appsv1beta1.ConfigConstraintSpec) error { configChecker := validate.NewConfigValidator(cc, validate.WithKeySelector(configSpec.Keys)) // NOTE: It is necessary to verify the correctness of the data if err := configChecker.Validate(renderedData); err != nil { diff --git a/pkg/controller/configuration/template_wrapper_test.go b/pkg/controller/configuration/template_wrapper_test.go index 52642f4bce7..6c4cb5cf18a 100644 --- a/pkg/controller/configuration/template_wrapper_test.go +++ b/pkg/controller/configuration/template_wrapper_test.go @@ -27,6 +27,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/client" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" appsv1beta1 "github.com/apecloud/kubeblocks/apis/apps/v1beta1" cfgcore "github.com/apecloud/kubeblocks/pkg/configuration/core" @@ -38,8 +39,8 @@ import ( var _ = Describe("TemplateWrapperTest", func() { var mockK8sCli *testutil.K8sClientMockHelper var clusterObj *appsv1alpha1.Cluster - var componentObj *appsv1alpha1.Component - var compDefObj *appsv1alpha1.ComponentDefinition + var componentObj *appsv1.Component + var compDefObj *appsv1.ComponentDefinition var clusterComponent *component.SynthesizedComponent mockTemplateWrapper := func() renderWrapper { diff --git a/pkg/controller/configuration/tool_image_builder_test.go b/pkg/controller/configuration/tool_image_builder_test.go index 53b6075b2c2..22546e32451 100644 --- a/pkg/controller/configuration/tool_image_builder_test.go +++ b/pkg/controller/configuration/tool_image_builder_test.go @@ -20,6 +20,7 @@ along with this program. If not, see . package configuration import ( + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" @@ -39,7 +40,7 @@ var _ = Describe("ToolsImageBuilderTest", func() { var noneCommand = []string{"/bin/true"} var clusterObj *appsv1alpha1.Cluster - var compDefObj *appsv1alpha1.ComponentDefinition + var compDefObj *appsv1.ComponentDefinition var clusterComponent *component.SynthesizedComponent BeforeEach(func() { diff --git a/pkg/controller/factory/builder.go b/pkg/controller/factory/builder.go index f92393fce81..3ce10972f1a 100644 --- a/pkg/controller/factory/builder.go +++ b/pkg/controller/factory/builder.go @@ -30,6 +30,7 @@ import ( "k8s.io/apimachinery/pkg/types" "k8s.io/klog/v2" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" appsv1beta1 "github.com/apecloud/kubeblocks/apis/apps/v1beta1" dpv1alpha1 "github.com/apecloud/kubeblocks/apis/dataprotection/v1alpha1" @@ -46,7 +47,7 @@ import ( ) // BuildInstanceSet builds an InstanceSet object from SynthesizedComponent. -func BuildInstanceSet(synthesizedComp *component.SynthesizedComponent, componentDef *appsv1alpha1.ComponentDefinition) (*workloads.InstanceSet, error) { +func BuildInstanceSet(synthesizedComp *component.SynthesizedComponent, componentDef *appsv1.ComponentDefinition) (*workloads.InstanceSet, error) { var ( compDefName = synthesizedComp.CompDefName namespace = synthesizedComp.Namespace @@ -133,7 +134,7 @@ func vctToPVC(vct corev1.PersistentVolumeClaimTemplate) corev1.PersistentVolumeC } // getMonitorAnnotations returns the annotations for the monitor. -func getMonitorAnnotations(synthesizedComp *component.SynthesizedComponent, componentDef *appsv1alpha1.ComponentDefinition) map[string]string { +func getMonitorAnnotations(synthesizedComp *component.SynthesizedComponent, componentDef *appsv1.ComponentDefinition) map[string]string { if synthesizedComp.DisableExporter == nil || *synthesizedComp.DisableExporter || componentDef == nil { return nil } @@ -211,7 +212,7 @@ func GetRestorePassword(synthesizedComp *component.SynthesizedComponent) string } // GetRestoreSystemAccountPassword gets restore password if exists during recovery. -func GetRestoreSystemAccountPassword(synthesizedComp *component.SynthesizedComponent, account appsv1alpha1.SystemAccount) string { +func GetRestoreSystemAccountPassword(synthesizedComp *component.SynthesizedComponent, account appsv1.SystemAccount) string { valueString := synthesizedComp.Annotations[constant.RestoreFromBackupAnnotationKey] if len(valueString) == 0 { return "" @@ -293,7 +294,7 @@ func BuildConfigMapWithTemplate(cluster *appsv1alpha1.Cluster, component *component.SynthesizedComponent, configs map[string]string, cmName string, - configTemplateSpec appsv1alpha1.ComponentTemplateSpec) *corev1.ConfigMap { + configTemplateSpec appsv1.ComponentTemplateSpec) *corev1.ConfigMap { wellKnownLabels := constant.GetKBWellKnownLabels(component.ClusterDefName, cluster.Name, component.Name) wellKnownLabels[constant.AppComponentLabelKey] = component.CompDefName return builder.NewConfigMapBuilder(cluster.Namespace, cmName). diff --git a/pkg/controller/factory/builder_test.go b/pkg/controller/factory/builder_test.go index 3e4fef47caf..3167824ab60 100644 --- a/pkg/controller/factory/builder_test.go +++ b/pkg/controller/factory/builder_test.go @@ -31,6 +31,7 @@ import ( "k8s.io/apimachinery/pkg/types" "sigs.k8s.io/controller-runtime/pkg/client" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" appsv1beta1 "github.com/apecloud/kubeblocks/apis/apps/v1beta1" workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" @@ -47,7 +48,7 @@ var _ = Describe("builder", func() { const clusterName = "test-cluster" const mysqlCompName = "mysql" - allFieldsCompDefObj := func(needCreate bool) *appsv1alpha1.ComponentDefinition { + allFieldsCompDefObj := func(needCreate bool) *appsv1.ComponentDefinition { By("By assure an componentDefinition obj") compDebObj := testapps.NewComponentDefinitionFactory(compDefName). SetDefaultSpec(). @@ -67,7 +68,7 @@ var _ = Describe("builder", func() { } } - newAllFieldsClusterObj := func(compDefObj *appsv1alpha1.ComponentDefinition, create bool) (*appsv1alpha1.Cluster, *appsv1alpha1.ComponentDefinition, types.NamespacedName) { + newAllFieldsClusterObj := func(compDefObj *appsv1.ComponentDefinition, create bool) (*appsv1alpha1.Cluster, *appsv1.ComponentDefinition, types.NamespacedName) { // setup Cluster obj requires default ComponentDefinition object if compDefObj == nil { compDefObj = allFieldsCompDefObj(create) @@ -116,7 +117,7 @@ var _ = Describe("builder", func() { return reqCtx } - newAllFieldsSynthesizedComponent := func(compDef *appsv1alpha1.ComponentDefinition, cluster *appsv1alpha1.Cluster) *component.SynthesizedComponent { + newAllFieldsSynthesizedComponent := func(compDef *appsv1.ComponentDefinition, cluster *appsv1alpha1.Cluster) *component.SynthesizedComponent { reqCtx := newReqCtx() By("assign every available fields") comp, err := component.BuildComponent(cluster, &cluster.Spec.ComponentSpecs[0], nil, nil) @@ -132,7 +133,7 @@ var _ = Describe("builder", func() { return synthesizeComp } - newClusterObjs := func(compDefObj *appsv1alpha1.ComponentDefinition) (*appsv1alpha1.ComponentDefinition, *appsv1alpha1.Cluster, *component.SynthesizedComponent) { + newClusterObjs := func(compDefObj *appsv1.ComponentDefinition) (*appsv1.ComponentDefinition, *appsv1alpha1.Cluster, *component.SynthesizedComponent) { cluster, compDef, _ := newAllFieldsClusterObj(compDefObj, false) synthesizedComponent := newAllFieldsSynthesizedComponent(compDef, cluster) return compDef, cluster, synthesizedComponent @@ -202,8 +203,8 @@ var _ = Describe("builder", func() { It("builds ConfigMap with template correctly", func() { config := map[string]string{} _, cluster, synthesizedComponent := newClusterObjs(nil) - tplCfg := appsv1alpha1.ComponentConfigSpec{ - ComponentTemplateSpec: appsv1alpha1.ComponentTemplateSpec{ + tplCfg := appsv1.ComponentConfigSpec{ + ComponentTemplateSpec: appsv1.ComponentTemplateSpec{ Name: "test-config-tpl", TemplateRef: "test-config-tpl", }, diff --git a/pkg/controller/plan/prepare.go b/pkg/controller/plan/prepare.go index 24ad3dd1894..798f4d70b17 100644 --- a/pkg/controller/plan/prepare.go +++ b/pkg/controller/plan/prepare.go @@ -23,6 +23,7 @@ import ( corev1 "k8s.io/api/core/v1" "sigs.k8s.io/controller-runtime/pkg/client" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" "github.com/apecloud/kubeblocks/pkg/controller/component" "github.com/apecloud/kubeblocks/pkg/controller/configuration" @@ -32,7 +33,7 @@ import ( // and generates configManager sidecar for the reconfigure operation. func RenderConfigNScriptFiles(resourceCtx *configuration.ResourceCtx, cluster *appsv1alpha1.Cluster, - component *appsv1alpha1.Component, + component *appsv1.Component, synthesizedComponent *component.SynthesizedComponent, podSpec *corev1.PodSpec, localObjs []client.Object) error { diff --git a/pkg/controller/plan/prepare_test.go b/pkg/controller/plan/prepare_test.go index 29d6774c30d..b58aa1078bf 100644 --- a/pkg/controller/plan/prepare_test.go +++ b/pkg/controller/plan/prepare_test.go @@ -26,6 +26,7 @@ import ( corev1 "k8s.io/api/core/v1" "sigs.k8s.io/controller-runtime/pkg/client" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" appsv1beta1 "github.com/apecloud/kubeblocks/apis/apps/v1beta1" cfgcore "github.com/apecloud/kubeblocks/pkg/configuration/core" @@ -69,9 +70,9 @@ var _ = Describe("Prepare Test", func() { ) var ( - compDefObj *appsv1alpha1.ComponentDefinition + compDefObj *appsv1.ComponentDefinition cluster *appsv1alpha1.Cluster - comp *appsv1alpha1.Component + comp *appsv1.Component configSpecName string ) diff --git a/pkg/controller/plan/restore.go b/pkg/controller/plan/restore.go index ef9de1fa46a..45daea9e011 100644 --- a/pkg/controller/plan/restore.go +++ b/pkg/controller/plan/restore.go @@ -32,6 +32,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" dpv1alpha1 "github.com/apecloud/kubeblocks/apis/dataprotection/v1alpha1" "github.com/apecloud/kubeblocks/pkg/constant" @@ -82,7 +83,7 @@ func NewRestoreManager(ctx context.Context, } } -func (r *RestoreManager) DoRestore(comp *component.SynthesizedComponent, compObj *appsv1alpha1.Component, postProvisionDone bool) error { +func (r *RestoreManager) DoRestore(comp *component.SynthesizedComponent, compObj *appsv1.Component, postProvisionDone bool) error { backupObj, err := r.initFromAnnotation(comp, compObj) if err != nil { return err @@ -96,7 +97,7 @@ func (r *RestoreManager) DoRestore(comp *component.SynthesizedComponent, compObj if err = r.DoPrepareData(comp, compObj, backupObj); err != nil { return err } - if compObj.Status.Phase != appsv1alpha1.RunningClusterCompPhase { + if compObj.Status.Phase != appsv1.RunningClusterCompPhase { return nil } // wait for the post-provision action to complete. @@ -118,12 +119,18 @@ func (r *RestoreManager) DoRestore(comp *component.SynthesizedComponent, compObj } func (r *RestoreManager) DoPrepareData(comp *component.SynthesizedComponent, - compObj *appsv1alpha1.Component, + compObj *appsv1.Component, backupObj *dpv1alpha1.Backup) error { + replicas := func(t appsv1.InstanceTemplate) int32 { + if t.Replicas != nil { + return *t.Replicas + } + return 1 // default replica + } var restores []*dpv1alpha1.Restore var templateReplicas int32 for _, v := range comp.Instances { - r.replicas = v.GetReplicas() + r.replicas = replicas(v) templateReplicas += r.replicas restore, err := r.BuildPrepareDataRestore(comp, backupObj, v.Name) if err != nil { @@ -233,7 +240,7 @@ func (r *RestoreManager) BuildPrepareDataRestore(comp *component.SynthesizedComp } func (r *RestoreManager) DoPostReady(comp *component.SynthesizedComponent, - compObj *appsv1alpha1.Component, + compObj *appsv1.Component, backupObj *dpv1alpha1.Backup) error { jobActionLabels := constant.GetComponentWellKnownLabels(r.Cluster.Name, comp.Name) if len(comp.Roles) > 0 { @@ -330,7 +337,7 @@ func (r *RestoreManager) GetRestoreObjectMeta(comp *component.SynthesizedCompone } } -func (r *RestoreManager) initFromAnnotation(synthesizedComponent *component.SynthesizedComponent, compObj *appsv1alpha1.Component) (*dpv1alpha1.Backup, error) { +func (r *RestoreManager) initFromAnnotation(synthesizedComponent *component.SynthesizedComponent, compObj *appsv1.Component) (*dpv1alpha1.Backup, error) { valueString := r.Cluster.Annotations[constant.RestoreFromBackupAnnotationKey] if len(valueString) == 0 { return nil, nil @@ -363,7 +370,7 @@ func (r *RestoreManager) initFromAnnotation(synthesizedComponent *component.Synt } // createRestoreAndWait create the restore CR and wait for completion. -func (r *RestoreManager) createRestoreAndWait(compObj *appsv1alpha1.Component, restores ...*dpv1alpha1.Restore) error { +func (r *RestoreManager) createRestoreAndWait(compObj *appsv1.Component, restores ...*dpv1alpha1.Restore) error { if len(restores) == 0 { return nil } diff --git a/pkg/controller/plan/restore_test.go b/pkg/controller/plan/restore_test.go index 7116d54dcd2..64afb865250 100644 --- a/pkg/controller/plan/restore_test.go +++ b/pkg/controller/plan/restore_test.go @@ -32,6 +32,7 @@ import ( "k8s.io/client-go/kubernetes/scheme" "sigs.k8s.io/controller-runtime/pkg/client" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" dpv1alpha1 "github.com/apecloud/kubeblocks/apis/dataprotection/v1alpha1" "github.com/apecloud/kubeblocks/pkg/constant" @@ -99,10 +100,10 @@ var _ = Describe("Restore", func() { ) var ( - compDef *appsv1alpha1.ComponentDefinition + compDef *appsv1.ComponentDefinition cluster *appsv1alpha1.Cluster synthesizedComponent *component.SynthesizedComponent - compObj *appsv1alpha1.Component + compObj *appsv1.Component pvc *corev1.PersistentVolumeClaim backup *dpv1alpha1.Backup fullBackupActionSet *dpv1alpha1.ActionSet @@ -163,7 +164,7 @@ var _ = Describe("Restore", func() { VolumeClaimTemplates: cluster.Spec.ComponentSpecs[0].ToVolumeClaimTemplates(), Name: defaultCompName, Replicas: 1, - Roles: []appsv1alpha1.ReplicaRole{ + Roles: []appsv1.ReplicaRole{ { Name: "leader", Serviceable: true, @@ -244,7 +245,7 @@ var _ = Describe("Restore", func() { } })).Should(Succeed()) Expect(testapps.ChangeObjStatus(&testCtx, compObj, func() { - compObj.Status.Phase = appsv1alpha1.RunningClusterCompPhase + compObj.Status.Phase = appsv1.RunningClusterCompPhase })).Should(Succeed()) By("wait for postReady restore created and mock it to Completed") diff --git a/pkg/controller/plan/tls_utils.go b/pkg/controller/plan/tls_utils.go index 6fff1a84a61..fa324170b98 100644 --- a/pkg/controller/plan/tls_utils.go +++ b/pkg/controller/plan/tls_utils.go @@ -32,7 +32,7 @@ import ( "k8s.io/apimachinery/pkg/types" "sigs.k8s.io/controller-runtime/pkg/client" - dbaasv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" "github.com/apecloud/kubeblocks/pkg/constant" "github.com/apecloud/kubeblocks/pkg/controller/builder" ) @@ -94,7 +94,7 @@ func buildFromTemplate(tpl string, vars interface{}) (string, error) { } func CheckTLSSecretRef(ctx context.Context, cli client.Reader, namespace string, - secretRef *dbaasv1alpha1.TLSSecretRef) error { + secretRef *appsv1.TLSSecretRef) error { if secretRef == nil { return errors.New("issuer.secretRef shouldn't be nil when issuer is UserProvided") } diff --git a/pkg/controller/scheduling/scheduling_utils.go b/pkg/controller/scheduling/scheduling_utils.go index 288b37f300b..898babf5f04 100644 --- a/pkg/controller/scheduling/scheduling_utils.go +++ b/pkg/controller/scheduling/scheduling_utils.go @@ -28,12 +28,13 @@ import ( corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" "github.com/apecloud/kubeblocks/pkg/constant" viper "github.com/apecloud/kubeblocks/pkg/viperx" ) -func BuildSchedulingPolicy(cluster *appsv1alpha1.Cluster, compSpec *appsv1alpha1.ClusterComponentSpec) (*appsv1alpha1.SchedulingPolicy, error) { +func BuildSchedulingPolicy(cluster *appsv1alpha1.Cluster, compSpec *appsv1alpha1.ClusterComponentSpec) (*appsv1.SchedulingPolicy, error) { if cluster.Spec.SchedulingPolicy != nil || (compSpec != nil && compSpec.SchedulingPolicy != nil) { return buildSchedulingPolicy(cluster, compSpec) } @@ -41,11 +42,11 @@ func BuildSchedulingPolicy(cluster *appsv1alpha1.Cluster, compSpec *appsv1alpha1 } func BuildSchedulingPolicy4Component(clusterName, compName string, affinity *appsv1alpha1.Affinity, - tolerations []corev1.Toleration) (*appsv1alpha1.SchedulingPolicy, error) { + tolerations []corev1.Toleration) (*appsv1.SchedulingPolicy, error) { return buildSchedulingPolicy4LegacyComponent(clusterName, compName, affinity, tolerations) } -func buildSchedulingPolicy(cluster *appsv1alpha1.Cluster, compSpec *appsv1alpha1.ClusterComponentSpec) (*appsv1alpha1.SchedulingPolicy, error) { +func buildSchedulingPolicy(cluster *appsv1alpha1.Cluster, compSpec *appsv1alpha1.ClusterComponentSpec) (*appsv1.SchedulingPolicy, error) { schedulingPolicy := cluster.Spec.SchedulingPolicy if compSpec != nil && compSpec.SchedulingPolicy != nil { schedulingPolicy = compSpec.SchedulingPolicy @@ -81,10 +82,24 @@ func buildSchedulingPolicy(cluster *appsv1alpha1.Cluster, compSpec *appsv1alpha1 if err := mergeGlobalTolerations(); err != nil { return nil, err } - return schedulingPolicy, nil + return toV1SchedulingPolicy(schedulingPolicy), nil } -func buildSchedulingPolicy4Legacy(cluster *appsv1alpha1.Cluster, compSpec *appsv1alpha1.ClusterComponentSpec) (*appsv1alpha1.SchedulingPolicy, error) { +func toV1SchedulingPolicy(schedulingPolicy *appsv1alpha1.SchedulingPolicy) *appsv1.SchedulingPolicy { + if schedulingPolicy != nil { + return &appsv1.SchedulingPolicy{ + SchedulerName: schedulingPolicy.SchedulerName, + NodeSelector: schedulingPolicy.NodeSelector, + NodeName: schedulingPolicy.NodeName, + Affinity: schedulingPolicy.Affinity, + Tolerations: schedulingPolicy.Tolerations, + TopologySpreadConstraints: schedulingPolicy.TopologySpreadConstraints, + } + } + return nil +} + +func buildSchedulingPolicy4Legacy(cluster *appsv1alpha1.Cluster, compSpec *appsv1alpha1.ClusterComponentSpec) (*appsv1.SchedulingPolicy, error) { affinity := buildAffinity4Legacy(cluster, compSpec) tolerations, err := buildTolerations4Legacy(cluster, compSpec) if err != nil { @@ -94,12 +109,12 @@ func buildSchedulingPolicy4Legacy(cluster *appsv1alpha1.Cluster, compSpec *appsv } func buildSchedulingPolicy4LegacyComponent(clusterName, compName string, affinity *appsv1alpha1.Affinity, - tolerations []corev1.Toleration) (*appsv1alpha1.SchedulingPolicy, error) { + tolerations []corev1.Toleration) (*appsv1.SchedulingPolicy, error) { podAffinity, err := buildPodAffinity4Legacy(clusterName, compName, affinity) if err != nil { return nil, err } - return &appsv1alpha1.SchedulingPolicy{ + return &appsv1.SchedulingPolicy{ Affinity: podAffinity, Tolerations: tolerations, TopologySpreadConstraints: buildPodTopologySpreadConstraints4Legacy(clusterName, compName, affinity), diff --git a/pkg/controllerutil/sharding_utils.go b/pkg/controllerutil/sharding_utils.go index ecd102fc66d..390f49a62e5 100644 --- a/pkg/controllerutil/sharding_utils.go +++ b/pkg/controllerutil/sharding_utils.go @@ -27,6 +27,7 @@ import ( "github.com/pkg/errors" "sigs.k8s.io/controller-runtime/pkg/client" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" "github.com/apecloud/kubeblocks/pkg/common" "github.com/apecloud/kubeblocks/pkg/constant" @@ -97,8 +98,8 @@ func listNCheckShardingComponents(ctx context.Context, cli client.Reader, } func ListShardingComponents(ctx context.Context, cli client.Reader, - cluster *appsv1alpha1.Cluster, shardingName string) ([]appsv1alpha1.Component, error) { - compList := &appsv1alpha1.ComponentList{} + cluster *appsv1alpha1.Cluster, shardingName string) ([]appsv1.Component, error) { + compList := &appsv1.ComponentList{} ml := client.MatchingLabels{ constant.AppInstanceLabelKey: cluster.Name, constant.KBAppShardingNameLabelKey: shardingName, diff --git a/pkg/controllerutil/volume_util.go b/pkg/controllerutil/volume_util.go index ee3135ebd21..60045a1b9af 100644 --- a/pkg/controllerutil/volume_util.go +++ b/pkg/controllerutil/volume_util.go @@ -27,7 +27,7 @@ import ( "golang.org/x/exp/maps" corev1 "k8s.io/api/core/v1" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" "github.com/apecloud/kubeblocks/pkg/constant" viper "github.com/apecloud/kubeblocks/pkg/viperx" ) @@ -65,7 +65,7 @@ func CreateOrUpdateVolume(volumes []corev1.Volume, volumeName string, createFn c return append(volumes, createFn(volumeName)), nil } -func CreateOrUpdatePodVolumes(podSpec *corev1.PodSpec, volumes map[string]appsv1alpha1.ComponentTemplateSpec, configSet []string) error { +func CreateOrUpdatePodVolumes(podSpec *corev1.PodSpec, volumes map[string]appsv1.ComponentTemplateSpec, configSet []string) error { var ( err error podVolumes = podSpec.Volumes @@ -106,7 +106,7 @@ func CreateOrUpdatePodVolumes(podSpec *corev1.PodSpec, volumes map[string]appsv1 return nil } -func buildVolumeMode(configs []string, configSpec appsv1alpha1.ComponentTemplateSpec) *int32 { +func buildVolumeMode(configs []string, configSpec appsv1.ComponentTemplateSpec) *int32 { // If the defaultMode is not set, permissions are automatically set based on the template type. if !viper.GetBool(constant.FeatureGateIgnoreConfigTemplateDefaultMode) && configSpec.DefaultMode != nil { return configSpec.DefaultMode diff --git a/pkg/generics/type.go b/pkg/generics/type.go index dc6ebeb1a8a..df08eb74e69 100644 --- a/pkg/generics/type.go +++ b/pkg/generics/type.go @@ -91,9 +91,9 @@ var ClusterSignature = func(_ appsv1alpha1.Cluster, _ *appsv1alpha1.Cluster, _ a } var ClusterDefinitionSignature = func(_ appsv1.ClusterDefinition, _ *appsv1.ClusterDefinition, _ appsv1.ClusterDefinitionList, _ *appsv1.ClusterDefinitionList) { } -var ComponentSignature = func(appsv1alpha1.Component, *appsv1alpha1.Component, appsv1alpha1.ComponentList, *appsv1alpha1.ComponentList) { +var ComponentSignature = func(appsv1.Component, *appsv1.Component, appsv1.ComponentList, *appsv1.ComponentList) { } -var ComponentDefinitionSignature = func(appsv1alpha1.ComponentDefinition, *appsv1alpha1.ComponentDefinition, appsv1alpha1.ComponentDefinitionList, *appsv1alpha1.ComponentDefinitionList) { +var ComponentDefinitionSignature = func(appsv1.ComponentDefinition, *appsv1.ComponentDefinition, appsv1.ComponentDefinitionList, *appsv1.ComponentDefinitionList) { } var ComponentVersionSignature = func(appsv1.ComponentVersion, *appsv1.ComponentVersion, appsv1.ComponentVersionList, *appsv1.ComponentVersionList) { } diff --git a/pkg/testutil/apps/cluster_instance_set_test_util.go b/pkg/testutil/apps/cluster_instance_set_test_util.go index a264cd9b42c..68e8414d044 100644 --- a/pkg/testutil/apps/cluster_instance_set_test_util.go +++ b/pkg/testutil/apps/cluster_instance_set_test_util.go @@ -33,6 +33,7 @@ import ( "k8s.io/apimachinery/pkg/util/sets" "sigs.k8s.io/controller-runtime/pkg/client" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" "github.com/apecloud/kubeblocks/pkg/constant" @@ -44,7 +45,7 @@ const ( replicas = 3 ) -func InitConsensusMysql(testCtx *testutil.TestContext, clusterName, compDefName, compName string) (*appsv1alpha1.ComponentDefinition, *appsv1alpha1.Cluster) { +func InitConsensusMysql(testCtx *testutil.TestContext, clusterName, compDefName, compName string) (*appsv1.ComponentDefinition, *appsv1alpha1.Cluster) { compDef := createCompDef(testCtx, compDefName) cluster := CreateDefaultMysqlCluster(testCtx, clusterName, compDef.GetName(), compName) return compDef, cluster @@ -65,7 +66,7 @@ func CreateDefaultMysqlCluster(testCtx *testutil.TestContext, clusterName, compD GetObject() } -func createCompDef(testCtx *testutil.TestContext, compDefName string) *appsv1alpha1.ComponentDefinition { +func createCompDef(testCtx *testutil.TestContext, compDefName string) *appsv1.ComponentDefinition { return NewComponentDefinitionFactory(compDefName).SetDefaultSpec().Create(testCtx).GetObject() } diff --git a/pkg/testutil/apps/component_factory.go b/pkg/testutil/apps/component_factory.go index 933fc547c68..3810764c677 100644 --- a/pkg/testutil/apps/component_factory.go +++ b/pkg/testutil/apps/component_factory.go @@ -20,20 +20,19 @@ along with this program. If not, see . package apps import ( + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" corev1 "k8s.io/api/core/v1" - - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" ) type MockComponentFactory struct { - BaseFactory[appsv1alpha1.Component, *appsv1alpha1.Component, MockComponentFactory] + BaseFactory[appsv1.Component, *appsv1.Component, MockComponentFactory] } func NewComponentFactory(namespace, name, componentDefinition string) *MockComponentFactory { f := &MockComponentFactory{} f.Init(namespace, name, - &appsv1alpha1.Component{ - Spec: appsv1alpha1.ComponentSpec{ + &appsv1.Component{ + Spec: appsv1.ComponentSpec{ CompDef: componentDefinition, }, }, f) @@ -45,21 +44,6 @@ func (factory *MockComponentFactory) SetServiceVersion(serviceVersion string) *M return factory } -func (factory *MockComponentFactory) SetAffinity(affinity *appsv1alpha1.Affinity) *MockComponentFactory { - factory.Get().Spec.Affinity = affinity - return factory -} - -func (factory *MockComponentFactory) AddToleration(toleration corev1.Toleration) *MockComponentFactory { - tolerations := factory.Get().Spec.Tolerations - if len(tolerations) == 0 { - tolerations = []corev1.Toleration{} - } - tolerations = append(tolerations, toleration) - factory.Get().Spec.Tolerations = tolerations - return factory -} - func (factory *MockComponentFactory) SetReplicas(replicas int32) *MockComponentFactory { factory.Get().Spec.Replicas = replicas return factory @@ -80,9 +64,9 @@ func (factory *MockComponentFactory) SetResources(resources corev1.ResourceRequi // return factory // } -func (factory *MockComponentFactory) SetTLSConfig(enable bool, issuer *appsv1alpha1.Issuer) *MockComponentFactory { +func (factory *MockComponentFactory) SetTLSConfig(enable bool, issuer *appsv1.Issuer) *MockComponentFactory { if enable { - factory.Get().Spec.TLSConfig = &appsv1alpha1.TLSConfig{ + factory.Get().Spec.TLSConfig = &appsv1.TLSConfig{ Enable: enable, Issuer: issuer, } @@ -91,8 +75,8 @@ func (factory *MockComponentFactory) SetTLSConfig(enable bool, issuer *appsv1alp } func (factory *MockComponentFactory) AddVolumeClaimTemplate(volumeName string, - pvcSpec appsv1alpha1.PersistentVolumeClaimSpec) *MockComponentFactory { - factory.Get().Spec.VolumeClaimTemplates = append(factory.Get().Spec.VolumeClaimTemplates, appsv1alpha1.ClusterComponentVolumeClaimTemplate{ + pvcSpec appsv1.PersistentVolumeClaimSpec) *MockComponentFactory { + factory.Get().Spec.VolumeClaimTemplates = append(factory.Get().Spec.VolumeClaimTemplates, appsv1.ClusterComponentVolumeClaimTemplate{ Name: volumeName, Spec: pvcSpec, }) diff --git a/pkg/testutil/apps/component_util.go b/pkg/testutil/apps/component_util.go index 54a460dcb38..01e93e41d2f 100644 --- a/pkg/testutil/apps/component_util.go +++ b/pkg/testutil/apps/component_util.go @@ -23,32 +23,23 @@ import ( "github.com/onsi/gomega" "k8s.io/apimachinery/pkg/types" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" "github.com/apecloud/kubeblocks/pkg/testutil" ) -// GetComponentGeneration gets the testing component's metadata.generation. -func GetComponentGeneration(testCtx *testutil.TestContext, compKey types.NamespacedName) func(gomega.Gomega) int64 { - return func(g gomega.Gomega) int64 { - comp := &appsv1alpha1.Component{} - g.Expect(testCtx.Cli.Get(testCtx.Ctx, compKey, comp)).Should(gomega.Succeed()) - return comp.GetGeneration() - } -} - // GetComponentObservedGeneration gets the testing component's ObservedGeneration in status for verification. func GetComponentObservedGeneration(testCtx *testutil.TestContext, compKey types.NamespacedName) func(gomega.Gomega) int64 { return func(g gomega.Gomega) int64 { - comp := &appsv1alpha1.Component{} + comp := &appsv1.Component{} g.Expect(testCtx.Cli.Get(testCtx.Ctx, compKey, comp)).Should(gomega.Succeed()) return comp.Status.ObservedGeneration } } // GetComponentPhase gets the testing component's phase in status for verification. -func GetComponentPhase(testCtx *testutil.TestContext, compKey types.NamespacedName) func(gomega.Gomega) appsv1alpha1.ClusterComponentPhase { - return func(g gomega.Gomega) appsv1alpha1.ClusterComponentPhase { - comp := &appsv1alpha1.Component{} +func GetComponentPhase(testCtx *testutil.TestContext, compKey types.NamespacedName) func(gomega.Gomega) appsv1.ClusterComponentPhase { + return func(g gomega.Gomega) appsv1.ClusterComponentPhase { + comp := &appsv1.Component{} g.Expect(testCtx.Cli.Get(testCtx.Ctx, compKey, comp)).Should(gomega.Succeed()) return comp.Status.Phase } diff --git a/pkg/testutil/apps/componentdefinition_factory.go b/pkg/testutil/apps/componentdefinition_factory.go index f29e00f2cf7..04346c1e7dc 100644 --- a/pkg/testutil/apps/componentdefinition_factory.go +++ b/pkg/testutil/apps/componentdefinition_factory.go @@ -27,11 +27,11 @@ import ( corev1 "k8s.io/api/core/v1" rbacv1 "k8s.io/api/rbac/v1" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" + kbappsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" ) type MockComponentDefinitionFactory struct { - BaseFactory[appsv1alpha1.ComponentDefinition, *appsv1alpha1.ComponentDefinition, MockComponentDefinitionFactory] + BaseFactory[kbappsv1.ComponentDefinition, *kbappsv1.ComponentDefinition, MockComponentDefinitionFactory] } func NewComponentDefinitionFactory(name string) *MockComponentDefinitionFactory { @@ -41,8 +41,8 @@ func NewComponentDefinitionFactory(name string) *MockComponentDefinitionFactory func NewComponentDefinitionFactoryExt(name, provider, description, serviceKind, serviceVersion string) *MockComponentDefinitionFactory { f := &MockComponentDefinitionFactory{} f.Init("", name, - &appsv1alpha1.ComponentDefinition{ - Spec: appsv1alpha1.ComponentDefinitionSpec{ + &kbappsv1.ComponentDefinition{ + Spec: kbappsv1.ComponentDefinitionSpec{ Provider: provider, Description: description, ServiceKind: serviceKind, @@ -111,34 +111,34 @@ func (f *MockComponentDefinitionFactory) AddVolumeMounts(containerName string, v return f } -func (f *MockComponentDefinitionFactory) AddVar(v appsv1alpha1.EnvVar) *MockComponentDefinitionFactory { +func (f *MockComponentDefinitionFactory) AddVar(v kbappsv1.EnvVar) *MockComponentDefinitionFactory { if f.Get().Spec.Vars == nil { - f.Get().Spec.Vars = make([]appsv1alpha1.EnvVar, 0) + f.Get().Spec.Vars = make([]kbappsv1.EnvVar, 0) } f.Get().Spec.Vars = append(f.Get().Spec.Vars, v) return f } func (f *MockComponentDefinitionFactory) AddVolume(name string, snapshot bool, watermark int) *MockComponentDefinitionFactory { - vol := appsv1alpha1.ComponentVolume{ + vol := kbappsv1.ComponentVolume{ Name: name, NeedSnapshot: snapshot, HighWatermark: watermark, } if f.Get().Spec.Volumes == nil { - f.Get().Spec.Volumes = make([]appsv1alpha1.ComponentVolume, 0) + f.Get().Spec.Volumes = make([]kbappsv1.ComponentVolume, 0) } f.Get().Spec.Volumes = append(f.Get().Spec.Volumes, vol) return f } func (f *MockComponentDefinitionFactory) AddHostNetworkContainerPort(container string, ports []string) *MockComponentDefinitionFactory { - containerPort := appsv1alpha1.HostNetworkContainerPort{ + containerPort := kbappsv1.HostNetworkContainerPort{ Container: container, Ports: ports, } if f.Get().Spec.HostNetwork == nil { - f.Get().Spec.HostNetwork = &appsv1alpha1.HostNetwork{} + f.Get().Spec.HostNetwork = &kbappsv1.HostNetwork{} } f.Get().Spec.HostNetwork.ContainerPorts = append(f.Get().Spec.HostNetwork.ContainerPorts, containerPort) return f @@ -154,8 +154,8 @@ func (f *MockComponentDefinitionFactory) AddService(name, serviceName string, po } func (f *MockComponentDefinitionFactory) AddServiceExt(name, serviceName string, serviceSpec corev1.ServiceSpec, roleSelector string) *MockComponentDefinitionFactory { - svc := appsv1alpha1.ComponentService{ - Service: appsv1alpha1.Service{ + svc := kbappsv1.ComponentService{ + Service: kbappsv1.Service{ Name: name, ServiceName: serviceName, Spec: serviceSpec, @@ -163,7 +163,7 @@ func (f *MockComponentDefinitionFactory) AddServiceExt(name, serviceName string, }, } if f.Get().Spec.Services == nil { - f.Get().Spec.Services = make([]appsv1alpha1.ComponentService, 0) + f.Get().Spec.Services = make([]kbappsv1.ComponentService, 0) } f.Get().Spec.Services = append(f.Get().Spec.Services, svc) return f @@ -171,8 +171,8 @@ func (f *MockComponentDefinitionFactory) AddServiceExt(name, serviceName string, func (f *MockComponentDefinitionFactory) AddConfigTemplate(name, configTemplateRef, configConstraintRef, namespace, volumeName string, injectEnvTo ...string) *MockComponentDefinitionFactory { - config := appsv1alpha1.ComponentConfigSpec{ - ComponentTemplateSpec: appsv1alpha1.ComponentTemplateSpec{ + config := kbappsv1.ComponentConfigSpec{ + ComponentTemplateSpec: kbappsv1.ComponentTemplateSpec{ Name: name, TemplateRef: configTemplateRef, Namespace: namespace, @@ -182,44 +182,44 @@ func (f *MockComponentDefinitionFactory) AddConfigTemplate(name, configTemplateR InjectEnvTo: injectEnvTo, } if f.Get().Spec.Configs == nil { - f.Get().Spec.Configs = make([]appsv1alpha1.ComponentConfigSpec, 0) + f.Get().Spec.Configs = make([]kbappsv1.ComponentConfigSpec, 0) } f.Get().Spec.Configs = append(f.Get().Spec.Configs, config) return f } -func (f *MockComponentDefinitionFactory) AddConfigs(configs []appsv1alpha1.ComponentConfigSpec) *MockComponentDefinitionFactory { +func (f *MockComponentDefinitionFactory) AddConfigs(configs []kbappsv1.ComponentConfigSpec) *MockComponentDefinitionFactory { if f.Get().Spec.Configs == nil { - f.Get().Spec.Configs = make([]appsv1alpha1.ComponentConfigSpec, 0) + f.Get().Spec.Configs = make([]kbappsv1.ComponentConfigSpec, 0) } f.Get().Spec.Configs = append(f.Get().Spec.Configs, configs...) return f } -func (f *MockComponentDefinitionFactory) AddScripts(scripts []appsv1alpha1.ComponentTemplateSpec) *MockComponentDefinitionFactory { +func (f *MockComponentDefinitionFactory) AddScripts(scripts []kbappsv1.ComponentTemplateSpec) *MockComponentDefinitionFactory { if f.Get().Spec.Scripts == nil { - f.Get().Spec.Scripts = make([]appsv1alpha1.ComponentTemplateSpec, 0) + f.Get().Spec.Scripts = make([]kbappsv1.ComponentTemplateSpec, 0) } f.Get().Spec.Scripts = append(f.Get().Spec.Scripts, scripts...) return f } func (f *MockComponentDefinitionFactory) AddLogConfig(name, filePathPattern string) *MockComponentDefinitionFactory { - logConfig := appsv1alpha1.LogConfig{ + logConfig := kbappsv1.LogConfig{ FilePathPattern: filePathPattern, Name: name, } if f.Get().Spec.LogConfigs == nil { - f.Get().Spec.LogConfigs = make([]appsv1alpha1.LogConfig, 0) + f.Get().Spec.LogConfigs = make([]kbappsv1.LogConfig, 0) } f.Get().Spec.LogConfigs = append(f.Get().Spec.LogConfigs, logConfig) return f } // func (f *MockComponentDefinitionFactory) SetMonitor(builtIn bool, scrapePort intstr.IntOrString, scrapePath string) *MockComponentDefinitionFactory { -// f.Get().Spec.Monitor = &appsv1alpha1.MonitorConfig{ +// f.Get().Spec.Monitor = &kbappsv1.MonitorConfig{ // BuiltIn: builtIn, -// Exporter: &appsv1alpha1.ExporterConfig{ +// Exporter: &kbappsv1.ExporterConfig{ // ScrapePort: scrapePort, // ScrapePath: scrapePath, // }, @@ -229,7 +229,7 @@ func (f *MockComponentDefinitionFactory) AddLogConfig(name, filePathPattern stri func (f *MockComponentDefinitionFactory) AddScriptTemplate(name, configTemplateRef, namespace, volumeName string, mode *int32) *MockComponentDefinitionFactory { - script := appsv1alpha1.ComponentTemplateSpec{ + script := kbappsv1.ComponentTemplateSpec{ Name: name, TemplateRef: configTemplateRef, Namespace: namespace, @@ -237,7 +237,7 @@ func (f *MockComponentDefinitionFactory) AddScriptTemplate(name, configTemplateR DefaultMode: mode, } if f.Get().Spec.Scripts == nil { - f.Get().Spec.Scripts = make([]appsv1alpha1.ComponentTemplateSpec, 0) + f.Get().Spec.Scripts = make([]kbappsv1.ComponentTemplateSpec, 0) } f.Get().Spec.Scripts = append(f.Get().Spec.Scripts, script) return f @@ -254,7 +254,7 @@ func (f *MockComponentDefinitionFactory) SetLabels(labels map[string]string) *Mo } func (f *MockComponentDefinitionFactory) SetReplicasLimit(minReplicas, maxReplicas int32) *MockComponentDefinitionFactory { - f.Get().Spec.ReplicasLimit = &appsv1alpha1.ReplicasLimit{ + f.Get().Spec.ReplicasLimit = &kbappsv1.ReplicasLimit{ MinReplicas: minReplicas, MaxReplicas: maxReplicas, } @@ -262,19 +262,19 @@ func (f *MockComponentDefinitionFactory) SetReplicasLimit(minReplicas, maxReplic } func (f *MockComponentDefinitionFactory) AddSystemAccount(accountName string, initAccount bool, statement string) *MockComponentDefinitionFactory { - account := appsv1alpha1.SystemAccount{ + account := kbappsv1.SystemAccount{ Name: accountName, InitAccount: initAccount, Statement: statement, } if f.Get().Spec.SystemAccounts == nil { - f.Get().Spec.SystemAccounts = make([]appsv1alpha1.SystemAccount, 0) + f.Get().Spec.SystemAccounts = make([]kbappsv1.SystemAccount, 0) } f.Get().Spec.SystemAccounts = append(f.Get().Spec.SystemAccounts, account) return f } -func (f *MockComponentDefinitionFactory) SetUpdateStrategy(strategy *appsv1alpha1.UpdateStrategy) *MockComponentDefinitionFactory { +func (f *MockComponentDefinitionFactory) SetUpdateStrategy(strategy *kbappsv1.UpdateStrategy) *MockComponentDefinitionFactory { f.Get().Spec.UpdateStrategy = strategy return f } @@ -285,13 +285,13 @@ func (f *MockComponentDefinitionFactory) SetPodManagementPolicy(policy *appsv1.P } func (f *MockComponentDefinitionFactory) AddRole(name string, serviceable, writable bool) *MockComponentDefinitionFactory { - role := appsv1alpha1.ReplicaRole{ + role := kbappsv1.ReplicaRole{ Name: name, Serviceable: serviceable, Writable: writable, } if f.Get().Spec.Roles == nil { - f.Get().Spec.Roles = make([]appsv1alpha1.ReplicaRole, 0) + f.Get().Spec.Roles = make([]kbappsv1.ReplicaRole, 0) } f.Get().Spec.Roles = append(f.Get().Spec.Roles, role) return f @@ -299,7 +299,7 @@ func (f *MockComponentDefinitionFactory) AddRole(name string, serviceable, writa func (f *MockComponentDefinitionFactory) SetLifecycleAction(name string, val interface{}) *MockComponentDefinitionFactory { if f.Get().Spec.LifecycleActions == nil { - f.Get().Spec.LifecycleActions = &appsv1alpha1.ComponentLifecycleActions{} + f.Get().Spec.LifecycleActions = &kbappsv1.ComponentLifecycleActions{} } obj := f.Get().Spec.LifecycleActions t := reflect.TypeOf(obj).Elem() @@ -322,9 +322,9 @@ func (f *MockComponentDefinitionFactory) SetLifecycleAction(name string, val int } func (f *MockComponentDefinitionFactory) AddServiceRef(name, serviceKind, serviceVersion string) *MockComponentDefinitionFactory { - serviceRef := appsv1alpha1.ServiceRefDeclaration{ + serviceRef := kbappsv1.ServiceRefDeclaration{ Name: name, - ServiceRefDeclarationSpecs: []appsv1alpha1.ServiceRefDeclarationSpec{ + ServiceRefDeclarationSpecs: []kbappsv1.ServiceRefDeclarationSpec{ { ServiceKind: serviceKind, ServiceVersion: serviceVersion, @@ -332,7 +332,7 @@ func (f *MockComponentDefinitionFactory) AddServiceRef(name, serviceKind, servic }, } if f.Get().Spec.ServiceRefDeclarations == nil { - f.Get().Spec.ServiceRefDeclarations = make([]appsv1alpha1.ServiceRefDeclaration, 0) + f.Get().Spec.ServiceRefDeclarations = make([]kbappsv1.ServiceRefDeclaration, 0) } f.Get().Spec.ServiceRefDeclarations = append(f.Get().Spec.ServiceRefDeclarations, serviceRef) return f diff --git a/pkg/testutil/apps/constant.go b/pkg/testutil/apps/constant.go index 50da43c2012..705f26838c0 100644 --- a/pkg/testutil/apps/constant.go +++ b/pkg/testutil/apps/constant.go @@ -27,7 +27,6 @@ import ( "k8s.io/apimachinery/pkg/util/intstr" appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" ) const ( @@ -56,9 +55,9 @@ const ( ) var ( - NewLifecycleAction = func(name string) *appsv1alpha1.Action { - return &appsv1alpha1.Action{ - Exec: &appsv1alpha1.ExecAction{ + NewLifecycleAction = func(name string) *appsv1.Action { + return &appsv1.Action{ + Exec: &appsv1.ExecAction{ Command: []string{"/bin/sh", "-c", fmt.Sprintf("echo %s", name)}, }, } @@ -106,7 +105,7 @@ var ( Command: []string{"/scripts/setup.sh"}, } - defaultComponentDefSpec = appsv1alpha1.ComponentDefinitionSpec{ + defaultComponentDefSpec = appsv1.ComponentDefinitionSpec{ Provider: "kubeblocks.io", Description: "ApeCloud MySQL is a database that is compatible with MySQL syntax and achieves high availability\n through the utilization of the RAFT consensus protocol.", ServiceKind: "mysql", @@ -116,7 +115,7 @@ var ( defaultMySQLContainer, }, }, - Volumes: []appsv1alpha1.ComponentVolume{ + Volumes: []appsv1.ComponentVolume{ { Name: DataVolumeName, NeedSnapshot: true, @@ -126,9 +125,9 @@ var ( NeedSnapshot: true, }, }, - Services: []appsv1alpha1.ComponentService{ + Services: []appsv1.ComponentService{ { - Service: appsv1alpha1.Service{ + Service: appsv1.Service{ Name: "default", Spec: corev1.ServiceSpec{ Ports: []corev1.ServicePort{ @@ -146,7 +145,7 @@ var ( }, }, { - Service: appsv1alpha1.Service{ + Service: appsv1.Service{ Name: "rw", ServiceName: "rw", Spec: corev1.ServiceSpec{ @@ -165,7 +164,7 @@ var ( }, }, { - Service: appsv1alpha1.Service{ + Service: appsv1.Service{ Name: "ro", ServiceName: "ro", Spec: corev1.ServiceSpec{ @@ -184,30 +183,30 @@ var ( }, }, }, - SystemAccounts: []appsv1alpha1.SystemAccount{ + SystemAccounts: []appsv1.SystemAccount{ { Name: "root", InitAccount: true, - PasswordGenerationPolicy: appsv1alpha1.PasswordConfig{ + PasswordGenerationPolicy: appsv1.PasswordConfig{ Length: 16, NumDigits: 8, NumSymbols: 8, - LetterCase: appsv1alpha1.MixedCases, + LetterCase: appsv1.MixedCases, }, }, { Name: "admin", Statement: "CREATE USER $(USERNAME) IDENTIFIED BY '$(PASSWORD)'; GRANT ALL PRIVILEGES ON *.* TO $(USERNAME);", - PasswordGenerationPolicy: appsv1alpha1.PasswordConfig{ + PasswordGenerationPolicy: appsv1.PasswordConfig{ Length: 10, NumDigits: 5, NumSymbols: 0, - LetterCase: appsv1alpha1.MixedCases, + LetterCase: appsv1.MixedCases, }, }, }, - UpdateStrategy: &[]appsv1alpha1.UpdateStrategy{appsv1alpha1.BestEffortParallelStrategy}[0], - Roles: []appsv1alpha1.ReplicaRole{ + UpdateStrategy: &[]appsv1.UpdateStrategy{appsv1.BestEffortParallelStrategy}[0], + Roles: []appsv1.ReplicaRole{ { Name: "leader", Serviceable: true, @@ -227,15 +226,15 @@ var ( Votable: false, }, }, - Exporter: &appsv1alpha1.Exporter{ + Exporter: &appsv1.Exporter{ ScrapePath: "metrics", ScrapePort: "http-metric", - ScrapeScheme: appsv1alpha1.HTTPProtocol, + ScrapeScheme: appsv1.HTTPProtocol, }, - LifecycleActions: &appsv1alpha1.ComponentLifecycleActions{ + LifecycleActions: &appsv1.ComponentLifecycleActions{ PostProvision: nil, PreTerminate: nil, - RoleProbe: &appsv1alpha1.Probe{ + RoleProbe: &appsv1.Probe{ Action: *NewLifecycleAction("role-probe"), PeriodSeconds: 1, }, @@ -251,9 +250,9 @@ var ( }, } - DefaultCompDefConfigs = []appsv1alpha1.ComponentConfigSpec{ + DefaultCompDefConfigs = []appsv1.ComponentConfigSpec{ { - ComponentTemplateSpec: appsv1alpha1.ComponentTemplateSpec{ + ComponentTemplateSpec: appsv1.ComponentTemplateSpec{ Name: DefaultConfigSpecName, TemplateRef: DefaultConfigSpecTplRef, VolumeName: DefaultConfigSpecVolumeName, @@ -262,7 +261,7 @@ var ( }, } - DefaultCompDefScripts = []appsv1alpha1.ComponentTemplateSpec{ + DefaultCompDefScripts = []appsv1.ComponentTemplateSpec{ { Name: DefaultScriptSpecName, TemplateRef: DefaultScriptSpecTplRef, From ab752e42cdecb56f9fbab32ba536e4bc29f0cf51 Mon Sep 17 00:00:00 2001 From: Leon Date: Tue, 3 Sep 2024 23:50:23 +0800 Subject: [PATCH 07/15] cluster --- apis/apps/v1/cluster_types.go | 800 +- apis/apps/v1/legacy.go | 239 + apis/apps/v1/types.go | 7 + apis/apps/v1/zz_generated.deepcopy.go | 389 +- apis/apps/v1alpha1/opsrequest_types.go | 10 +- apis/apps/v1alpha1/opsrequest_validation.go | 43 +- apis/apps/v1alpha1/type.go | 6 +- apis/apps/v1alpha1/zz_generated.deepcopy.go | 9 +- .../bases/apps.kubeblocks.io_clusters.yaml | 16512 +++++++++++++++- controllers/apps/cluster_controller.go | 6 +- controllers/apps/cluster_controller_test.go | 268 +- controllers/apps/cluster_plan_builder.go | 32 +- controllers/apps/cluster_plan_builder_test.go | 4 +- controllers/apps/cluster_status_conditions.go | 18 +- .../apps/clusterdefinition_controller.go | 5 +- controllers/apps/component_controller_test.go | 206 +- .../apps/component_hscale_volume_populator.go | 8 +- controllers/apps/component_plan_builder.go | 5 +- .../apps/componentversion_controller.go | 3 +- .../configconstraint_controller.go | 3 +- .../apps/configuration/configuration_test.go | 8 +- .../apps/configuration/policy_util_test.go | 5 +- .../apps/configuration/reconfigure_policy.go | 5 +- controllers/apps/operations/backup.go | 9 +- controllers/apps/operations/backup_test.go | 5 +- controllers/apps/operations/custom.go | 2 +- .../apps/operations/custom/action_exec.go | 15 +- .../apps/operations/custom/action_workload.go | 13 +- controllers/apps/operations/custom/utils.go | 11 +- controllers/apps/operations/custom_test.go | 2 +- .../apps/operations/custom_workflow.go | 3 +- controllers/apps/operations/expose.go | 17 +- .../apps/operations/horizontal_scaling.go | 29 +- .../operations/horizontal_scaling_test.go | 43 +- .../apps/operations/ops_comp_helper.go | 20 +- .../apps/operations/ops_progress_util.go | 3 +- .../apps/operations/ops_progress_util_test.go | 5 +- controllers/apps/operations/ops_util.go | 10 +- controllers/apps/operations/ops_util_test.go | 9 +- .../apps/operations/rebuild_instance.go | 21 +- .../apps/operations/rebuild_instance_test.go | 9 +- .../apps/operations/reconfigure_test.go | 14 +- controllers/apps/operations/restart_test.go | 8 +- controllers/apps/operations/restore.go | 17 +- controllers/apps/operations/restore_test.go | 11 +- controllers/apps/operations/start.go | 7 +- controllers/apps/operations/start_test.go | 3 +- controllers/apps/operations/stop.go | 11 +- controllers/apps/operations/suite_test.go | 10 +- controllers/apps/operations/switchover.go | 27 +- .../apps/operations/switchover_test.go | 8 +- .../apps/operations/switchover_util.go | 8 +- controllers/apps/operations/type.go | 12 +- controllers/apps/operations/upgrade.go | 12 +- controllers/apps/operations/upgrade_test.go | 26 +- .../apps/operations/util/common_util.go | 7 +- .../apps/operations/util/common_util_test.go | 3 +- .../apps/operations/vertical_scaling.go | 15 +- .../apps/operations/vertical_scaling_test.go | 5 +- .../apps/operations/volume_expansion.go | 20 +- .../apps/operations/volume_expansion_test.go | 16 +- controllers/apps/opsrequest_controller.go | 17 +- .../apps/opsrequest_controller_test.go | 88 +- .../apps/servicedescriptor_controller.go | 3 +- controllers/apps/transform_utils.go | 8 +- controllers/apps/transform_utils_test.go | 10 +- .../transformer_cluster_api_normalization.go | 41 +- .../apps/transformer_cluster_backup_policy.go | 15 +- .../apps/transformer_cluster_component.go | 26 +- .../transformer_cluster_component_status.go | 29 +- .../transformer_cluster_component_test.go | 7 +- .../apps/transformer_cluster_deletion.go | 12 +- .../apps/transformer_cluster_deletion_test.go | 2 +- controllers/apps/transformer_cluster_halt.go | 6 +- .../transformer_cluster_halt_recovering.go | 20 +- controllers/apps/transformer_cluster_init.go | 4 +- .../transformer_cluster_load_resources.go | 31 +- ...transformer_cluster_load_resources_test.go | 20 +- .../apps/transformer_cluster_ownership.go | 4 +- .../apps/transformer_cluster_restore.go | 10 +- .../apps/transformer_cluster_secret.go | 4 +- .../apps/transformer_cluster_service.go | 37 +- .../apps/transformer_cluster_status.go | 74 +- .../transformer_component_custom_volumes.go | 8 +- .../apps/transformer_component_deletion.go | 12 +- .../transformer_component_load_resources.go | 4 +- .../transformer_component_pre_terminate.go | 3 +- .../apps/transformer_component_rbac.go | 4 +- .../apps/transformer_component_rbac_test.go | 5 +- .../apps/transformer_component_status.go | 2 +- .../apps/transformer_component_tls_test.go | 17 +- .../apps/transformer_component_workload.go | 9 +- .../dataprotection/backup_controller.go | 14 +- .../dataprotection/backup_controller_test.go | 6 +- controllers/dataprotection/utils.go | 8 +- .../nodecountscaler_controller.go | 4 +- .../reconciler_scale_target_cluster.go | 4 +- .../reconciler_scale_target_cluster_test.go | 4 +- controllers/experimental/suite_test.go | 6 +- controllers/experimental/tree_loader.go | 4 +- controllers/experimental/tree_loader_test.go | 6 +- .../extensions/addon_controller_stages.go | 4 +- .../extensions/addon_controller_test.go | 6 +- controllers/k8score/event_controller_test.go | 4 +- .../crds/apps.kubeblocks.io_clusters.yaml | 16512 +++++++++++++++- docs/developer_docs/api-reference/cluster.md | 2098 +- pkg/configuration/config_manager/builder.go | 7 +- .../config_manager/builder_test.go | 3 +- .../config_manager/handler_util.go | 3 +- pkg/configuration/core/config_query.go | 2 +- pkg/configuration/core/type_test.go | 3 +- pkg/controller/builder/builder_cluster.go | 8 +- .../builder/builder_cluster_test.go | 4 +- pkg/controller/builder/builder_component.go | 6 +- pkg/controller/component/component.go | 13 +- pkg/controller/component/component_test.go | 3 +- pkg/controller/component/lifecycle/kbagent.go | 7 +- .../component/lifecycle/lifecycle_test.go | 19 +- .../component/synthesize_component.go | 17 +- pkg/controller/component/vars_test.go | 733 +- pkg/controller/component/workload_utils.go | 12 +- .../configuration/builtin_env_test.go | 8 +- .../configuration/builtin_objects.go | 6 +- .../configuration/config_template.go | 9 +- .../configuration/config_template_test.go | 8 +- pkg/controller/configuration/config_utils.go | 4 +- .../configuration/configuration_test.go | 7 +- pkg/controller/configuration/envfrom_utils.go | 5 +- .../configuration/envfrom_utils_test.go | 3 +- pkg/controller/configuration/operator.go | 3 +- pkg/controller/configuration/operator_test.go | 2 +- pkg/controller/configuration/pipeline.go | 2 +- pkg/controller/configuration/pipeline_test.go | 2 +- .../configuration/resource_wrapper.go | 6 +- .../configuration/resource_wrapper_test.go | 4 +- .../configuration/template_merger.go | 2 +- .../configuration/template_merger_test.go | 39 +- .../configuration/template_wrapper.go | 14 +- .../configuration/template_wrapper_test.go | 3 +- .../configuration/tool_image_builder_test.go | 11 +- pkg/controller/factory/builder.go | 13 +- pkg/controller/factory/builder_test.go | 7 +- pkg/controller/job/job_utils.go | 17 +- pkg/controller/job/job_utils_test.go | 4 +- pkg/controller/plan/prepare.go | 3 +- pkg/controller/plan/prepare_test.go | 3 +- pkg/controller/plan/restore.go | 12 +- pkg/controller/plan/restore_test.go | 19 +- pkg/controller/scheduling/scheduling_utils.go | 181 +- .../scheduling/scheduling_utils_test.go | 169 - pkg/controller/scheduling/suite_test.go | 91 - pkg/controllerutil/cluster_utils.go | 4 +- pkg/controllerutil/cluster_utils_test.go | 6 +- pkg/controllerutil/controller_common.go | 6 +- pkg/controllerutil/sharding_utils.go | 23 +- pkg/controllerutil/sharding_utils_test.go | 10 +- pkg/controllerutil/util.go | 5 +- pkg/dataprotection/backup/scheduler.go | 5 +- pkg/dataprotection/backup/scheduler_test.go | 8 +- pkg/generics/type.go | 2 +- pkg/testutil/apps/cluster_factory.go | 135 +- .../apps/cluster_instance_set_test_util.go | 11 +- pkg/testutil/apps/cluster_util.go | 22 +- pkg/testutil/apps/common_util.go | 4 +- pkg/testutil/dataprotection/types.go | 4 +- 165 files changed, 37713 insertions(+), 2298 deletions(-) create mode 100644 apis/apps/v1/legacy.go delete mode 100644 pkg/controller/scheduling/scheduling_utils_test.go delete mode 100644 pkg/controller/scheduling/suite_test.go diff --git a/apis/apps/v1/cluster_types.go b/apis/apps/v1/cluster_types.go index a8367830472..d239dec52f9 100644 --- a/apis/apps/v1/cluster_types.go +++ b/apis/apps/v1/cluster_types.go @@ -20,7 +20,11 @@ along with this program. If not, see . package v1 import ( + corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/intstr" + + dpv1alpha1 "github.com/apecloud/kubeblocks/apis/dataprotection/v1alpha1" ) // +genclient @@ -80,17 +84,797 @@ func init() { SchemeBuilder.Register(&Cluster{}, &ClusterList{}) } -// ClusterSpec defines the desired state of Cluster +// ClusterSpec defines the desired state of Cluster. type ClusterSpec struct { - // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster - // Important: Run "make" to regenerate code after modifying this file + // Specifies the name of the ClusterDefinition to use when creating a Cluster. + // + // This field enables users to create a Cluster based on a specific ClusterDefinition. + // Which, in conjunction with the `topology` field, determine: + // + // - The Components to be included in the Cluster. + // - The sequences in which the Components are created, updated, and terminate. + // + // This facilitates multiple-components management with predefined ClusterDefinition. + // + // Users with advanced requirements can bypass this general setting and specify more precise control over + // the composition of the Cluster by directly referencing specific ComponentDefinitions for each component + // within `componentSpecs[*].componentDef`. + // + // If this field is not provided, each component must be explicitly defined in `componentSpecs[*].componentDef`. + // + // Note: Once set, this field cannot be modified; it is immutable. + // + // +kubebuilder:validation:MaxLength=63 + // +kubebuilder:validation:Pattern:=`^[a-z0-9]([a-z0-9\.\-]*[a-z0-9])?$` + // +kubebuilder:validation:XValidation:rule="self == oldSelf",message="clusterDefinitionRef is immutable" + // +optional + ClusterDefRef string `json:"clusterDefinitionRef,omitempty"` + + // Refers to the ClusterVersion name. + // + // Deprecated since v0.9, use ComponentVersion instead. + // This field is maintained for backward compatibility and its use is discouraged. + // Existing usage should be updated to the current preferred approach to avoid compatibility issues in future releases. + // + // +kubebuilder:validation:MaxLength=63 + // +kubebuilder:validation:Pattern:=`^[a-z0-9]([a-z0-9\.\-]*[a-z0-9])?$` + // +kubebuilder:deprecatedversion:warning="This field has been deprecated since 0.9.0" + // +optional + ClusterVersionRef string `json:"clusterVersionRef,omitempty"` + + // Specifies the name of the ClusterTopology to be used when creating the Cluster. + // + // This field defines which set of Components, as outlined in the ClusterDefinition, will be used to + // construct the Cluster based on the named topology. + // The ClusterDefinition may list multiple topologies under `clusterdefinition.spec.topologies[*]`, + // each tailored to different use cases or environments. + // + // If `topology` is not specified, the Cluster will use the default topology defined in the ClusterDefinition. + // + // Note: Once set during the Cluster creation, the `topology` field cannot be modified. + // It establishes the initial composition and structure of the Cluster and is intended for one-time configuration. + // + // +kubebuilder:validation:MaxLength=32 + // +optional + Topology string `json:"topology,omitempty"` + + // Specifies the behavior when a Cluster is deleted. + // It defines how resources, data, and backups associated with a Cluster are managed during termination. + // Choose a policy based on the desired level of resource cleanup and data preservation: + // + // - `DoNotTerminate`: Prevents deletion of the Cluster. This policy ensures that all resources remain intact. + // - `Halt`: Deletes Cluster resources like Pods and Services but retains Persistent Volume Claims (PVCs), + // allowing for data preservation while stopping other operations. + // - `Delete`: Extends the `Halt` policy by also removing PVCs, leading to a thorough cleanup while + // removing all persistent data. + // - `WipeOut`: An aggressive policy that deletes all Cluster resources, including volume snapshots and + // backups in external storage. + // This results in complete data removal and should be used cautiously, primarily in non-production environments + // to avoid irreversible data loss. + // + // Warning: Choosing an inappropriate termination policy can result in data loss. + // The `WipeOut` policy is particularly risky in production environments due to its irreversible nature. + // + // +kubebuilder:validation:Required + TerminationPolicy TerminationPolicyType `json:"terminationPolicy"` + + // Specifies a list of ClusterComponentSpec objects used to define the individual Components that make up a Cluster. + // This field allows for detailed configuration of each Component within the Cluster. + // + // Note: `shardingSpecs` and `componentSpecs` cannot both be empty; at least one must be defined to configure a Cluster. + // + // +kubebuilder:validation:MinItems=1 + // +kubebuilder:validation:MaxItems=128 + // +kubebuilder:validation:XValidation:rule="self.all(x, size(self.filter(c, c.name == x.name)) == 1)",message="duplicated component" + // +kubebuilder:validation:XValidation:rule="self.all(x, size(self.filter(c, has(c.componentDef))) == 0) || self.all(x, size(self.filter(c, has(c.componentDef))) == size(self))",message="two kinds of definition API can not be used simultaneously" + // +optional + ComponentSpecs []ClusterComponentSpec `json:"componentSpecs,omitempty" patchStrategy:"merge,retainKeys" patchMergeKey:"name"` + + // Specifies a list of ShardingSpec objects that manage the sharding topology for Cluster Components. + // Each ShardingSpec organizes components into shards, with each shard corresponding to a Component. + // Components within a shard are all based on a common ClusterComponentSpec template, ensuring uniform configurations. + // + // This field supports dynamic resharding by facilitating the addition or removal of shards + // through the `shards` field in ShardingSpec. + // + // Note: `shardingSpecs` and `componentSpecs` cannot both be empty; at least one must be defined to configure a Cluster. + // + // +patchMergeKey=name + // +patchStrategy=merge,retainKeys + // +listType=map + // +listMapKey=name + // +kubebuilder:validation:MinItems=1 + // +kubebuilder:validation:MaxItems=128 + // +optional + ShardingSpecs []ShardingSpec `json:"shardingSpecs,omitempty"` + + // Specifies runtimeClassName for all Pods managed by this Cluster. + // + // +optional + RuntimeClassName *string `json:"runtimeClassName,omitempty"` - // Foo is an example field of Cluster. Edit cluster_types.go to remove/update - Foo string `json:"foo,omitempty"` + // Specifies the scheduling policy for the Cluster. + // + // +optional + SchedulingPolicy *SchedulingPolicy `json:"schedulingPolicy,omitempty"` + + // Defines a list of additional Services that are exposed by a Cluster. + // This field allows Services of selected Components, either from `componentSpecs` or `shardingSpecs` to be exposed, + // alongside Services defined with ComponentService. + // + // Services defined here can be referenced by other clusters using the ServiceRefClusterSelector. + // + // +kubebuilder:pruning:PreserveUnknownFields + // +optional + Services []ClusterService `json:"services,omitempty"` + + // Specifies the backup configuration of the Cluster. + // + // +optional + Backup *ClusterBackup `json:"backup,omitempty"` } -// ClusterStatus defines the observed state of Cluster +// ClusterStatus defines the observed state of the Cluster. type ClusterStatus struct { - // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster - // Important: Run "make" to regenerate code after modifying this file + // The most recent generation number of the Cluster object that has been observed by the controller. + // + // +optional + ObservedGeneration int64 `json:"observedGeneration,omitempty"` + + // The current phase of the Cluster includes: + // `Creating`, `Running`, `Updating`, `Stopping`, `Stopped`, `Deleting`, `Failed`, `Abnormal`. + // + // +optional + Phase ClusterPhase `json:"phase,omitempty"` + + // Provides additional information about the current phase. + // + // +optional + Message string `json:"message,omitempty"` + + // Records the current status information of all Components within the Cluster. + // + // +optional + Components map[string]ClusterComponentStatus `json:"components,omitempty"` + + // Represents the generation number of the referenced ClusterDefinition. + // + // +optional + ClusterDefGeneration int64 `json:"clusterDefGeneration,omitempty"` + + // Represents a list of detailed status of the Cluster object. + // Each condition in the list provides real-time information about certain aspect of the Cluster object. + // + // This field is crucial for administrators and developers to monitor and respond to changes within the Cluster. + // It provides a history of state transitions and a snapshot of the current state that can be used for + // automated logic or direct inspection. + // + // +optional + Conditions []metav1.Condition `json:"conditions,omitempty"` +} + +// TerminationPolicyType defines termination policy types. +// +// +enum +// +kubebuilder:validation:Enum={DoNotTerminate,Halt,Delete,WipeOut} +type TerminationPolicyType string + +const ( + // DoNotTerminate will block delete operation. + DoNotTerminate TerminationPolicyType = "DoNotTerminate" + + // Halt will delete workload resources such as statefulset, deployment workloads but keep PVCs. + Halt TerminationPolicyType = "Halt" + + // Delete is based on Halt and deletes PVCs. + Delete TerminationPolicyType = "Delete" + + // WipeOut is based on Delete and wipe out all volume snapshots and snapshot data from backup storage location. + WipeOut TerminationPolicyType = "WipeOut" +) + +// ClusterComponentSpec defines the specification of a Component within a Cluster. +// TODO +kubebuilder:validation:XValidation:rule="!has(oldSelf.componentDefRef) || has(self.componentDefRef)", message="componentDefRef is required once set" +// TODO +kubebuilder:validation:XValidation:rule="!has(oldSelf.componentDef) || has(self.componentDef)", message="componentDef is required once set" +type ClusterComponentSpec struct { + // Specifies the Component's name. + // It's part of the Service DNS name and must comply with the IANA service naming rule. + // The name is optional when ClusterComponentSpec is used as a template (e.g., in `shardingSpec`), + // but required otherwise. + // + // +kubebuilder:validation:MaxLength=22 + // +kubebuilder:validation:Pattern:=`^[a-z]([a-z0-9\-]*[a-z0-9])?$` + // TODO +kubebuilder:validation:XValidation:rule="self == oldSelf",message="name is immutable" + // +optional + Name string `json:"name"` + + // References a ClusterComponentDefinition defined in the `clusterDefinition.spec.componentDef` field. + // Must comply with the IANA service naming rule. + // + // Deprecated since v0.9, + // because defining Components in `clusterDefinition.spec.componentDef` field has been deprecated. + // This field is replaced by the `componentDef` field, use `componentDef` instead. + // This field is maintained for backward compatibility and its use is discouraged. + // Existing usage should be updated to the current preferred approach to avoid compatibility issues in future releases. + // + // +kubebuilder:validation:MaxLength=22 + // +kubebuilder:validation:Pattern:=`^[a-z]([a-z0-9\-]*[a-z0-9])?$` + // TODO +kubebuilder:validation:XValidation:rule="self == oldSelf",message="componentDefRef is immutable" + // +kubebuilder:deprecatedversion:warning="This field has been deprecated since 0.9.0, consider using the ComponentDef instead" + // +optional + ComponentDefRef string `json:"componentDefRef,omitempty"` + + // References the name of a ComponentDefinition object. + // The ComponentDefinition specifies the behavior and characteristics of the Component. + // If both `componentDefRef` and `componentDef` are provided, + // the `componentDef` will take precedence over `componentDefRef`. + // + // +kubebuilder:validation:MaxLength=64 + // +kubebuilder:validation:Pattern:=`^[a-z0-9]([a-z0-9\.\-]*[a-z0-9])?$` + // +optional + ComponentDef string `json:"componentDef,omitempty"` + + // ServiceVersion specifies the version of the Service expected to be provisioned by this Component. + // The version should follow the syntax and semantics of the "Semantic Versioning" specification (http://semver.org/). + // If no version is specified, the latest available version will be used. + // + // +kubebuilder:validation:MaxLength=32 + // +optional + ServiceVersion string `json:"serviceVersion,omitempty"` + + // Defines a list of ServiceRef for a Component, enabling access to both external services and + // Services provided by other Clusters. + // + // Types of services: + // + // - External services: Not managed by KubeBlocks or managed by a different KubeBlocks operator; + // Require a ServiceDescriptor for connection details. + // - Services provided by a Cluster: Managed by the same KubeBlocks operator; + // identified using Cluster, Component and Service names. + // + // ServiceRefs with identical `serviceRef.name` in the same Cluster are considered the same. + // + // Example: + // ```yaml + // serviceRefs: + // - name: "redis-sentinel" + // serviceDescriptor: + // name: "external-redis-sentinel" + // - name: "postgres-cluster" + // clusterServiceSelector: + // cluster: "my-postgres-cluster" + // service: + // component: "postgresql" + // ``` + // The example above includes ServiceRefs to an external Redis Sentinel service and a PostgreSQL Cluster. + // + // +optional + ServiceRefs []ServiceRef `json:"serviceRefs,omitempty"` + + // Specifies which types of logs should be collected for the Component. + // The log types are defined in the `componentDefinition.spec.logConfigs` field with the LogConfig entries. + // + // The elements in the `enabledLogs` array correspond to the names of the LogConfig entries. + // For example, if the `componentDefinition.spec.logConfigs` defines LogConfig entries with + // names "slow_query_log" and "error_log", + // you can enable the collection of these logs by including their names in the `enabledLogs` array: + // ```yaml + // enabledLogs: + // - slow_query_log + // - error_log + // ``` + // + // +listType=set + // +optional + EnabledLogs []string `json:"enabledLogs,omitempty"` + + // Specifies Labels to override or add for underlying Pods. + // + // +optional + Labels map[string]string `json:"labels,omitempty"` + + // Specifies Annotations to override or add for underlying Pods. + // + // +optional + Annotations map[string]string `json:"annotations,omitempty"` + + // List of environment variables to add. + // These environment variables will be placed after the environment variables declared in the Pod. + // + // +optional + Env []corev1.EnvVar `json:"env,omitempty"` + + // Specifies the desired number of replicas in the Component for enhancing availability and durability, or load balancing. + // + // +kubebuilder:validation:Required + // +kubebuilder:validation:Minimum=0 + // +kubebuilder:default=1 + Replicas int32 `json:"replicas"` + + // Specifies the scheduling policy for the Component. + // + // +optional + SchedulingPolicy *SchedulingPolicy `json:"schedulingPolicy,omitempty"` + + // Specifies the resources required by the Component. + // It allows defining the CPU, memory requirements and limits for the Component's containers. + // + // +kubebuilder:pruning:PreserveUnknownFields + // +optional + Resources corev1.ResourceRequirements `json:"resources,omitempty"` + + // Specifies a list of PersistentVolumeClaim templates that represent the storage requirements for the Component. + // Each template specifies the desired characteristics of a persistent volume, such as storage class, + // size, and access modes. + // These templates are used to dynamically provision persistent volumes for the Component. + // + // +patchMergeKey=name + // +patchStrategy=merge,retainKeys + // +optional + VolumeClaimTemplates []ClusterComponentVolumeClaimTemplate `json:"volumeClaimTemplates,omitempty" patchStrategy:"merge,retainKeys" patchMergeKey:"name"` + + // List of volumes to override. + // + // +optional + Volumes []corev1.Volume `json:"volumes,omitempty"` + + // Overrides services defined in referenced ComponentDefinition and expose endpoints that can be accessed by clients. + // + // +optional + Services []ClusterComponentService `json:"services,omitempty"` + + // Overrides system accounts defined in referenced ComponentDefinition. + // + // +optional + SystemAccounts []ComponentSystemAccount `json:"systemAccounts,omitempty"` + + // Specifies the configuration content of a config template. + // + // +optional + Configs []ClusterComponentConfig `json:"configs,omitempty"` + + // A boolean flag that indicates whether the Component should use Transport Layer Security (TLS) + // for secure communication. + // When set to true, the Component will be configured to use TLS encryption for its network connections. + // This ensures that the data transmitted between the Component and its clients or other Components is encrypted + // and protected from unauthorized access. + // If TLS is enabled, the Component may require additional configuration, such as specifying TLS certificates and keys, + // to properly set up the secure communication channel. + // + // +optional + TLS bool `json:"tls,omitempty"` + + // Specifies the configuration for the TLS certificates issuer. + // It allows defining the issuer name and the reference to the secret containing the TLS certificates and key. + // The secret should contain the CA certificate, TLS certificate, and private key in the specified keys. + // Required when TLS is enabled. + // + // +optional + Issuer *Issuer `json:"issuer,omitempty"` + + // Specifies the name of the ServiceAccount required by the running Component. + // This ServiceAccount is used to grant necessary permissions for the Component's Pods to interact + // with other Kubernetes resources, such as modifying Pod labels or sending events. + // + // Defaults: + // To perform certain operational tasks, agent sidecars running in Pods require specific RBAC permissions. + // The service account will be bound to a default role named "kubeblocks-cluster-pod-role" which is installed together with KubeBlocks. + // If not specified, KubeBlocks automatically assigns a default ServiceAccount named "kb-{cluster.name}" + // + // Future Changes: + // Future versions might change the default ServiceAccount creation strategy to one per Component, + // potentially revising the naming to "kb-{cluster.name}-{component.name}". + // + // Users can override the automatic ServiceAccount assignment by explicitly setting the name of + // an existed ServiceAccount in this field. + // + // +optional + ServiceAccountName string `json:"serviceAccountName,omitempty"` + + // Defines the update strategy for the Component. + // + // Deprecated since v0.9. + // This field is maintained for backward compatibility and its use is discouraged. + // Existing usage should be updated to the current preferred approach to avoid compatibility issues in future releases. + // + // +kubebuilder:deprecatedversion:warning="This field has been deprecated since 0.9.0" + // +optional + UpdateStrategy *UpdateStrategy `json:"updateStrategy,omitempty"` + + // Controls the concurrency of pods during initial scale up, when replacing pods on nodes, + // or when scaling down. It only used when `PodManagementPolicy` is set to `Parallel`. + // The default Concurrency is 100%. + // + // +optional + ParallelPodManagementConcurrency *intstr.IntOrString `json:"parallelPodManagementConcurrency,omitempty"` + + // PodUpdatePolicy indicates how pods should be updated + // + // - `StrictInPlace` indicates that only allows in-place upgrades. + // Any attempt to modify other fields will be rejected. + // - `PreferInPlace` indicates that we will first attempt an in-place upgrade of the Pod. + // If that fails, it will fall back to the ReCreate, where pod will be recreated. + // Default value is "PreferInPlace" + // + // +kubebuilder:validation:Enum={StrictInPlace,PreferInPlace} + // +optional + PodUpdatePolicy *PodUpdatePolicyType `json:"podUpdatePolicy,omitempty"` + + // Allows users to specify custom ConfigMaps and Secrets to be mounted as volumes + // in the Cluster's Pods. + // This is useful in scenarios where users need to provide additional resources to the Cluster, such as: + // + // - Mounting custom scripts or configuration files during Cluster startup. + // - Mounting Secrets as volumes to provide sensitive information, like S3 AK/SK, to the Cluster. + // + // +optional + UserResourceRefs *UserResourceRefs `json:"userResourceRefs,omitempty"` + + // Allows for the customization of configuration values for each instance within a Component. + // An instance represent a single replica (Pod and associated K8s resources like PVCs, Services, and ConfigMaps). + // While instances typically share a common configuration as defined in the ClusterComponentSpec, + // they can require unique settings in various scenarios: + // + // For example: + // - A database Component might require different resource allocations for primary and secondary instances, + // with primaries needing more resources. + // - During a rolling upgrade, a Component may first update the image for one or a few instances, + // and then update the remaining instances after verifying that the updated instances are functioning correctly. + // + // InstanceTemplate allows for specifying these unique configurations per instance. + // Each instance's name is constructed using the pattern: $(component.name)-$(template.name)-$(ordinal), + // starting with an ordinal of 0. + // It is crucial to maintain unique names for each InstanceTemplate to avoid conflicts. + // + // The sum of replicas across all InstanceTemplates should not exceed the total number of replicas specified for the Component. + // Any remaining replicas will be generated using the default template and will follow the default naming rules. + // + // +optional + // +patchMergeKey=name + // +patchStrategy=merge,retainKeys + // +listType=map + // +listMapKey=name + Instances []InstanceTemplate `json:"instances,omitempty" patchStrategy:"merge,retainKeys" patchMergeKey:"name"` + + // Specifies the names of instances to be transitioned to offline status. + // + // Marking an instance as offline results in the following: + // + // 1. The associated Pod is stopped, and its PersistentVolumeClaim (PVC) is retained for potential + // future reuse or data recovery, but it is no longer actively used. + // 2. The ordinal number assigned to this instance is preserved, ensuring it remains unique + // and avoiding conflicts with new instances. + // + // Setting instances to offline allows for a controlled scale-in process, preserving their data and maintaining + // ordinal consistency within the Cluster. + // Note that offline instances and their associated resources, such as PVCs, are not automatically deleted. + // The administrator must manually manage the cleanup and removal of these resources when they are no longer needed. + // + // +optional + OfflineInstances []string `json:"offlineInstances,omitempty"` + + // Determines whether metrics exporter information is annotated on the Component's headless Service. + // + // If set to true, the following annotations will not be patched into the Service: + // + // - "monitor.kubeblocks.io/path" + // - "monitor.kubeblocks.io/port" + // - "monitor.kubeblocks.io/scheme" + // + // These annotations allow the Prometheus installed by KubeBlocks to discover and scrape metrics from the exporter. + // + // +optional + DisableExporter *bool `json:"disableExporter,omitempty"` + + // Deprecated since v0.9 + // Determines whether metrics exporter information is annotated on the Component's headless Service. + // + // If set to true, the following annotations will be patched into the Service: + // + // - "monitor.kubeblocks.io/path" + // - "monitor.kubeblocks.io/port" + // - "monitor.kubeblocks.io/scheme" + // + // These annotations allow the Prometheus installed by KubeBlocks to discover and scrape metrics from the exporter. + // + // +optional + // +kubebuilder:deprecatedversion:warning="This field has been deprecated since 0.10.0" + Monitor *bool `json:"monitor,omitempty"` + + // Stop the Component. + // If set, all the computing resources will be released. + // + // +optional + Stop *bool `json:"stop,omitempty"` +} + +type ClusterComponentService struct { + // References the ComponentService name defined in the `componentDefinition.spec.services[*].name`. + // + // +kubebuilder:validation:Required + // +kubebuilder:validation:MaxLength=25 + Name string `json:"name"` + + // Determines how the Service is exposed. Valid options are `ClusterIP`, `NodePort`, and `LoadBalancer`. + // + // - `ClusterIP` allocates a Cluster-internal IP address for load-balancing to endpoints. + // Endpoints are determined by the selector or if that is not specified, + // they are determined by manual construction of an Endpoints object or EndpointSlice objects. + // - `NodePort` builds on ClusterIP and allocates a port on every node which routes to the same endpoints as the ClusterIP. + // - `LoadBalancer` builds on NodePort and creates an external load-balancer (if supported in the current cloud) + // which routes to the same endpoints as the ClusterIP. + // + // Note: although K8s Service type allows the 'ExternalName' type, it is not a valid option for ClusterComponentService. + // + // For more info, see: + // https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types. + // + // +kubebuilder:default=ClusterIP + // +kubebuilder:validation:Enum={ClusterIP,NodePort,LoadBalancer} + // +kubebuilder:pruning:PreserveUnknownFields + // +optional + ServiceType corev1.ServiceType `json:"serviceType,omitempty"` + + // If ServiceType is LoadBalancer, cloud provider related parameters can be put here. + // More info: https://kubernetes.io/docs/concepts/services-networking/service/#loadbalancer. + // + // +optional + Annotations map[string]string `json:"annotations,omitempty"` + + // Indicates whether to generate individual Services for each Pod. + // If set to true, a separate Service will be created for each Pod in the Cluster. + // + // +optional + PodService *bool `json:"podService,omitempty"` +} + +// UserResourceRefs defines references to user-defined Secrets and ConfigMaps. +type UserResourceRefs struct { + // SecretRefs defines the user-defined Secrets. + // + // +patchMergeKey=name + // +patchStrategy=merge,retainKeys + // +listType=map + // +listMapKey=name + // +optional + SecretRefs []SecretRef `json:"secretRefs,omitempty"` + + // ConfigMapRefs defines the user-defined ConfigMaps. + // + // +patchMergeKey=name + // +patchStrategy=merge,retainKeys + // +listType=map + // +listMapKey=name + // +optional + ConfigMapRefs []ConfigMapRef `json:"configMapRefs,omitempty"` +} + +// SecretRef defines a reference to a Secret. +type SecretRef struct { + ResourceMeta `json:",inline"` + + // Secret specifies the Secret to be mounted as a volume. + // + // +kubebuilder:validation:Required + Secret corev1.SecretVolumeSource `json:"secret"` +} + +// ConfigMapRef defines a reference to a ConfigMap. +type ConfigMapRef struct { + ResourceMeta `json:",inline"` + + // ConfigMap specifies the ConfigMap to be mounted as a volume. + // + // +kubebuilder:validation:Required + ConfigMap corev1.ConfigMapVolumeSource `json:"configMap"` +} + +// ResourceMeta encapsulates metadata and configuration for referencing ConfigMaps and Secrets as volumes. +type ResourceMeta struct { + // Name is the name of the referenced ConfigMap or Secret object. It must conform to DNS label standards. + // + // +kubebuilder:validation:Required + // +kubebuilder:validation:MaxLength=63 + // +kubebuilder:validation:Pattern:=`^[a-z0-9]([a-z0-9\.\-]*[a-z0-9])?$` + Name string `json:"name"` + + // MountPoint is the filesystem path where the volume will be mounted. + // + // +kubebuilder:validation:Required + // +kubebuilder:validation:MaxLength=256 + // +kubebuilder:validation:Pattern:=`^/[a-z]([a-z0-9\-]*[a-z0-9])?$` + MountPoint string `json:"mountPoint"` + + // SubPath specifies a path within the volume from which to mount. + // + // +optional + SubPath string `json:"subPath,omitempty"` + + // AsVolumeFrom lists the names of containers in which the volume should be mounted. + // + // +listType=set + // +optional + AsVolumeFrom []string `json:"asVolumeFrom,omitempty"` +} + +// ShardingSpec defines how KubeBlocks manage dynamic provisioned shards. +// A typical design pattern for distributed databases is to distribute data across multiple shards, +// with each shard consisting of multiple replicas. +// Therefore, KubeBlocks supports representing a shard with a Component and dynamically instantiating Components +// using a template when shards are added. +// When shards are removed, the corresponding Components are also deleted. +type ShardingSpec struct { + // Represents the common parent part of all shard names. + // This identifier is included as part of the Service DNS name and must comply with IANA service naming rules. + // It is used to generate the names of underlying Components following the pattern `$(shardingSpec.name)-$(ShardID)`. + // ShardID is a random string that is appended to the Name to generate unique identifiers for each shard. + // For example, if the sharding specification name is "my-shard" and the ShardID is "abc", the resulting Component name + // would be "my-shard-abc". + // + // Note that the name defined in Component template(`shardingSpec.template.name`) will be disregarded + // when generating the Component names of the shards. The `shardingSpec.name` field takes precedence. + // + // +kubebuilder:validation:Required + // +kubebuilder:validation:MaxLength=15 + // +kubebuilder:validation:Pattern:=`^[a-z0-9]([a-z0-9\.\-]*[a-z0-9])?$` + // +kubebuilder:validation:XValidation:rule="self == oldSelf",message="name is immutable" + Name string `json:"name"` + + // The template for generating Components for shards, where each shard consists of one Component. + // This field is of type ClusterComponentSpec, which encapsulates all the required details and + // definitions for creating and managing the Components. + // KubeBlocks uses this template to generate a set of identical Components or shards. + // All the generated Components will have the same specifications and definitions as specified in the `template` field. + // + // This allows for the creation of multiple Components with consistent configurations, + // enabling sharding and distribution of workloads across Components. + // + // +kubebuilder:validation:Required + Template ClusterComponentSpec `json:"template"` + + // Specifies the desired number of shards. + // Users can declare the desired number of shards through this field. + // KubeBlocks dynamically creates and deletes Components based on the difference + // between the desired and actual number of shards. + // KubeBlocks provides lifecycle management for sharding, including: + // + // - Executing the postProvision Action defined in the ComponentDefinition when the number of shards increases. + // This allows for custom actions to be performed after a new shard is provisioned. + // - Executing the preTerminate Action defined in the ComponentDefinition when the number of shards decreases. + // This enables custom cleanup or data migration tasks to be executed before a shard is terminated. + // Resources and data associated with the corresponding Component will also be deleted. + // + // +kubebuilder:validation:Required + // +kubebuilder:validation:Minimum=0 + // +kubebuilder:validation:Maximum=2048 + Shards int32 `json:"shards,omitempty"` +} + +// ClusterService defines a service that is exposed externally, allowing entities outside the cluster to access it. +// For example, external applications, or other Clusters. +// And another Cluster managed by the same KubeBlocks operator can resolve the address exposed by a ClusterService +// using the `serviceRef` field. +// +// When a Component needs to access another Cluster's ClusterService using the `serviceRef` field, +// it must also define the service type and version information in the `componentDefinition.spec.serviceRefDeclarations` +// section. +type ClusterService struct { + Service `json:",inline"` + + // Extends the ServiceSpec.Selector by allowing the specification of a sharding name, which is defined in + // `cluster.spec.shardingSpecs[*].name`, to be used as a selector for the service. + // Note that this and the `componentSelector` are mutually exclusive and cannot be set simultaneously. + // + // +optional + ShardingSelector string `json:"shardingSelector,omitempty"` + + // Extends the ServiceSpec.Selector by allowing the specification of a component, to be used as a selector for the service. + // Note that this and the `shardingSelector` are mutually exclusive and cannot be set simultaneously. + // + // +optional + ComponentSelector string `json:"componentSelector,omitempty"` +} + +type ClusterBackup struct { + // Specifies whether automated backup is enabled for the Cluster. + // + // +kubebuilder:default=false + // +optional + Enabled *bool `json:"enabled,omitempty"` + + // Determines the duration to retain backups. Backups older than this period are automatically removed. + // + // For example, RetentionPeriod of `30d` will keep only the backups of last 30 days. + // Sample duration format: + // + // - years: 2y + // - months: 6mo + // - days: 30d + // - hours: 12h + // - minutes: 30m + // + // You can also combine the above durations. For example: 30d12h30m. + // Default value is 7d. + // + // +kubebuilder:default="7d" + // +optional + RetentionPeriod dpv1alpha1.RetentionPeriod `json:"retentionPeriod,omitempty"` + + // Specifies the backup method to use, as defined in backupPolicy. + // + // +kubebuilder:validation:Required + Method string `json:"method"` + + // The cron expression for the schedule. The timezone is in UTC. See https://en.wikipedia.org/wiki/Cron. + // + // +optional + CronExpression string `json:"cronExpression,omitempty"` + + // Specifies the maximum time in minutes that the system will wait to start a missed backup job. + // If the scheduled backup time is missed for any reason, the backup job must start within this deadline. + // Values must be between 0 (immediate execution) and 1440 (one day). + // + // +kubebuilder:validation:Minimum=0 + // +kubebuilder:validation:Maximum=1440 + // +optional + StartingDeadlineMinutes *int64 `json:"startingDeadlineMinutes,omitempty"` + + // Specifies the name of the backupRepo. If not set, the default backupRepo will be used. + // + // +optional + RepoName string `json:"repoName,omitempty"` + + // Specifies whether to enable point-in-time recovery. + // + // +kubebuilder:default=false + // +optional + PITREnabled *bool `json:"pitrEnabled,omitempty"` +} + +// ClusterPhase defines the phase of the Cluster within the .status.phase field. +// +// +enum +// +kubebuilder:validation:Enum={Creating,Running,Updating,Stopping,Stopped,Deleting,Failed,Abnormal} +type ClusterPhase string + +const ( + // CreatingClusterPhase represents all components are in `Creating` phase. + CreatingClusterPhase ClusterPhase = "Creating" + + // RunningClusterPhase represents all components are in `Running` phase, indicates that the cluster is functioning properly. + RunningClusterPhase ClusterPhase = "Running" + + // UpdatingClusterPhase represents all components are in `Creating`, `Running` or `Updating` phase, and at least one + // component is in `Creating` or `Updating` phase, indicates that the cluster is undergoing an update. + UpdatingClusterPhase ClusterPhase = "Updating" + + // StoppingClusterPhase represents at least one component is in `Stopping` phase, indicates that the cluster is in + // the process of stopping. + StoppingClusterPhase ClusterPhase = "Stopping" + + // StoppedClusterPhase represents all components are in `Stopped` phase, indicates that the cluster has stopped and + // is not providing any functionality. + StoppedClusterPhase ClusterPhase = "Stopped" + + // DeletingClusterPhase indicates the cluster is being deleted. + DeletingClusterPhase ClusterPhase = "Deleting" + + // FailedClusterPhase represents all components are in `Failed` phase, indicates that the cluster is unavailable. + FailedClusterPhase ClusterPhase = "Failed" + + // AbnormalClusterPhase represents some components are in `Failed` or `Abnormal` phase, indicates that the cluster + // is in a fragile state and troubleshooting is required. + AbnormalClusterPhase ClusterPhase = "Abnormal" +) + +// ClusterComponentStatus records Component status. +type ClusterComponentStatus struct { + // Specifies the current state of the Component. + Phase ClusterComponentPhase `json:"phase,omitempty"` + + // Records detailed information about the Component in its current phase. + // The keys are either podName, deployName, or statefulSetName, formatted as 'ObjectKind/Name'. + // + // +optional + Message map[string]string `json:"message,omitempty"` } diff --git a/apis/apps/v1/legacy.go b/apis/apps/v1/legacy.go new file mode 100644 index 00000000000..008ad897752 --- /dev/null +++ b/apis/apps/v1/legacy.go @@ -0,0 +1,239 @@ +/* +Copyright (C) 2022-2024 ApeCloud Co., Ltd + +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 v1 + +import ( + "fmt" + "strings" + + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + "github.com/apecloud/kubeblocks/pkg/constant" + viper "github.com/apecloud/kubeblocks/pkg/viperx" +) + +const ( + defaultInstanceTemplateReplicas = 1 +) + +func (r *Cluster) IsDeleting() bool { + if r.GetDeletionTimestamp().IsZero() { + return false + } + return r.Spec.TerminationPolicy != DoNotTerminate +} + +func (r *Cluster) IsUpdating() bool { + return r.Status.ObservedGeneration != r.Generation +} + +func (r *Cluster) IsStatusUpdating() bool { + return !r.IsDeleting() && !r.IsUpdating() +} + +func (r *Cluster) GetComponentByName(componentName string) *ClusterComponentSpec { + for _, v := range r.Spec.ComponentSpecs { + if v.Name == componentName { + return &v + } + } + return nil +} + +// GetVolumeClaimNames gets all PVC names of component compName. +// +// r.Spec.GetComponentByName(compName).VolumeClaimTemplates[*].Name will be used if no claimNames provided +// +// nil return if: +// 1. component compName not found or +// 2. len(VolumeClaimTemplates)==0 or +// 3. any claimNames not found +func (r *Cluster) GetVolumeClaimNames(compName string, claimNames ...string) []string { + if r == nil { + return nil + } + comp := r.Spec.GetComponentByName(compName) + if comp == nil { + return nil + } + if len(comp.VolumeClaimTemplates) == 0 { + return nil + } + if len(claimNames) == 0 { + for _, template := range comp.VolumeClaimTemplates { + claimNames = append(claimNames, template.Name) + } + } + allExist := true + for _, name := range claimNames { + found := false + for _, template := range comp.VolumeClaimTemplates { + if template.Name == name { + found = true + break + } + } + if !found { + allExist = false + break + } + } + if !allExist { + return nil + } + + pvcNames := make([]string, 0) + for _, claimName := range claimNames { + for i := 0; i < int(comp.Replicas); i++ { + pvcName := fmt.Sprintf("%s-%s-%s-%d", claimName, r.Name, compName, i) + pvcNames = append(pvcNames, pvcName) + } + } + return pvcNames +} + +func (r *ClusterSpec) GetComponentByName(componentName string) *ClusterComponentSpec { + for _, v := range r.ComponentSpecs { + if v.Name == componentName { + return &v + } + } + return nil +} + +func (r *ClusterSpec) GetShardingByName(shardingName string) *ShardingSpec { + for _, v := range r.ShardingSpecs { + if v.Name == shardingName { + return &v + } + } + return nil +} + +// SetComponentStatus does safe operation on ClusterStatus.Components map object update. +func (r *ClusterStatus) SetComponentStatus(name string, status ClusterComponentStatus) { + if r.Components == nil { + r.Components = map[string]ClusterComponentStatus{} + } + r.Components[name] = status +} + +func (r *ClusterComponentSpec) GetDisableExporter() *bool { + if r.DisableExporter != nil { + return r.DisableExporter + } + + toPointer := func(b bool) *bool { + p := b + return &p + } + + // Compatible with previous versions of kb + if r.Monitor != nil { + return toPointer(!*r.Monitor) + } + return nil +} + +func (r *ClusterComponentSpec) ToVolumeClaimTemplates() []corev1.PersistentVolumeClaimTemplate { + if r == nil { + return nil + } + var ts []corev1.PersistentVolumeClaimTemplate + for _, t := range r.VolumeClaimTemplates { + ts = append(ts, t.toVolumeClaimTemplate()) + } + return ts +} + +func (r *ClusterComponentStatus) GetObjectMessage(objectKind, objectName string) string { + messageKey := fmt.Sprintf("%s/%s", objectKind, objectName) + return r.Message[messageKey] +} + +func (r *ClusterComponentVolumeClaimTemplate) toVolumeClaimTemplate() corev1.PersistentVolumeClaimTemplate { + return corev1.PersistentVolumeClaimTemplate{ + ObjectMeta: metav1.ObjectMeta{ + Name: r.Name, + }, + Spec: r.Spec.ToV1PersistentVolumeClaimSpec(), + } +} + +func (r *PersistentVolumeClaimSpec) ToV1PersistentVolumeClaimSpec() corev1.PersistentVolumeClaimSpec { + return corev1.PersistentVolumeClaimSpec{ + AccessModes: r.AccessModes, + Resources: r.Resources, + StorageClassName: r.getStorageClassName(viper.GetString(constant.CfgKeyDefaultStorageClass)), + VolumeMode: r.VolumeMode, + } +} + +// getStorageClassName returns PersistentVolumeClaimSpec.StorageClassName if a value is assigned; otherwise, +// it returns preferSC argument. +func (r *PersistentVolumeClaimSpec) getStorageClassName(preferSC string) *string { + if r.StorageClassName != nil && *r.StorageClassName != "" { + return r.StorageClassName + } + if preferSC != "" { + return &preferSC + } + return nil +} + +func GetClusterUpRunningPhases() []ClusterPhase { + return []ClusterPhase{ + RunningClusterPhase, + AbnormalClusterPhase, + FailedClusterPhase, + } +} + +func GetComponentTerminalPhases() []ClusterComponentPhase { + return []ClusterComponentPhase{ + RunningClusterCompPhase, + StoppedClusterCompPhase, + FailedClusterCompPhase, + AbnormalClusterCompPhase, + } +} + +func GetReconfiguringRunningPhases() []ClusterPhase { + return []ClusterPhase{ + RunningClusterPhase, + UpdatingClusterPhase, // enable partial running for reconfiguring + AbnormalClusterPhase, + FailedClusterPhase, + } +} + +func GetInstanceTemplateName(clusterName, componentName, instanceName string) string { + workloadPrefix := fmt.Sprintf("%s-%s", clusterName, componentName) + compInsKey := instanceName[:strings.LastIndex(instanceName, "-")] + if compInsKey == workloadPrefix { + return "" + } + return strings.Replace(compInsKey, workloadPrefix+"-", "", 1) +} + +func (t *InstanceTemplate) GetReplicas() int32 { + if t.Replicas != nil { + return *t.Replicas + } + return defaultInstanceTemplateReplicas +} diff --git a/apis/apps/v1/types.go b/apis/apps/v1/types.go index 2dba4c50b99..2418425f56b 100644 --- a/apis/apps/v1/types.go +++ b/apis/apps/v1/types.go @@ -20,6 +20,13 @@ import ( corev1 "k8s.io/api/core/v1" ) +const ( + APIVersion = "apps.kubeblocks.io/v1" + ClusterDefinitionKind = "ClusterDefinition" + ClusterKind = "Cluster" + ComponentKind = "Component" +) + // Phase represents the status of a CR. // // +enum diff --git a/apis/apps/v1/zz_generated.deepcopy.go b/apis/apps/v1/zz_generated.deepcopy.go index f0eb9d031e1..3e0018aa680 100644 --- a/apis/apps/v1/zz_generated.deepcopy.go +++ b/apis/apps/v1/zz_generated.deepcopy.go @@ -67,8 +67,8 @@ func (in *Cluster) DeepCopyInto(out *Cluster) { *out = *in out.TypeMeta = in.TypeMeta in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - out.Spec = in.Spec - out.Status = in.Status + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Cluster. @@ -89,6 +89,36 @@ func (in *Cluster) DeepCopyObject() runtime.Object { return nil } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterBackup) DeepCopyInto(out *ClusterBackup) { + *out = *in + if in.Enabled != nil { + in, out := &in.Enabled, &out.Enabled + *out = new(bool) + **out = **in + } + if in.StartingDeadlineMinutes != nil { + in, out := &in.StartingDeadlineMinutes, &out.StartingDeadlineMinutes + *out = new(int64) + **out = **in + } + if in.PITREnabled != nil { + in, out := &in.PITREnabled, &out.PITREnabled + *out = new(bool) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterBackup. +func (in *ClusterBackup) DeepCopy() *ClusterBackup { + if in == nil { + return nil + } + out := new(ClusterBackup) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ClusterComponentConfig) DeepCopyInto(out *ClusterComponentConfig) { *out = *in @@ -130,6 +160,196 @@ func (in *ClusterComponentConfigSource) DeepCopy() *ClusterComponentConfigSource return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterComponentService) DeepCopyInto(out *ClusterComponentService) { + *out = *in + if in.Annotations != nil { + in, out := &in.Annotations, &out.Annotations + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.PodService != nil { + in, out := &in.PodService, &out.PodService + *out = new(bool) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterComponentService. +func (in *ClusterComponentService) DeepCopy() *ClusterComponentService { + if in == nil { + return nil + } + out := new(ClusterComponentService) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterComponentSpec) DeepCopyInto(out *ClusterComponentSpec) { + *out = *in + if in.ServiceRefs != nil { + in, out := &in.ServiceRefs, &out.ServiceRefs + *out = make([]ServiceRef, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.EnabledLogs != nil { + in, out := &in.EnabledLogs, &out.EnabledLogs + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.Labels != nil { + in, out := &in.Labels, &out.Labels + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.Annotations != nil { + in, out := &in.Annotations, &out.Annotations + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.Env != nil { + in, out := &in.Env, &out.Env + *out = make([]corev1.EnvVar, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.SchedulingPolicy != nil { + in, out := &in.SchedulingPolicy, &out.SchedulingPolicy + *out = new(SchedulingPolicy) + (*in).DeepCopyInto(*out) + } + in.Resources.DeepCopyInto(&out.Resources) + if in.VolumeClaimTemplates != nil { + in, out := &in.VolumeClaimTemplates, &out.VolumeClaimTemplates + *out = make([]ClusterComponentVolumeClaimTemplate, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.Volumes != nil { + in, out := &in.Volumes, &out.Volumes + *out = make([]corev1.Volume, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.Services != nil { + in, out := &in.Services, &out.Services + *out = make([]ClusterComponentService, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.SystemAccounts != nil { + in, out := &in.SystemAccounts, &out.SystemAccounts + *out = make([]ComponentSystemAccount, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.Configs != nil { + in, out := &in.Configs, &out.Configs + *out = make([]ClusterComponentConfig, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.Issuer != nil { + in, out := &in.Issuer, &out.Issuer + *out = new(Issuer) + (*in).DeepCopyInto(*out) + } + if in.UpdateStrategy != nil { + in, out := &in.UpdateStrategy, &out.UpdateStrategy + *out = new(UpdateStrategy) + **out = **in + } + if in.ParallelPodManagementConcurrency != nil { + in, out := &in.ParallelPodManagementConcurrency, &out.ParallelPodManagementConcurrency + *out = new(intstr.IntOrString) + **out = **in + } + if in.PodUpdatePolicy != nil { + in, out := &in.PodUpdatePolicy, &out.PodUpdatePolicy + *out = new(PodUpdatePolicyType) + **out = **in + } + if in.UserResourceRefs != nil { + in, out := &in.UserResourceRefs, &out.UserResourceRefs + *out = new(UserResourceRefs) + (*in).DeepCopyInto(*out) + } + if in.Instances != nil { + in, out := &in.Instances, &out.Instances + *out = make([]InstanceTemplate, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.OfflineInstances != nil { + in, out := &in.OfflineInstances, &out.OfflineInstances + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.DisableExporter != nil { + in, out := &in.DisableExporter, &out.DisableExporter + *out = new(bool) + **out = **in + } + if in.Monitor != nil { + in, out := &in.Monitor, &out.Monitor + *out = new(bool) + **out = **in + } + if in.Stop != nil { + in, out := &in.Stop, &out.Stop + *out = new(bool) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterComponentSpec. +func (in *ClusterComponentSpec) DeepCopy() *ClusterComponentSpec { + if in == nil { + return nil + } + out := new(ClusterComponentSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterComponentStatus) DeepCopyInto(out *ClusterComponentStatus) { + *out = *in + if in.Message != nil { + in, out := &in.Message, &out.Message + *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 ClusterComponentStatus. +func (in *ClusterComponentStatus) DeepCopy() *ClusterComponentStatus { + if in == nil { + return nil + } + out := new(ClusterComponentStatus) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ClusterComponentVolumeClaimTemplate) DeepCopyInto(out *ClusterComponentVolumeClaimTemplate) { *out = *in @@ -299,9 +519,61 @@ func (in *ClusterObjectReference) DeepCopy() *ClusterObjectReference { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterService) DeepCopyInto(out *ClusterService) { + *out = *in + in.Service.DeepCopyInto(&out.Service) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterService. +func (in *ClusterService) DeepCopy() *ClusterService { + if in == nil { + return nil + } + out := new(ClusterService) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ClusterSpec) DeepCopyInto(out *ClusterSpec) { *out = *in + if in.ComponentSpecs != nil { + in, out := &in.ComponentSpecs, &out.ComponentSpecs + *out = make([]ClusterComponentSpec, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.ShardingSpecs != nil { + in, out := &in.ShardingSpecs, &out.ShardingSpecs + *out = make([]ShardingSpec, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.RuntimeClassName != nil { + in, out := &in.RuntimeClassName, &out.RuntimeClassName + *out = new(string) + **out = **in + } + if in.SchedulingPolicy != nil { + in, out := &in.SchedulingPolicy, &out.SchedulingPolicy + *out = new(SchedulingPolicy) + (*in).DeepCopyInto(*out) + } + if in.Services != nil { + in, out := &in.Services, &out.Services + *out = make([]ClusterService, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.Backup != nil { + in, out := &in.Backup, &out.Backup + *out = new(ClusterBackup) + (*in).DeepCopyInto(*out) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterSpec. @@ -317,6 +589,20 @@ func (in *ClusterSpec) DeepCopy() *ClusterSpec { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ClusterStatus) DeepCopyInto(out *ClusterStatus) { *out = *in + if in.Components != nil { + in, out := &in.Components, &out.Components + *out = make(map[string]ClusterComponentStatus, len(*in)) + for key, val := range *in { + (*out)[key] = *val.DeepCopy() + } + } + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]metav1.Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterStatus. @@ -1281,6 +1567,23 @@ func (in *ComponentVolume) DeepCopy() *ComponentVolume { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ConfigMapRef) DeepCopyInto(out *ConfigMapRef) { + *out = *in + in.ResourceMeta.DeepCopyInto(&out.ResourceMeta) + in.ConfigMap.DeepCopyInto(&out.ConfigMap) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ConfigMapRef. +func (in *ConfigMapRef) DeepCopy() *ConfigMapRef { + if in == nil { + return nil + } + out := new(ConfigMapRef) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ConfigTemplateExtension) DeepCopyInto(out *ConfigTemplateExtension) { *out = *in @@ -1869,6 +2172,26 @@ func (in *ReplicasLimit) DeepCopy() *ReplicasLimit { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ResourceMeta) DeepCopyInto(out *ResourceMeta) { + *out = *in + if in.AsVolumeFrom != nil { + in, out := &in.AsVolumeFrom, &out.AsVolumeFrom + *out = make([]string, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceMeta. +func (in *ResourceMeta) DeepCopy() *ResourceMeta { + if in == nil { + return nil + } + out := new(ResourceMeta) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *RetryPolicy) DeepCopyInto(out *RetryPolicy) { *out = *in @@ -1945,6 +2268,23 @@ func (in *SchedulingPolicy) DeepCopy() *SchedulingPolicy { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SecretRef) DeepCopyInto(out *SecretRef) { + *out = *in + in.ResourceMeta.DeepCopyInto(&out.ResourceMeta) + in.Secret.DeepCopyInto(&out.Secret) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecretRef. +func (in *SecretRef) DeepCopy() *SecretRef { + if in == nil { + return nil + } + out := new(SecretRef) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Service) DeepCopyInto(out *Service) { *out = *in @@ -2292,6 +2632,22 @@ func (in *ServiceVars) DeepCopy() *ServiceVars { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ShardingSpec) DeepCopyInto(out *ShardingSpec) { + *out = *in + in.Template.DeepCopyInto(&out.Template) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ShardingSpec. +func (in *ShardingSpec) DeepCopy() *ShardingSpec { + if in == nil { + return nil + } + out := new(ShardingSpec) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *SystemAccount) DeepCopyInto(out *SystemAccount) { *out = *in @@ -2348,6 +2704,35 @@ func (in *TLSSecretRef) DeepCopy() *TLSSecretRef { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *UserResourceRefs) DeepCopyInto(out *UserResourceRefs) { + *out = *in + if in.SecretRefs != nil { + in, out := &in.SecretRefs, &out.SecretRefs + *out = make([]SecretRef, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.ConfigMapRefs != nil { + in, out := &in.ConfigMapRefs, &out.ConfigMapRefs + *out = make([]ConfigMapRef, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new UserResourceRefs. +func (in *UserResourceRefs) DeepCopy() *UserResourceRefs { + if in == nil { + return nil + } + out := new(UserResourceRefs) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *VarSource) DeepCopyInto(out *VarSource) { *out = *in diff --git a/apis/apps/v1alpha1/opsrequest_types.go b/apis/apps/v1alpha1/opsrequest_types.go index 1c8dd0eca13..31cad67bb81 100644 --- a/apis/apps/v1alpha1/opsrequest_types.go +++ b/apis/apps/v1alpha1/opsrequest_types.go @@ -21,6 +21,8 @@ import ( "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/intstr" + + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" ) // TODO: @wangyelei could refactor to ops group @@ -484,7 +486,7 @@ type ScaleOut struct { // +patchStrategy=merge,retainKeys // +listType=map // +listMapKey=name - NewInstances []InstanceTemplate `json:"newInstances,omitempty" patchStrategy:"merge,retainKeys" patchMergeKey:"name"` + NewInstances []appsv1.InstanceTemplate `json:"newInstances,omitempty" patchStrategy:"merge,retainKeys" patchMergeKey:"name"` // Specifies the instances in the offline list to bring back online. // +optional @@ -1086,7 +1088,7 @@ type LastComponentConfiguration struct { // Records the ClusterComponentService list of the Component prior to any changes. // +optional - Services []ClusterComponentService `json:"services,omitempty"` + Services []appsv1.ClusterComponentService `json:"services,omitempty"` // Records the information about various types of resources associated with the Component prior to any changes. // Currently, only one type of resource is supported: "pods". @@ -1096,7 +1098,7 @@ type LastComponentConfiguration struct { // Records the InstanceTemplate list of the Component prior to any changes. // +optional - Instances []InstanceTemplate `json:"instances,omitempty"` + Instances []appsv1.InstanceTemplate `json:"instances,omitempty"` // Records the offline instances of the Component prior to any changes. // +optional @@ -1126,7 +1128,7 @@ type OpsRequestComponentStatus struct { // Records the current phase of the Component, mirroring `cluster.status.components[componentName].phase`. // Possible values include "Creating", "Running", "Updating", "Stopping", "Stopped", "Deleting", "Failed", "Abnormal". // +optional - Phase ClusterComponentPhase `json:"phase,omitempty"` + Phase appsv1.ClusterComponentPhase `json:"phase,omitempty"` // Records the timestamp when the Component last transitioned to a "Failed" or "Abnormal" phase. // +optional diff --git a/apis/apps/v1alpha1/opsrequest_validation.go b/apis/apps/v1alpha1/opsrequest_validation.go index 4f650084f11..b39a1d08148 100644 --- a/apis/apps/v1alpha1/opsrequest_validation.go +++ b/apis/apps/v1alpha1/opsrequest_validation.go @@ -32,6 +32,7 @@ import ( "k8s.io/apimachinery/pkg/util/sets" "sigs.k8s.io/controller-runtime/pkg/client" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" "github.com/apecloud/kubeblocks/pkg/constant" ) @@ -71,7 +72,7 @@ func (r *OpsRequest) Force() bool { // Validate validates OpsRequest func (r *OpsRequest) Validate(ctx context.Context, k8sClient client.Client, - cluster *Cluster, + cluster *appsv1.Cluster, needCheckClusterPhase bool) error { if needCheckClusterPhase { if err := r.validateClusterPhase(cluster); err != nil { @@ -82,7 +83,7 @@ func (r *OpsRequest) Validate(ctx context.Context, } // validateClusterPhase validates whether the current cluster state supports the OpsRequest -func (r *OpsRequest) validateClusterPhase(cluster *Cluster) error { +func (r *OpsRequest) validateClusterPhase(cluster *appsv1.Cluster) error { opsBehaviour := OpsRequestBehaviourMapper[r.Spec.Type] // if the OpsType has no cluster phases, ignore it if len(opsBehaviour.FromClusterPhases) == 0 { @@ -118,7 +119,7 @@ func (r *OpsRequest) validateClusterPhase(cluster *Cluster) error { // validateOps validates ops attributes func (r *OpsRequest) validateOps(ctx context.Context, k8sClient client.Client, - cluster *Cluster) error { + cluster *appsv1.Cluster) error { // Check whether the corresponding attribute is legal according to the operation type switch r.Spec.Type { case UpgradeType: @@ -144,7 +145,7 @@ func (r *OpsRequest) validateOps(ctx context.Context, } // validateExpose validates expose api when spec.type is Expose -func (r *OpsRequest) validateExpose(_ context.Context, cluster *Cluster) error { +func (r *OpsRequest) validateExpose(_ context.Context, cluster *appsv1.Cluster) error { exposeList := r.Spec.ExposeList if exposeList == nil { return notEmptyError("spec.expose") @@ -173,7 +174,7 @@ func (r *OpsRequest) validateExpose(_ context.Context, cluster *Cluster) error { return r.checkComponentExistence(cluster, compOpsList) } -func (r *OpsRequest) validateRebuildInstance(cluster *Cluster) error { +func (r *OpsRequest) validateRebuildInstance(cluster *appsv1.Cluster) error { rebuildFrom := r.Spec.RebuildFrom if len(rebuildFrom) == 0 { return notEmptyError("spec.rebuildFrom") @@ -186,7 +187,7 @@ func (r *OpsRequest) validateRebuildInstance(cluster *Cluster) error { } // validateUpgrade validates spec.restart -func (r *OpsRequest) validateRestart(cluster *Cluster) error { +func (r *OpsRequest) validateRestart(cluster *appsv1.Cluster) error { restartList := r.Spec.RestartList if len(restartList) == 0 { return notEmptyError("spec.restart") @@ -195,7 +196,7 @@ func (r *OpsRequest) validateRestart(cluster *Cluster) error { } // validateUpgrade validates spec.clusterOps.upgrade -func (r *OpsRequest) validateUpgrade(ctx context.Context, k8sClient client.Client, cluster *Cluster) error { +func (r *OpsRequest) validateUpgrade(ctx context.Context, k8sClient client.Client, cluster *appsv1.Cluster) error { upgrade := r.Spec.Upgrade if upgrade == nil { return notEmptyError("spec.upgrade") @@ -210,7 +211,7 @@ func (r *OpsRequest) validateUpgrade(ctx context.Context, k8sClient client.Clien } // validateVerticalScaling validates api when spec.type is VerticalScaling -func (r *OpsRequest) validateVerticalScaling(cluster *Cluster) error { +func (r *OpsRequest) validateVerticalScaling(cluster *appsv1.Cluster) error { verticalScalingList := r.Spec.VerticalScalingList if len(verticalScalingList) == 0 { return notEmptyError("spec.verticalScaling") @@ -243,7 +244,7 @@ func (r *OpsRequest) validateVerticalScaling(cluster *Cluster) error { // validateVerticalScaling validate api is legal when spec.type is VerticalScaling func (r *OpsRequest) validateReconfigure(ctx context.Context, k8sClient client.Client, - cluster *Cluster) error { + cluster *appsv1.Cluster) error { reconfigure := r.Spec.Reconfigure if reconfigure == nil && len(r.Spec.Reconfigures) == 0 { return notEmptyError("spec.reconfigure") @@ -261,7 +262,7 @@ func (r *OpsRequest) validateReconfigure(ctx context.Context, func (r *OpsRequest) validateReconfigureParams(ctx context.Context, k8sClient client.Client, - cluster *Cluster, + cluster *appsv1.Cluster, reconfigure *Reconfigure) error { if cluster.Spec.GetComponentByName(reconfigure.ComponentName) == nil { return fmt.Errorf("component %s not found", reconfigure.ComponentName) @@ -322,7 +323,7 @@ func compareQuantity(requestQuantity, limitQuantity *resource.Quantity) bool { } // validateHorizontalScaling validates api when spec.type is HorizontalScaling -func (r *OpsRequest) validateHorizontalScaling(_ context.Context, _ client.Client, cluster *Cluster) error { +func (r *OpsRequest) validateHorizontalScaling(_ context.Context, _ client.Client, cluster *appsv1.Cluster) error { horizontalScalingList := r.Spec.HorizontalScalingList if len(horizontalScalingList) == 0 { return notEmptyError("spec.horizontalScaling") @@ -363,7 +364,7 @@ func (r *OpsRequest) CountOfflineOrOnlineInstances(clusterName, componentName st return offlineOrOnlineInsCountMap } -func (r *OpsRequest) validateHorizontalScalingSpec(hScale HorizontalScaling, compSpec ClusterComponentSpec, clusterName string, isSharding bool) error { +func (r *OpsRequest) validateHorizontalScalingSpec(hScale HorizontalScaling, compSpec appsv1.ClusterComponentSpec, clusterName string, isSharding bool) error { scaleIn := hScale.ScaleIn scaleOut := hScale.ScaleOut if hScale.Replicas != nil && (scaleIn != nil || scaleOut != nil) { @@ -461,7 +462,7 @@ func (r *OpsRequest) validateHorizontalScalingSpec(hScale HorizontalScaling, com } // validateVolumeExpansion validates volumeExpansion api when spec.type is VolumeExpansion -func (r *OpsRequest) validateVolumeExpansion(ctx context.Context, cli client.Client, cluster *Cluster) error { +func (r *OpsRequest) validateVolumeExpansion(ctx context.Context, cli client.Client, cluster *appsv1.Cluster) error { volumeExpansionList := r.Spec.VolumeExpansionList if len(volumeExpansionList) == 0 { return notEmptyError("spec.volumeExpansion") @@ -485,7 +486,7 @@ func (r *OpsRequest) validateVolumeExpansion(ctx context.Context, cli client.Cli } // validateSwitchover validates switchover api when spec.type is Switchover. -func (r *OpsRequest) validateSwitchover(ctx context.Context, cli client.Client, cluster *Cluster) error { +func (r *OpsRequest) validateSwitchover(ctx context.Context, cli client.Client, cluster *appsv1.Cluster) error { switchoverList := r.Spec.SwitchoverList if len(switchoverList) == 0 { return notEmptyError("spec.switchover") @@ -501,9 +502,9 @@ func (r *OpsRequest) validateSwitchover(ctx context.Context, cli client.Client, return validateSwitchoverResourceList(ctx, cli, cluster, switchoverList) } -func (r *OpsRequest) checkInstanceTemplate(cluster *Cluster, componentOps ComponentOps, inputInstances []string) error { +func (r *OpsRequest) checkInstanceTemplate(cluster *appsv1.Cluster, componentOps ComponentOps, inputInstances []string) error { instanceNameMap := make(map[string]sets.Empty) - setInstanceMap := func(instances []InstanceTemplate) { + setInstanceMap := func(instances []appsv1.InstanceTemplate) { for i := range instances { instanceNameMap[instances[i].Name] = sets.Empty{} } @@ -533,7 +534,7 @@ func (r *OpsRequest) checkInstanceTemplate(cluster *Cluster, componentOps Compon } // checkComponentExistence checks whether components to be operated exist in cluster spec. -func (r *OpsRequest) checkComponentExistence(cluster *Cluster, compOpsList []ComponentOps) error { +func (r *OpsRequest) checkComponentExistence(cluster *appsv1.Cluster, compOpsList []ComponentOps) error { compNameMap := make(map[string]sets.Empty) for _, compSpec := range cluster.Spec.ComponentSpecs { compNameMap[compSpec.Name] = sets.Empty{} @@ -557,7 +558,7 @@ func (r *OpsRequest) checkComponentExistence(cluster *Cluster, compOpsList []Com return nil } -func (r *OpsRequest) checkVolumesAllowExpansion(ctx context.Context, cli client.Client, cluster *Cluster) error { +func (r *OpsRequest) checkVolumesAllowExpansion(ctx context.Context, cli client.Client, cluster *appsv1.Cluster) error { type Entity struct { existInSpec bool storageClassName *string @@ -591,7 +592,7 @@ func (r *OpsRequest) checkVolumesAllowExpansion(ctx context.Context, cli client. setVols(ins.VolumeClaimTemplates, comp.ComponentOps.ComponentName, ins.Name) } } - fillVol := func(vct ClusterComponentVolumeClaimTemplate, key string, isShardingComp bool) { + fillVol := func(vct appsv1.ClusterComponentVolumeClaimTemplate, key string, isShardingComp bool) { e, ok := vols[key][vct.Name] if !ok { return @@ -601,7 +602,7 @@ func (r *OpsRequest) checkVolumesAllowExpansion(ctx context.Context, cli client. e.isShardingComponent = isShardingComp vols[key][vct.Name] = e } - fillCompVols := func(compSpec ClusterComponentSpec, componentName string, isShardingComp bool) { + fillCompVols := func(compSpec appsv1.ClusterComponentSpec, componentName string, isShardingComp bool) { key := getKey(componentName, "") if _, ok := vols[key]; !ok { return // ignore not-exist component @@ -771,7 +772,7 @@ func GetRunningOpsByOpsType(ctx context.Context, cli client.Client, } // validateSwitchoverResourceList checks if switchover resourceList is legal. -func validateSwitchoverResourceList(ctx context.Context, cli client.Client, cluster *Cluster, switchoverList []Switchover) error { +func validateSwitchoverResourceList(ctx context.Context, cli client.Client, cluster *appsv1.Cluster, switchoverList []Switchover) error { var ( targetRole string ) diff --git a/apis/apps/v1alpha1/type.go b/apis/apps/v1alpha1/type.go index 886a47f20e1..c13515a03dd 100644 --- a/apis/apps/v1alpha1/type.go +++ b/apis/apps/v1alpha1/type.go @@ -22,6 +22,8 @@ import ( appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" + + kbappsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" ) const ( @@ -545,8 +547,8 @@ const ( ) type OpsRequestBehaviour struct { - FromClusterPhases []ClusterPhase - ToClusterPhase ClusterPhase + FromClusterPhases []kbappsv1.ClusterPhase + ToClusterPhase kbappsv1.ClusterPhase } type OpsRecorder struct { diff --git a/apis/apps/v1alpha1/zz_generated.deepcopy.go b/apis/apps/v1alpha1/zz_generated.deepcopy.go index f86aaa75efd..38920a4fefa 100644 --- a/apis/apps/v1alpha1/zz_generated.deepcopy.go +++ b/apis/apps/v1alpha1/zz_generated.deepcopy.go @@ -24,6 +24,7 @@ along with this program. If not, see . package v1alpha1 import ( + apisappsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" "github.com/apecloud/kubeblocks/apis/apps/v1beta1" dataprotectionv1alpha1 "github.com/apecloud/kubeblocks/apis/dataprotection/v1alpha1" workloadsv1alpha1 "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" @@ -3051,7 +3052,7 @@ func (in *LastComponentConfiguration) DeepCopyInto(out *LastComponentConfigurati } if in.Services != nil { in, out := &in.Services, &out.Services - *out = make([]ClusterComponentService, len(*in)) + *out = make([]apisappsv1.ClusterComponentService, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } @@ -3074,7 +3075,7 @@ func (in *LastComponentConfiguration) DeepCopyInto(out *LastComponentConfigurati } if in.Instances != nil { in, out := &in.Instances, &out.Instances - *out = make([]InstanceTemplate, len(*in)) + *out = make([]apisappsv1.InstanceTemplate, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } @@ -3486,7 +3487,7 @@ func (in *OpsRequestBehaviour) DeepCopyInto(out *OpsRequestBehaviour) { *out = *in if in.FromClusterPhases != nil { in, out := &in.FromClusterPhases, &out.FromClusterPhases - *out = make([]ClusterPhase, len(*in)) + *out = make([]apisappsv1.ClusterPhase, len(*in)) copy(*out, *in) } } @@ -4424,7 +4425,7 @@ func (in *ScaleOut) DeepCopyInto(out *ScaleOut) { in.ReplicaChanger.DeepCopyInto(&out.ReplicaChanger) if in.NewInstances != nil { in, out := &in.NewInstances, &out.NewInstances - *out = make([]InstanceTemplate, len(*in)) + *out = make([]apisappsv1.InstanceTemplate, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } diff --git a/config/crd/bases/apps.kubeblocks.io_clusters.yaml b/config/crd/bases/apps.kubeblocks.io_clusters.yaml index 2cdcc981f4d..8eb9ec1959a 100644 --- a/config/crd/bases/apps.kubeblocks.io_clusters.yaml +++ b/config/crd/bases/apps.kubeblocks.io_clusters.yaml @@ -89,15 +89,16517 @@ spec: metadata: type: object spec: - description: ClusterSpec defines the desired state of Cluster + description: ClusterSpec defines the desired state of Cluster. properties: - foo: - description: Foo is an example field of Cluster. Edit cluster_types.go - to remove/update + backup: + description: Specifies the backup configuration of the Cluster. + properties: + cronExpression: + description: The cron expression for the schedule. The timezone + is in UTC. See https://en.wikipedia.org/wiki/Cron. + type: string + enabled: + default: false + description: Specifies whether automated backup is enabled for + the Cluster. + type: boolean + method: + description: Specifies the backup method to use, as defined in + backupPolicy. + type: string + pitrEnabled: + default: false + description: Specifies whether to enable point-in-time recovery. + type: boolean + repoName: + description: Specifies the name of the backupRepo. If not set, + the default backupRepo will be used. + type: string + retentionPeriod: + default: 7d + description: "Determines the duration to retain backups. Backups + older than this period are automatically removed.\n\n\nFor example, + RetentionPeriod of `30d` will keep only the backups of last + 30 days.\nSample duration format:\n\n\n- years: \t2y\n- months: + \t6mo\n- days: \t\t30d\n- hours: \t12h\n- minutes: \t30m\n\n\nYou + can also combine the above durations. For example: 30d12h30m.\nDefault + value is 7d." + type: string + startingDeadlineMinutes: + description: |- + Specifies the maximum time in minutes that the system will wait to start a missed backup job. + If the scheduled backup time is missed for any reason, the backup job must start within this deadline. + Values must be between 0 (immediate execution) and 1440 (one day). + format: int64 + maximum: 1440 + minimum: 0 + type: integer + required: + - method + type: object + clusterDefinitionRef: + description: |- + Specifies the name of the ClusterDefinition to use when creating a Cluster. + + + This field enables users to create a Cluster based on a specific ClusterDefinition. + Which, in conjunction with the `topology` field, determine: + + + - The Components to be included in the Cluster. + - The sequences in which the Components are created, updated, and terminate. + + + This facilitates multiple-components management with predefined ClusterDefinition. + + + Users with advanced requirements can bypass this general setting and specify more precise control over + the composition of the Cluster by directly referencing specific ComponentDefinitions for each component + within `componentSpecs[*].componentDef`. + + + If this field is not provided, each component must be explicitly defined in `componentSpecs[*].componentDef`. + + + Note: Once set, this field cannot be modified; it is immutable. + maxLength: 63 + pattern: ^[a-z0-9]([a-z0-9\.\-]*[a-z0-9])?$ + type: string + x-kubernetes-validations: + - message: clusterDefinitionRef is immutable + rule: self == oldSelf + clusterVersionRef: + description: |- + Refers to the ClusterVersion name. + + + Deprecated since v0.9, use ComponentVersion instead. + This field is maintained for backward compatibility and its use is discouraged. + Existing usage should be updated to the current preferred approach to avoid compatibility issues in future releases. + maxLength: 63 + pattern: ^[a-z0-9]([a-z0-9\.\-]*[a-z0-9])?$ + type: string + componentSpecs: + description: |- + Specifies a list of ClusterComponentSpec objects used to define the individual Components that make up a Cluster. + This field allows for detailed configuration of each Component within the Cluster. + + + Note: `shardingSpecs` and `componentSpecs` cannot both be empty; at least one must be defined to configure a Cluster. + items: + description: |- + ClusterComponentSpec defines the specification of a Component within a Cluster. + TODO +kubebuilder:validation:XValidation:rule="!has(oldSelf.componentDefRef) || has(self.componentDefRef)", message="componentDefRef is required once set" + TODO +kubebuilder:validation:XValidation:rule="!has(oldSelf.componentDef) || has(self.componentDef)", message="componentDef is required once set" + properties: + annotations: + additionalProperties: + type: string + description: Specifies Annotations to override or add for underlying + Pods. + type: object + componentDef: + description: |- + References the name of a ComponentDefinition object. + The ComponentDefinition specifies the behavior and characteristics of the Component. + If both `componentDefRef` and `componentDef` are provided, + the `componentDef` will take precedence over `componentDefRef`. + maxLength: 64 + pattern: ^[a-z0-9]([a-z0-9\.\-]*[a-z0-9])?$ + type: string + componentDefRef: + description: |- + References a ClusterComponentDefinition defined in the `clusterDefinition.spec.componentDef` field. + Must comply with the IANA service naming rule. + + + Deprecated since v0.9, + because defining Components in `clusterDefinition.spec.componentDef` field has been deprecated. + This field is replaced by the `componentDef` field, use `componentDef` instead. + This field is maintained for backward compatibility and its use is discouraged. + Existing usage should be updated to the current preferred approach to avoid compatibility issues in future releases. + + + TODO +kubebuilder:validation:XValidation:rule="self == oldSelf",message="componentDefRef is immutable" + maxLength: 22 + pattern: ^[a-z]([a-z0-9\-]*[a-z0-9])?$ + type: string + configs: + description: Specifies the configuration content of a config + template. + items: + description: ClusterComponentConfig represents a config with + its source bound. + properties: + configMap: + description: ConfigMap source for the config. + properties: + defaultMode: + description: |- + defaultMode is optional: mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + items: + description: |- + items if unspecified, each key-value pair in the Data field of the referenced + ConfigMap will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the ConfigMap, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within + a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + 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 + optional: + description: optional specify whether the ConfigMap + or its keys must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + name: + description: The name of the config. + type: string + type: object + type: array + disableExporter: + description: |- + Determines whether metrics exporter information is annotated on the Component's headless Service. + + + If set to true, the following annotations will not be patched into the Service: + + + - "monitor.kubeblocks.io/path" + - "monitor.kubeblocks.io/port" + - "monitor.kubeblocks.io/scheme" + + + These annotations allow the Prometheus installed by KubeBlocks to discover and scrape metrics from the exporter. + type: boolean + enabledLogs: + description: |- + Specifies which types of logs should be collected for the Component. + The log types are defined in the `componentDefinition.spec.logConfigs` field with the LogConfig entries. + + + The elements in the `enabledLogs` array correspond to the names of the LogConfig entries. + For example, if the `componentDefinition.spec.logConfigs` defines LogConfig entries with + names "slow_query_log" and "error_log", + you can enable the collection of these logs by including their names in the `enabledLogs` array: + ```yaml + enabledLogs: + - slow_query_log + - error_log + ``` + items: + type: string + type: array + x-kubernetes-list-type: set + env: + description: |- + List of environment variables to add. + These environment variables will be placed after the environment variables declared in the Pod. + items: + description: EnvVar represents an environment variable present + in a Container. + properties: + name: + description: Name of the environment variable. Must be + a C_IDENTIFIER. + type: string + value: + description: |- + Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in the container and + any service environment variables. If a variable cannot be resolved, + the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless of whether the variable + exists or not. + Defaults to "". + type: string + valueFrom: + description: Source for the environment variable's value. + Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap or + its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the + specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the + exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in the pod's + namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its + key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + instances: + description: |- + Allows for the customization of configuration values for each instance within a Component. + An instance represent a single replica (Pod and associated K8s resources like PVCs, Services, and ConfigMaps). + While instances typically share a common configuration as defined in the ClusterComponentSpec, + they can require unique settings in various scenarios: + + + For example: + - A database Component might require different resource allocations for primary and secondary instances, + with primaries needing more resources. + - During a rolling upgrade, a Component may first update the image for one or a few instances, + and then update the remaining instances after verifying that the updated instances are functioning correctly. + + + InstanceTemplate allows for specifying these unique configurations per instance. + Each instance's name is constructed using the pattern: $(component.name)-$(template.name)-$(ordinal), + starting with an ordinal of 0. + It is crucial to maintain unique names for each InstanceTemplate to avoid conflicts. + + + The sum of replicas across all InstanceTemplates should not exceed the total number of replicas specified for the Component. + Any remaining replicas will be generated using the default template and will follow the default naming rules. + items: + description: InstanceTemplate allows customization of individual + replica configurations in a Component. + properties: + annotations: + additionalProperties: + type: string + description: |- + Specifies a map of key-value pairs to be merged into the Pod's existing annotations. + Existing keys will have their values overwritten, while new keys will be added to the annotations. + type: object + env: + description: |- + Defines Env to override. + Add new or override existing envs. + items: + description: EnvVar represents an environment variable + present in a Container. + properties: + name: + description: Name of the environment variable. Must + be a C_IDENTIFIER. + type: string + value: + description: |- + Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in the container and + any service environment variables. If a variable cannot be resolved, + the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless of whether the variable + exists or not. + Defaults to "". + type: string + valueFrom: + description: Source for the environment variable's + value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select + in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required for + volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format + of the exposed resources, defaults to + "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in the + pod's namespace + properties: + key: + description: The key of the secret to select + from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + image: + description: Specifies an override for the first container's + image in the Pod. + type: string + labels: + additionalProperties: + type: string + description: |- + Specifies a map of key-value pairs that will be merged into the Pod's existing labels. + Values for existing keys will be overwritten, and new keys will be added. + type: object + name: + description: |- + Name specifies the unique name of the instance Pod created using this InstanceTemplate. + This name is constructed by concatenating the Component's name, the template's name, and the instance's ordinal + using the pattern: $(cluster.name)-$(component.name)-$(template.name)-$(ordinal). Ordinals start from 0. + The specified name overrides any default naming conventions or patterns. + maxLength: 54 + pattern: ^[a-z0-9]([a-z0-9\.\-]*[a-z0-9])?$ + type: string + replicas: + default: 1 + description: |- + Specifies the number of instances (Pods) to create from this InstanceTemplate. + This field allows setting how many replicated instances of the Component, + with the specific overrides in the InstanceTemplate, are created. + The default value is 1. A value of 0 disables instance creation. + format: int32 + minimum: 0 + type: integer + resources: + description: |- + Specifies an override for the resource requirements of the first container in the Pod. + This field allows for customizing resource allocation (CPU, memory, etc.) for the container. + properties: + claims: + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + + + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + + + This field is immutable. It can only be set for containers. + items: + description: ResourceClaim references one entry + in PodSpec.ResourceClaims. + properties: + name: + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + schedulingPolicy: + description: Specifies the scheduling policy for the Component. + properties: + affinity: + description: Specifies a group of affinity scheduling + rules of the Cluster, including NodeAffinity, PodAffinity, + and PodAntiAffinity. + properties: + nodeAffinity: + description: Describes node affinity scheduling + rules for the pod. + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node matches the corresponding matchExpressions; the + node(s) with the highest sum are the most preferred. + items: + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). + properties: + preference: + description: A node selector term, associated + with the corresponding weight. + properties: + matchExpressions: + description: A list of node selector + requirements by node's labels. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key + that the selector applies + to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector + requirements by node's fields. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key + that the selector applies + to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + weight: + description: Weight associated with + matching the corresponding nodeSelectorTerm, + in the range 1-100. + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. + properties: + nodeSelectorTerms: + description: Required. A list of node + selector terms. The terms are ORed. + items: + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. + properties: + matchExpressions: + description: A list of node selector + requirements by node's labels. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key + that the selector applies + to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector + requirements by node's fields. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key + that the selector applies + to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + type: array + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + description: Describes pod affinity scheduling + rules (e.g. co-locate this pod in the same node, + zone, etc. as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched + WeightedPodAffinityTerm fields are added + per-node to find the most preferred node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity + term, associated with the corresponding + weight. + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions + is a list of label selector + requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the + label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. + Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions + is a list of label selector + requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the + label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: |- + weight associated with matching the corresponding podAffinityTerm, + in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. + items: + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is + a list of label selector requirements. + The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. + Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is + a list of label selector requirements. + The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + description: Describes pod anti-affinity scheduling + rules (e.g. avoid putting this pod in the same + node, zone, etc. as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the anti-affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched + WeightedPodAffinityTerm fields are added + per-node to find the most preferred node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity + term, associated with the corresponding + weight. + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions + is a list of label selector + requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the + label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. + Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions + is a list of label selector + requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the + label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: |- + weight associated with matching the corresponding podAffinityTerm, + in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the anti-affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the anti-affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. + items: + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is + a list of label selector requirements. + The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. + Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is + a list of label selector requirements. + The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + nodeName: + description: |- + NodeName is a request to schedule this Pod onto a specific node. If it is non-empty, + the scheduler simply schedules this Pod onto that node, assuming that it fits resource + requirements. + type: string + nodeSelector: + additionalProperties: + type: string + description: |- + NodeSelector is a selector which must be true for the Pod to fit on a node. + Selector which must match a node's labels for the Pod to be scheduled on that node. + More info: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ + type: object + x-kubernetes-map-type: atomic + schedulerName: + description: |- + If specified, the Pod will be dispatched by specified scheduler. + If not specified, the Pod will be dispatched by default scheduler. + type: string + tolerations: + description: |- + Allows Pods to be scheduled onto nodes with matching taints. + Each toleration in the array allows the Pod to tolerate node taints based on + specified `key`, `value`, `effect`, and `operator`. + + + - The `key`, `value`, and `effect` identify the taint that the toleration matches. + - The `operator` determines how the toleration matches the taint. + + + Pods with matching tolerations are allowed to be scheduled on tainted nodes, typically reserved for specific purposes. + items: + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . + properties: + effect: + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. + type: string + operator: + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. + type: string + tolerationSeconds: + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. + format: int64 + type: integer + value: + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. + type: string + type: object + type: array + topologySpreadConstraints: + description: |- + TopologySpreadConstraints describes how a group of Pods ought to spread across topology + domains. Scheduler will schedule Pods in a way which abides by the constraints. + All topologySpreadConstraints are ANDed. + items: + description: TopologySpreadConstraint specifies + how to spread matching pods among the given topology. + properties: + labelSelector: + description: |- + LabelSelector is used to find matching pods. + Pods that match this label selector are counted to determine the number of pods + in their corresponding topology domain. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select the pods over which + spreading will be calculated. The keys are used to lookup values from the + incoming pod labels, those key-value labels are ANDed with labelSelector + to select the group of existing pods over which spreading will be calculated + for the incoming pod. The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + MatchLabelKeys cannot be set when LabelSelector isn't set. + Keys that don't exist in the incoming pod labels will + be ignored. A null or empty list means only match against labelSelector. + + + This is a beta field and requires the MatchLabelKeysInPodTopologySpread feature gate to be enabled (enabled by default). + items: + type: string + type: array + x-kubernetes-list-type: atomic + maxSkew: + description: |- + MaxSkew describes the degree to which pods may be unevenly distributed. + When `whenUnsatisfiable=DoNotSchedule`, it is the maximum permitted difference + between the number of matching pods in the target topology and the global minimum. + The global minimum is the minimum number of matching pods in an eligible domain + or zero if the number of eligible domains is less than MinDomains. + For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same + labelSelector spread as 2/2/1: + In this case, the global minimum is 1. + | zone1 | zone2 | zone3 | + | P P | P P | P | + - if MaxSkew is 1, incoming pod can only be scheduled to zone3 to become 2/2/2; + scheduling it onto zone1(zone2) would make the ActualSkew(3-1) on zone1(zone2) + violate MaxSkew(1). + - if MaxSkew is 2, incoming pod can be scheduled onto any zone. + When `whenUnsatisfiable=ScheduleAnyway`, it is used to give higher precedence + to topologies that satisfy it. + It's a required field. Default value is 1 and 0 is not allowed. + format: int32 + type: integer + minDomains: + description: |- + MinDomains indicates a minimum number of eligible domains. + When the number of eligible domains with matching topology keys is less than minDomains, + Pod Topology Spread treats "global minimum" as 0, and then the calculation of Skew is performed. + And when the number of eligible domains with matching topology keys equals or greater than minDomains, + this value has no effect on scheduling. + As a result, when the number of eligible domains is less than minDomains, + scheduler won't schedule more than maxSkew Pods to those domains. + If value is nil, the constraint behaves as if MinDomains is equal to 1. + Valid values are integers greater than 0. + When value is not nil, WhenUnsatisfiable must be DoNotSchedule. + + + For example, in a 3-zone cluster, MaxSkew is set to 2, MinDomains is set to 5 and pods with the same + labelSelector spread as 2/2/2: + | zone1 | zone2 | zone3 | + | P P | P P | P P | + The number of domains is less than 5(MinDomains), so "global minimum" is treated as 0. + In this situation, new pod with the same labelSelector cannot be scheduled, + because computed skew will be 3(3 - 0) if new Pod is scheduled to any of the three zones, + it will violate MaxSkew. + + + This is a beta field and requires the MinDomainsInPodTopologySpread feature gate to be enabled (enabled by default). + format: int32 + type: integer + nodeAffinityPolicy: + description: |- + NodeAffinityPolicy indicates how we will treat Pod's nodeAffinity/nodeSelector + when calculating pod topology spread skew. Options are: + - Honor: only nodes matching nodeAffinity/nodeSelector are included in the calculations. + - Ignore: nodeAffinity/nodeSelector are ignored. All nodes are included in the calculations. + + + If this value is nil, the behavior is equivalent to the Honor policy. + This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag. + type: string + nodeTaintsPolicy: + description: |- + NodeTaintsPolicy indicates how we will treat node taints when calculating + pod topology spread skew. Options are: + - Honor: nodes without taints, along with tainted nodes for which the incoming pod + has a toleration, are included. + - Ignore: node taints are ignored. All nodes are included. + + + If this value is nil, the behavior is equivalent to the Ignore policy. + This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag. + type: string + topologyKey: + description: |- + TopologyKey is the key of node labels. Nodes that have a label with this key + and identical values are considered to be in the same topology. + We consider each as a "bucket", and try to put balanced number + of pods into each bucket. + We define a domain as a particular instance of a topology. + Also, we define an eligible domain as a domain whose nodes meet the requirements of + nodeAffinityPolicy and nodeTaintsPolicy. + e.g. If TopologyKey is "kubernetes.io/hostname", each Node is a domain of that topology. + And, if TopologyKey is "topology.kubernetes.io/zone", each zone is a domain of that topology. + It's a required field. + type: string + whenUnsatisfiable: + description: |- + WhenUnsatisfiable indicates how to deal with a pod if it doesn't satisfy + the spread constraint. + - DoNotSchedule (default) tells the scheduler not to schedule it. + - ScheduleAnyway tells the scheduler to schedule the pod in any location, + but giving higher precedence to topologies that would help reduce the + skew. + A constraint is considered "Unsatisfiable" for an incoming pod + if and only if every possible node assignment for that pod would violate + "MaxSkew" on some topology. + For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same + labelSelector spread as 3/1/1: + | zone1 | zone2 | zone3 | + | P P P | P | P | + If WhenUnsatisfiable is set to DoNotSchedule, incoming pod can only be scheduled + to zone2(zone3) to become 3/2/1(3/1/2) as ActualSkew(2-1) on zone2(zone3) satisfies + MaxSkew(1). In other words, the cluster can still be imbalanced, but scheduler + won't make it *more* imbalanced. + It's a required field. + type: string + required: + - maxSkew + - topologyKey + - whenUnsatisfiable + type: object + type: array + type: object + volumeClaimTemplates: + description: |- + Defines VolumeClaimTemplates to override. + Add new or override existing volume claim templates. + items: + properties: + name: + description: |- + Refers to the name of a volumeMount defined in either: + + + - `componentDefinition.spec.runtime.containers[*].volumeMounts` + - `clusterDefinition.spec.componentDefs[*].podSpec.containers[*].volumeMounts` (deprecated) + + + The value of `name` must match the `name` field of a volumeMount specified in the corresponding `volumeMounts` array. + type: string + spec: + description: |- + Defines the desired characteristics of a PersistentVolumeClaim that will be created for the volume + with the mount name specified in the `name` field. + + + When a Pod is created for this ClusterComponent, a new PVC will be created based on the specification + defined in the `spec` field. The PVC will be associated with the volume mount specified by the `name` field. + properties: + accessModes: + description: |- + Contains the desired access modes the volume should have. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1. + items: + type: string + type: array + x-kubernetes-preserve-unknown-fields: true + resources: + description: |- + Represents the minimum resources the volume should have. + If the RecoverVolumeExpansionFailure feature is enabled, users are allowed to specify resource requirements that + are lower than the previous value but must still be higher than the capacity recorded in the status field of the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources. + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + x-kubernetes-preserve-unknown-fields: true + storageClassName: + description: |- + The name of the StorageClass required by the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1. + type: string + volumeMode: + description: Defines what type of volume is + required by the claim, either Block or Filesystem. + type: string + type: object + required: + - name + type: object + type: array + volumeMounts: + description: |- + Defines VolumeMounts to override. + Add new or override existing volume mounts of the first container in the Pod. + items: + description: VolumeMount describes a mounting of a Volume + within a container. + properties: + mountPath: + description: |- + Path within the container at which the volume should be mounted. Must + not contain ':'. + type: string + mountPropagation: + description: |- + mountPropagation determines how mounts are propagated from the host + to container and the other way around. + When not set, MountPropagationNone is used. + This field is beta in 1.10. + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: |- + Mounted read-only if true, read-write otherwise (false or unspecified). + Defaults to false. + type: boolean + subPath: + description: |- + Path within the volume from which the container's volume should be mounted. + Defaults to "" (volume's root). + type: string + subPathExpr: + description: |- + Expanded path within the volume from which the container's volume should be mounted. + Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment. + Defaults to "" (volume's root). + SubPathExpr and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + volumes: + description: |- + Defines Volumes to override. + Add new or override existing volumes. + items: + description: Volume represents a named volume in a pod + that may be accessed by any container in the pod. + properties: + awsElasticBlockStore: + description: |- + awsElasticBlockStore represents an AWS Disk resource that is attached to a + kubelet's host machine and then exposed to the pod. + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + properties: + fsType: + description: |- + fsType is the filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + partition: + description: |- + partition is the partition in the volume that you want to mount. + If omitted, the default is to mount by volume name. + Examples: For volume /dev/sda1, you specify the partition as "1". + Similarly, the volume partition for /dev/sda is "0" (or you can leave the property empty). + format: int32 + type: integer + readOnly: + description: |- + readOnly value true will force the readOnly setting in VolumeMounts. + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + type: boolean + volumeID: + description: |- + volumeID is unique ID of the persistent disk resource in AWS (Amazon EBS volume). + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + type: string + required: + - volumeID + type: object + azureDisk: + description: azureDisk represents an Azure Data + Disk mount on the host and bind mount to the pod. + properties: + cachingMode: + description: 'cachingMode is the Host Caching + mode: None, Read Only, Read Write.' + type: string + diskName: + description: diskName is the Name of the data + disk in the blob storage + type: string + diskURI: + description: diskURI is the URI of data disk + in the blob storage + type: string + fsType: + description: |- + fsType is Filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + kind: + description: 'kind expected values are Shared: + multiple blob disks per storage account Dedicated: + single blob disk per storage account Managed: + azure managed data disk (only in managed availability + set). defaults to shared' + type: string + readOnly: + description: |- + readOnly Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + description: azureFile represents an Azure File + Service mount on the host and bind mount to the + pod. + properties: + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretName: + description: secretName is the name of secret + that contains Azure Storage Account Name and + Key + type: string + shareName: + description: shareName is the azure share Name + type: string + required: + - secretName + - shareName + type: object + cephfs: + description: cephFS represents a Ceph FS mount on + the host that shares a pod's lifetime + properties: + monitors: + description: |- + monitors is Required: Monitors is a collection of Ceph monitors + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + items: + type: string + type: array + path: + description: 'path is Optional: Used as the + mounted root, rather than the full Ceph tree, + default is /' + type: string + readOnly: + description: |- + readOnly is Optional: Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + type: boolean + secretFile: + description: |- + secretFile is Optional: SecretFile is the path to key ring for User, default is /etc/ceph/user.secret + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + type: string + secretRef: + description: |- + secretRef is Optional: SecretRef is reference to the authentication secret for User, default is empty. + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + 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 + user: + description: |- + user is optional: User is the rados user name, default is admin + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + type: string + required: + - monitors + type: object + cinder: + description: |- + cinder represents a cinder volume attached and mounted on kubelets host machine. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + type: string + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + type: boolean + secretRef: + description: |- + secretRef is optional: points to a secret object containing parameters used to connect + to OpenStack. + 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 + volumeID: + description: |- + volumeID used to identify the volume in cinder. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + type: string + required: + - volumeID + type: object + configMap: + description: configMap represents a configMap that + should populate this volume + properties: + defaultMode: + description: |- + defaultMode is optional: mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + items: + description: |- + items if unspecified, each key-value pair in the Data field of the referenced + ConfigMap will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the ConfigMap, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within + a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + 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 + optional: + description: optional specify whether the ConfigMap + or its keys must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + csi: + description: csi (Container Storage Interface) represents + ephemeral storage that is handled by certain external + CSI drivers (Beta feature). + properties: + driver: + description: |- + driver is the name of the CSI driver that handles this volume. + Consult with your admin for the correct name as registered in the cluster. + type: string + fsType: + description: |- + fsType to mount. Ex. "ext4", "xfs", "ntfs". + If not provided, the empty value is passed to the associated CSI driver + which will determine the default filesystem to apply. + type: string + nodePublishSecretRef: + description: |- + nodePublishSecretRef is a reference to the secret object containing + sensitive information to pass to the CSI driver to complete the CSI + NodePublishVolume and NodeUnpublishVolume calls. + This field is optional, and may be empty if no secret is required. If the + secret object contains more than one secret, all secret references are passed. + 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 + readOnly: + description: |- + readOnly specifies a read-only configuration for the volume. + Defaults to false (read/write). + type: boolean + volumeAttributes: + additionalProperties: + type: string + description: |- + volumeAttributes stores driver-specific properties that are passed to the CSI + driver. Consult your driver's documentation for supported values. + type: object + required: + - driver + type: object + downwardAPI: + description: downwardAPI represents downward API + about the pod that should populate this volume + properties: + defaultMode: + description: |- + Optional: mode bits to use on created files by default. Must be a + Optional: mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + items: + description: Items is a list of downward API + volume file + items: + description: DownwardAPIVolumeFile represents + information to create the file containing + the pod field + properties: + fieldRef: + description: 'Required: Selects a field + of the pod: only annotations, labels, + name and namespace are supported.' + properties: + apiVersion: + description: Version of the schema + the FieldPath is written in terms + of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to + select in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + description: |- + Optional: mode bits used to set permissions on this file, must be an octal value + between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: 'Required: Path is the relative + path name of the file to be created. + Must not be absolute or contain the + ''..'' path. Must be utf-8 encoded. + The first item of the relative path + must not start with ''..''' + type: string + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported. + properties: + containerName: + description: 'Container name: required + for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output + format of the exposed resources, + defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to + select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + type: object + emptyDir: + description: |- + emptyDir represents a temporary directory that shares a pod's lifetime. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir + properties: + medium: + description: |- + medium represents what type of storage medium should back this directory. + The default is "" which means to use the node's default medium. + Must be an empty string (default) or Memory. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + description: |- + sizeLimit is the total amount of local storage required for this EmptyDir volume. + The size limit is also applicable for memory medium. + The maximum usage on memory medium EmptyDir would be the minimum value between + the SizeLimit specified here and the sum of memory limits of all containers in a pod. + The default is nil which means that the limit is undefined. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + description: |- + ephemeral represents a volume that is handled by a cluster storage driver. + The volume's lifecycle is tied to the pod that defines it - it will be created before the pod starts, + and deleted when the pod is removed. + + + Use this if: + a) the volume is only needed while the pod runs, + b) features of normal volumes like restoring from snapshot or capacity + tracking are needed, + c) the storage driver is specified through a storage class, and + d) the storage driver supports dynamic volume provisioning through + a PersistentVolumeClaim (see EphemeralVolumeSource for more + information on the connection between this volume type + and PersistentVolumeClaim). + + + Use PersistentVolumeClaim or one of the vendor-specific + APIs for volumes that persist for longer than the lifecycle + of an individual pod. + + + Use CSI for light-weight local ephemeral volumes if the CSI driver is meant to + be used that way - see the documentation of the driver for + more information. + + + A pod can use both types of ephemeral volumes and + persistent volumes at the same time. + properties: + volumeClaimTemplate: + description: |- + Will be used to create a stand-alone PVC to provision the volume. + The pod in which this EphemeralVolumeSource is embedded will be the + owner of the PVC, i.e. the PVC will be deleted together with the + pod. The name of the PVC will be `-` where + `` is the name from the `PodSpec.Volumes` array + entry. Pod validation will reject the pod if the concatenated name + is not valid for a PVC (for example, too long). + + + An existing PVC with that name that is not owned by the pod + will *not* be used for the pod to avoid using an unrelated + volume by mistake. Starting the pod is then blocked until + the unrelated PVC is removed. If such a pre-created PVC is + meant to be used by the pod, the PVC has to updated with an + owner reference to the pod once the pod exists. Normally + this should not be necessary, but it may be useful when + manually reconstructing a broken cluster. + + + This field is read-only and no changes will be made by Kubernetes + to the PVC after it has been created. + + + Required, must not be nil. + properties: + metadata: + description: |- + May contain labels and annotations that will be copied into the PVC + when creating it. No other fields are allowed and will be rejected during + validation. + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + description: |- + The specification for the PersistentVolumeClaim. The entire content is + copied unchanged into the PVC that gets created from this + template. The same fields as in a PersistentVolumeClaim + are also valid here. + properties: + accessModes: + description: |- + accessModes contains the desired access modes the volume should have. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1 + items: + type: string + type: array + dataSource: + description: |- + dataSource field can be used to specify either: + * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) + * An existing PVC (PersistentVolumeClaim) + If the provisioner or an external controller can support the specified data source, + it will create a new volume based on the contents of the specified data source. + When the AnyVolumeDataSource feature gate is enabled, dataSource contents will be copied to dataSourceRef, + and dataSourceRef contents will be copied to dataSource when dataSourceRef.namespace is not specified. + If the namespace is specified, then dataSourceRef will not be copied to dataSource. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of + resource being referenced + type: string + name: + description: Name is the name of + resource being referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + description: |- + dataSourceRef specifies the object from which to populate the volume with data, if a non-empty + volume is desired. This may be any object from a non-empty API group (non + core object) or a PersistentVolumeClaim object. + When this field is specified, volume binding will only succeed if the type of + the specified object matches some installed volume populator or dynamic + provisioner. + This field will replace the functionality of the dataSource field and as such + if both fields are non-empty, they must have the same value. For backwards + compatibility, when namespace isn't specified in dataSourceRef, + both fields (dataSource and dataSourceRef) will be set to the same + value automatically if one of them is empty and the other is non-empty. + When namespace is specified in dataSourceRef, + dataSource isn't set to the same value and must be empty. + There are three important differences between dataSource and dataSourceRef: + * While dataSource only allows two specific types of objects, dataSourceRef + allows any non-core object, as well as PersistentVolumeClaim objects. + * While dataSource ignores disallowed values (dropping them), dataSourceRef + preserves all values, and generates an error if a disallowed value is + specified. + * While dataSource only allows local objects, dataSourceRef allows objects + in any namespaces. + (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled. + (Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of + resource being referenced + type: string + name: + description: Name is the name of + resource being referenced + type: string + namespace: + description: |- + Namespace is the namespace of resource being referenced + Note that when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details. + (Alpha) This field requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + type: string + required: + - kind + - name + type: object + resources: + description: |- + resources represents the minimum resources the volume should have. + If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements + that are lower than previous value but must still be higher than capacity recorded in the + status field of the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + selector: + description: selector is a label query + over volumes to consider for binding. + properties: + matchExpressions: + description: matchExpressions is + a list of label selector requirements. + The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + description: |- + storageClassName is the name of the StorageClass required by the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1 + type: string + volumeAttributesClassName: + description: |- + volumeAttributesClassName may be used to set the VolumeAttributesClass used by this claim. + If specified, the CSI driver will create or update the volume with the attributes defined + in the corresponding VolumeAttributesClass. This has a different purpose than storageClassName, + it can be changed after the claim is created. An empty string value means that no VolumeAttributesClass + will be applied to the claim but it's not allowed to reset this field to empty string once it is set. + If unspecified and the PersistentVolumeClaim is unbound, the default VolumeAttributesClass + will be set by the persistentvolume controller if it exists. + If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be + set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource + exists. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#volumeattributesclass + (Alpha) Using this field requires the VolumeAttributesClass feature gate to be enabled. + type: string + volumeMode: + description: |- + volumeMode defines what type of volume is required by the claim. + Value of Filesystem is implied when not included in claim spec. + type: string + volumeName: + description: volumeName is the binding + reference to the PersistentVolume + backing this claim. + type: string + type: object + required: + - spec + type: object + type: object + fc: + description: fc represents a Fibre Channel resource + that is attached to a kubelet's host machine and + then exposed to the pod. + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + lun: + description: 'lun is Optional: FC target lun + number' + format: int32 + type: integer + readOnly: + description: |- + readOnly is Optional: Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + targetWWNs: + description: 'targetWWNs is Optional: FC target + worldwide names (WWNs)' + items: + type: string + type: array + wwids: + description: |- + wwids Optional: FC volume world wide identifiers (wwids) + Either wwids or combination of targetWWNs and lun must be set, but not both simultaneously. + items: + type: string + type: array + type: object + flexVolume: + description: |- + flexVolume represents a generic volume resource that is + provisioned/attached using an exec based plugin. + properties: + driver: + description: driver is the name of the driver + to use for this volume. + type: string + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". The default filesystem depends on FlexVolume script. + type: string + options: + additionalProperties: + type: string + description: 'options is Optional: this field + holds extra command options if any.' + type: object + readOnly: + description: |- + readOnly is Optional: defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: |- + secretRef is Optional: secretRef is reference to the secret object containing + sensitive information to pass to the plugin scripts. This may be + empty if no secret object is specified. If the secret object + contains more than one secret, all secrets are passed to the plugin + scripts. + 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 + required: + - driver + type: object + flocker: + description: flocker represents a Flocker volume + attached to a kubelet's host machine. This depends + on the Flocker control service being running + properties: + datasetName: + description: |- + datasetName is Name of the dataset stored as metadata -> name on the dataset for Flocker + should be considered as deprecated + type: string + datasetUUID: + description: datasetUUID is the UUID of the + dataset. This is unique identifier of a Flocker + dataset + type: string + type: object + gcePersistentDisk: + description: |- + gcePersistentDisk represents a GCE Disk resource that is attached to a + kubelet's host machine and then exposed to the pod. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + properties: + fsType: + description: |- + fsType is filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + partition: + description: |- + partition is the partition in the volume that you want to mount. + If omitted, the default is to mount by volume name. + Examples: For volume /dev/sda1, you specify the partition as "1". + Similarly, the volume partition for /dev/sda is "0" (or you can leave the property empty). + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + format: int32 + type: integer + pdName: + description: |- + pdName is unique name of the PD resource in GCE. Used to identify the disk in GCE. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + type: string + readOnly: + description: |- + readOnly here will force the ReadOnly setting in VolumeMounts. + Defaults to false. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + type: boolean + required: + - pdName + type: object + gitRepo: + description: |- + gitRepo represents a git repository at a particular revision. + DEPRECATED: GitRepo is deprecated. To provision a container with a git repo, mount an + EmptyDir into an InitContainer that clones the repo using git, then mount the EmptyDir + into the Pod's container. + properties: + directory: + description: |- + directory is the target directory name. + Must not contain or start with '..'. If '.' is supplied, the volume directory will be the + git repository. Otherwise, if specified, the volume will contain the git repository in + the subdirectory with the given name. + type: string + repository: + description: repository is the URL + type: string + revision: + description: revision is the commit hash for + the specified revision. + type: string + required: + - repository + type: object + glusterfs: + description: |- + glusterfs represents a Glusterfs mount on the host that shares a pod's lifetime. + More info: https://examples.k8s.io/volumes/glusterfs/README.md + properties: + endpoints: + description: |- + endpoints is the endpoint name that details Glusterfs topology. + More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod + type: string + path: + description: |- + path is the Glusterfs volume path. + More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod + type: string + readOnly: + description: |- + readOnly here will force the Glusterfs volume to be mounted with read-only permissions. + Defaults to false. + More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod + type: boolean + required: + - endpoints + - path + type: object + hostPath: + description: |- + hostPath represents a pre-existing file or directory on the host + machine that is directly exposed to the container. This is generally + used for system agents or other privileged things that are allowed + to see the host machine. Most containers will NOT need this. + More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + --- + TODO(jonesdl) We need to restrict who can use host directory mounts and who can/can not + mount host directories as read/write. + properties: + path: + description: |- + path of the directory on the host. + If the path is a symlink, it will follow the link to the real path. + More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + type: string + type: + description: |- + type for HostPath Volume + Defaults to "" + More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + type: string + required: + - path + type: object + iscsi: + description: |- + iscsi represents an ISCSI Disk resource that is attached to a + kubelet's host machine and then exposed to the pod. + More info: https://examples.k8s.io/volumes/iscsi/README.md + properties: + chapAuthDiscovery: + description: chapAuthDiscovery defines whether + support iSCSI Discovery CHAP authentication + type: boolean + chapAuthSession: + description: chapAuthSession defines whether + support iSCSI Session CHAP authentication + type: boolean + fsType: + description: |- + fsType is the filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#iscsi + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + initiatorName: + description: |- + initiatorName is the custom iSCSI Initiator Name. + If initiatorName is specified with iscsiInterface simultaneously, new iSCSI interface + : will be created for the connection. + type: string + iqn: + description: iqn is the target iSCSI Qualified + Name. + type: string + iscsiInterface: + description: |- + iscsiInterface is the interface Name that uses an iSCSI transport. + Defaults to 'default' (tcp). + type: string + lun: + description: lun represents iSCSI Target Lun + number. + format: int32 + type: integer + portals: + description: |- + portals is the iSCSI Target Portal List. The portal is either an IP or ip_addr:port if the port + is other than default (typically TCP ports 860 and 3260). + items: + type: string + type: array + readOnly: + description: |- + readOnly here will force the ReadOnly setting in VolumeMounts. + Defaults to false. + type: boolean + secretRef: + description: secretRef is the CHAP Secret for + iSCSI target and initiator authentication + 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 + targetPortal: + description: |- + targetPortal is iSCSI Target Portal. The Portal is either an IP or ip_addr:port if the port + is other than default (typically TCP ports 860 and 3260). + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + description: |- + name of the volume. + Must be a DNS_LABEL and unique within the pod. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + nfs: + description: |- + nfs represents an NFS mount on the host that shares a pod's lifetime + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + properties: + path: + description: |- + path that is exported by the NFS server. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + type: string + readOnly: + description: |- + readOnly here will force the NFS export to be mounted with read-only permissions. + Defaults to false. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + type: boolean + server: + description: |- + server is the hostname or IP address of the NFS server. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + description: |- + persistentVolumeClaimVolumeSource represents a reference to a + PersistentVolumeClaim in the same namespace. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims + properties: + claimName: + description: |- + claimName is the name of a PersistentVolumeClaim in the same namespace as the pod using this volume. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims + type: string + readOnly: + description: |- + readOnly Will force the ReadOnly setting in VolumeMounts. + Default false. + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + description: photonPersistentDisk represents a PhotonController + persistent disk attached and mounted on kubelets + host machine + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + pdID: + description: pdID is the ID that identifies + Photon Controller persistent disk + type: string + required: + - pdID + type: object + portworxVolume: + description: portworxVolume represents a portworx + volume attached and mounted on kubelets host machine + properties: + fsType: + description: |- + fSType represents the filesystem type to mount + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs". Implicitly inferred to be "ext4" if unspecified. + type: string + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + volumeID: + description: volumeID uniquely identifies a + Portworx volume + type: string + required: + - volumeID + type: object + projected: + description: projected items for all in one resources + secrets, configmaps, and downward API + properties: + defaultMode: + description: |- + defaultMode are the mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + sources: + description: sources is the list of volume projections + items: + description: Projection that may be projected + along with other supported volume types + properties: + clusterTrustBundle: + description: |- + ClusterTrustBundle allows a pod to access the `.spec.trustBundle` field + of ClusterTrustBundle objects in an auto-updating file. + + + Alpha, gated by the ClusterTrustBundleProjection feature gate. + + + ClusterTrustBundle objects can either be selected by name, or by the + combination of signer name and a label selector. + + + Kubelet performs aggressive normalization of the PEM contents written + into the pod filesystem. Esoteric PEM features such as inter-block + comments and block headers are stripped. Certificates are deduplicated. + The ordering of certificates within the file is arbitrary, and Kubelet + may change the order over time. + properties: + labelSelector: + description: |- + Select all ClusterTrustBundles that match this label selector. Only has + effect if signerName is set. Mutually-exclusive with name. If unset, + interpreted as "match nothing". If set but empty, interpreted as "match + everything". + properties: + matchExpressions: + description: matchExpressions + is a list of label selector + requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the + label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + name: + description: |- + Select a single ClusterTrustBundle by object name. Mutually-exclusive + with signerName and labelSelector. + type: string + optional: + description: |- + If true, don't block pod startup if the referenced ClusterTrustBundle(s) + aren't available. If using name, then the named ClusterTrustBundle is + allowed not to exist. If using signerName, then the combination of + signerName and labelSelector is allowed to match zero + ClusterTrustBundles. + type: boolean + path: + description: Relative path from the + volume root to write the bundle. + type: string + signerName: + description: |- + Select all ClusterTrustBundles that match this signer name. + Mutually-exclusive with name. The contents of all selected + ClusterTrustBundles will be unified and deduplicated. + type: string + required: + - path + type: object + configMap: + description: configMap information about + the configMap data to project + properties: + items: + description: |- + items if unspecified, each key-value pair in the Data field of the referenced + ConfigMap will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the ConfigMap, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to + a path within a volume. + properties: + key: + description: key is the key + to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + 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 + optional: + description: optional specify whether + the ConfigMap or its keys must be + defined + type: boolean + type: object + x-kubernetes-map-type: atomic + downwardAPI: + description: downwardAPI information about + the downwardAPI data to project + properties: + items: + description: Items is a list of DownwardAPIVolume + file + items: + description: DownwardAPIVolumeFile + represents information to create + the file containing the pod field + properties: + fieldRef: + description: 'Required: Selects + a field of the pod: only annotations, + labels, name and namespace + are supported.' + properties: + apiVersion: + description: Version of + the schema the FieldPath + is written in terms of, + defaults to "v1". + type: string + fieldPath: + description: Path of the + field to select in the + specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + description: |- + Optional: mode bits used to set permissions on this file, must be an octal value + between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: 'Required: Path + is the relative path name + of the file to be created. + Must not be absolute or contain + the ''..'' path. Must be utf-8 + encoded. The first item of + the relative path must not + start with ''..''' + type: string + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported. + properties: + containerName: + description: 'Container + name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the + output format of the exposed + resources, defaults to + "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: + resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + type: object + secret: + description: secret information about + the secret data to project + properties: + items: + description: |- + items if unspecified, each key-value pair in the Data field of the referenced + Secret will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the Secret, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to + a path within a volume. + properties: + key: + description: key is the key + to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + 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 + optional: + description: optional field specify + whether the Secret or its key must + be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + serviceAccountToken: + description: serviceAccountToken is information + about the serviceAccountToken data to + project + properties: + audience: + description: |- + audience is the intended audience of the token. A recipient of a token + must identify itself with an identifier specified in the audience of the + token, and otherwise should reject the token. The audience defaults to the + identifier of the apiserver. + type: string + expirationSeconds: + description: |- + expirationSeconds is the requested duration of validity of the service + account token. As the token approaches expiration, the kubelet volume + plugin will proactively rotate the service account token. The kubelet will + start trying to rotate the token if the token is older than 80 percent of + its time to live or if the token is older than 24 hours.Defaults to 1 hour + and must be at least 10 minutes. + format: int64 + type: integer + path: + description: |- + path is the path relative to the mount point of the file to project the + token into. + type: string + required: + - path + type: object + type: object + type: array + type: object + quobyte: + description: quobyte represents a Quobyte mount + on the host that shares a pod's lifetime + properties: + group: + description: |- + group to map volume access to + Default is no group + type: string + readOnly: + description: |- + readOnly here will force the Quobyte volume to be mounted with read-only permissions. + Defaults to false. + type: boolean + registry: + description: |- + registry represents a single or multiple Quobyte Registry services + specified as a string as host:port pair (multiple entries are separated with commas) + which acts as the central registry for volumes + type: string + tenant: + description: |- + tenant owning the given Quobyte volume in the Backend + Used with dynamically provisioned Quobyte volumes, value is set by the plugin + type: string + user: + description: |- + user to map volume access to + Defaults to serivceaccount user + type: string + volume: + description: volume is a string that references + an already created Quobyte volume by name. + type: string + required: + - registry + - volume + type: object + rbd: + description: |- + rbd represents a Rados Block Device mount on the host that shares a pod's lifetime. + More info: https://examples.k8s.io/volumes/rbd/README.md + properties: + fsType: + description: |- + fsType is the filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#rbd + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + image: + description: |- + image is the rados image name. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + keyring: + description: |- + keyring is the path to key ring for RBDUser. + Default is /etc/ceph/keyring. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + monitors: + description: |- + monitors is a collection of Ceph monitors. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + items: + type: string + type: array + pool: + description: |- + pool is the rados pool name. + Default is rbd. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + readOnly: + description: |- + readOnly here will force the ReadOnly setting in VolumeMounts. + Defaults to false. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: boolean + secretRef: + description: |- + secretRef is name of the authentication secret for RBDUser. If provided + overrides keyring. + Default is nil. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + 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 + user: + description: |- + user is the rados user name. + Default is admin. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + required: + - image + - monitors + type: object + scaleIO: + description: scaleIO represents a ScaleIO persistent + volume attached and mounted on Kubernetes nodes. + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". + Default is "xfs". + type: string + gateway: + description: gateway is the host address of + the ScaleIO API Gateway. + type: string + protectionDomain: + description: protectionDomain is the name of + the ScaleIO Protection Domain for the configured + storage. + type: string + readOnly: + description: |- + readOnly Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: |- + secretRef references to the secret for ScaleIO user and other + sensitive information. If this is not provided, Login operation will fail. + 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 + sslEnabled: + description: sslEnabled Flag enable/disable + SSL communication with Gateway, default false + type: boolean + storageMode: + description: |- + storageMode indicates whether the storage for a volume should be ThickProvisioned or ThinProvisioned. + Default is ThinProvisioned. + type: string + storagePool: + description: storagePool is the ScaleIO Storage + Pool associated with the protection domain. + type: string + system: + description: system is the name of the storage + system as configured in ScaleIO. + type: string + volumeName: + description: |- + volumeName is the name of a volume already created in the ScaleIO system + that is associated with this volume source. + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + description: |- + secret represents a secret that should populate this volume. + More info: https://kubernetes.io/docs/concepts/storage/volumes#secret + properties: + defaultMode: + description: |- + defaultMode is Optional: mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values + for mode bits. Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + items: + description: |- + items If unspecified, each key-value pair in the Data field of the referenced + Secret will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the Secret, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within + a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + optional: + description: optional field specify whether + the Secret or its keys must be defined + type: boolean + secretName: + description: |- + secretName is the name of the secret in the pod's namespace to use. + More info: https://kubernetes.io/docs/concepts/storage/volumes#secret + type: string + type: object + storageos: + description: storageOS represents a StorageOS volume + attached and mounted on Kubernetes nodes. + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: |- + secretRef specifies the secret to use for obtaining the StorageOS API + credentials. If not specified, default values will be attempted. + 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 + volumeName: + description: |- + volumeName is the human-readable name of the StorageOS volume. Volume + names are only unique within a namespace. + type: string + volumeNamespace: + description: |- + volumeNamespace specifies the scope of the volume within StorageOS. If no + namespace is specified then the Pod's namespace will be used. This allows the + Kubernetes name scoping to be mirrored within StorageOS for tighter integration. + Set VolumeName to any name to override the default behaviour. + Set to "default" if you are not using namespaces within StorageOS. + Namespaces that do not pre-exist within StorageOS will be created. + type: string + type: object + vsphereVolume: + description: vsphereVolume represents a vSphere + volume attached and mounted on kubelets host machine + properties: + fsType: + description: |- + fsType is filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + storagePolicyID: + description: storagePolicyID is the storage + Policy Based Management (SPBM) profile ID + associated with the StoragePolicyName. + type: string + storagePolicyName: + description: storagePolicyName is the storage + Policy Based Management (SPBM) profile name. + type: string + volumePath: + description: volumePath is the path that identifies + vSphere volume vmdk + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + issuer: + description: |- + Specifies the configuration for the TLS certificates issuer. + It allows defining the issuer name and the reference to the secret containing the TLS certificates and key. + The secret should contain the CA certificate, TLS certificate, and private key in the specified keys. + Required when TLS is enabled. + properties: + name: + allOf: + - enum: + - KubeBlocks + - UserProvided + - enum: + - KubeBlocks + - UserProvided + default: KubeBlocks + description: |- + The issuer for TLS certificates. + It only allows two enum values: `KubeBlocks` and `UserProvided`. + + + - `KubeBlocks` indicates that the self-signed TLS certificates generated by the KubeBlocks Operator will be used. + - `UserProvided` means that the user is responsible for providing their own CA, Cert, and Key. + In this case, the user-provided CA certificate, server certificate, and private key will be used + for TLS communication. + type: string + secretRef: + description: |- + SecretRef is the reference to the secret that contains user-provided certificates. + It is required when the issuer is set to `UserProvided`. + properties: + ca: + description: Key of CA cert in Secret + type: string + cert: + description: Key of Cert in Secret + type: string + key: + description: Key of TLS private key in Secret + type: string + name: + description: Name of the Secret that contains user-provided + certificates. + type: string + required: + - ca + - cert + - key + - name + type: object + required: + - name + type: object + labels: + additionalProperties: + type: string + description: Specifies Labels to override or add for underlying + Pods. + type: object + monitor: + description: |- + Deprecated since v0.9 + Determines whether metrics exporter information is annotated on the Component's headless Service. + + + If set to true, the following annotations will be patched into the Service: + + + - "monitor.kubeblocks.io/path" + - "monitor.kubeblocks.io/port" + - "monitor.kubeblocks.io/scheme" + + + These annotations allow the Prometheus installed by KubeBlocks to discover and scrape metrics from the exporter. + type: boolean + name: + description: |- + Specifies the Component's name. + It's part of the Service DNS name and must comply with the IANA service naming rule. + The name is optional when ClusterComponentSpec is used as a template (e.g., in `shardingSpec`), + but required otherwise. + + + TODO +kubebuilder:validation:XValidation:rule="self == oldSelf",message="name is immutable" + maxLength: 22 + pattern: ^[a-z]([a-z0-9\-]*[a-z0-9])?$ + type: string + offlineInstances: + description: |- + Specifies the names of instances to be transitioned to offline status. + + + Marking an instance as offline results in the following: + + + 1. The associated Pod is stopped, and its PersistentVolumeClaim (PVC) is retained for potential + future reuse or data recovery, but it is no longer actively used. + 2. The ordinal number assigned to this instance is preserved, ensuring it remains unique + and avoiding conflicts with new instances. + + + Setting instances to offline allows for a controlled scale-in process, preserving their data and maintaining + ordinal consistency within the Cluster. + Note that offline instances and their associated resources, such as PVCs, are not automatically deleted. + The administrator must manually manage the cleanup and removal of these resources when they are no longer needed. + items: + type: string + type: array + parallelPodManagementConcurrency: + anyOf: + - type: integer + - type: string + description: |- + Controls the concurrency of pods during initial scale up, when replacing pods on nodes, + or when scaling down. It only used when `PodManagementPolicy` is set to `Parallel`. + The default Concurrency is 100%. + x-kubernetes-int-or-string: true + podUpdatePolicy: + description: |- + PodUpdatePolicy indicates how pods should be updated + + + - `StrictInPlace` indicates that only allows in-place upgrades. + Any attempt to modify other fields will be rejected. + - `PreferInPlace` indicates that we will first attempt an in-place upgrade of the Pod. + If that fails, it will fall back to the ReCreate, where pod will be recreated. + Default value is "PreferInPlace" + enum: + - StrictInPlace + - PreferInPlace + type: string + replicas: + default: 1 + description: Specifies the desired number of replicas in the + Component for enhancing availability and durability, or load + balancing. + format: int32 + minimum: 0 + type: integer + resources: + description: |- + Specifies the resources required by the Component. + It allows defining the CPU, memory requirements and limits for the Component's containers. + properties: + claims: + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + + + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + + + This field is immutable. It can only be set for containers. + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + x-kubernetes-preserve-unknown-fields: true + schedulingPolicy: + description: Specifies the scheduling policy for the Component. + properties: + affinity: + description: Specifies a group of affinity scheduling rules + of the Cluster, including NodeAffinity, PodAffinity, and + PodAntiAffinity. + properties: + nodeAffinity: + description: Describes node affinity scheduling rules + for the pod. + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node matches the corresponding matchExpressions; the + node(s) with the highest sum are the most preferred. + items: + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). + properties: + preference: + description: A node selector term, associated + with the corresponding weight. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that + the selector applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that + the selector applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + weight: + description: Weight associated with matching + the corresponding nodeSelectorTerm, in the + range 1-100. + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. + properties: + nodeSelectorTerms: + description: Required. A list of node selector + terms. The terms are ORed. + items: + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that + the selector applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that + the selector applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + type: array + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + description: Describes pod affinity scheduling rules + (e.g. co-locate this pod in the same node, zone, etc. + as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched + WeightedPodAffinityTerm fields are added per-node + to find the most preferred node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, + associated with the corresponding weight. + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a + list of label selector requirements. + The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. + Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a + list of label selector requirements. + The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: |- + weight associated with matching the corresponding podAffinityTerm, + in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. + items: + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. + Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + description: Describes pod anti-affinity scheduling + rules (e.g. avoid putting this pod in the same node, + zone, etc. as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the anti-affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched + WeightedPodAffinityTerm fields are added per-node + to find the most preferred node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, + associated with the corresponding weight. + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a + list of label selector requirements. + The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. + Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a + list of label selector requirements. + The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: |- + weight associated with matching the corresponding podAffinityTerm, + in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the anti-affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the anti-affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. + items: + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. + Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + nodeName: + description: |- + NodeName is a request to schedule this Pod onto a specific node. If it is non-empty, + the scheduler simply schedules this Pod onto that node, assuming that it fits resource + requirements. + type: string + nodeSelector: + additionalProperties: + type: string + description: |- + NodeSelector is a selector which must be true for the Pod to fit on a node. + Selector which must match a node's labels for the Pod to be scheduled on that node. + More info: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ + type: object + x-kubernetes-map-type: atomic + schedulerName: + description: |- + If specified, the Pod will be dispatched by specified scheduler. + If not specified, the Pod will be dispatched by default scheduler. + type: string + tolerations: + description: |- + Allows Pods to be scheduled onto nodes with matching taints. + Each toleration in the array allows the Pod to tolerate node taints based on + specified `key`, `value`, `effect`, and `operator`. + + + - The `key`, `value`, and `effect` identify the taint that the toleration matches. + - The `operator` determines how the toleration matches the taint. + + + Pods with matching tolerations are allowed to be scheduled on tainted nodes, typically reserved for specific purposes. + items: + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . + properties: + effect: + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. + type: string + operator: + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. + type: string + tolerationSeconds: + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. + format: int64 + type: integer + value: + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. + type: string + type: object + type: array + topologySpreadConstraints: + description: |- + TopologySpreadConstraints describes how a group of Pods ought to spread across topology + domains. Scheduler will schedule Pods in a way which abides by the constraints. + All topologySpreadConstraints are ANDed. + items: + description: TopologySpreadConstraint specifies how to + spread matching pods among the given topology. + properties: + labelSelector: + description: |- + LabelSelector is used to find matching pods. + Pods that match this label selector are counted to determine the number of pods + in their corresponding topology domain. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select the pods over which + spreading will be calculated. The keys are used to lookup values from the + incoming pod labels, those key-value labels are ANDed with labelSelector + to select the group of existing pods over which spreading will be calculated + for the incoming pod. The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + MatchLabelKeys cannot be set when LabelSelector isn't set. + Keys that don't exist in the incoming pod labels will + be ignored. A null or empty list means only match against labelSelector. + + + This is a beta field and requires the MatchLabelKeysInPodTopologySpread feature gate to be enabled (enabled by default). + items: + type: string + type: array + x-kubernetes-list-type: atomic + maxSkew: + description: |- + MaxSkew describes the degree to which pods may be unevenly distributed. + When `whenUnsatisfiable=DoNotSchedule`, it is the maximum permitted difference + between the number of matching pods in the target topology and the global minimum. + The global minimum is the minimum number of matching pods in an eligible domain + or zero if the number of eligible domains is less than MinDomains. + For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same + labelSelector spread as 2/2/1: + In this case, the global minimum is 1. + | zone1 | zone2 | zone3 | + | P P | P P | P | + - if MaxSkew is 1, incoming pod can only be scheduled to zone3 to become 2/2/2; + scheduling it onto zone1(zone2) would make the ActualSkew(3-1) on zone1(zone2) + violate MaxSkew(1). + - if MaxSkew is 2, incoming pod can be scheduled onto any zone. + When `whenUnsatisfiable=ScheduleAnyway`, it is used to give higher precedence + to topologies that satisfy it. + It's a required field. Default value is 1 and 0 is not allowed. + format: int32 + type: integer + minDomains: + description: |- + MinDomains indicates a minimum number of eligible domains. + When the number of eligible domains with matching topology keys is less than minDomains, + Pod Topology Spread treats "global minimum" as 0, and then the calculation of Skew is performed. + And when the number of eligible domains with matching topology keys equals or greater than minDomains, + this value has no effect on scheduling. + As a result, when the number of eligible domains is less than minDomains, + scheduler won't schedule more than maxSkew Pods to those domains. + If value is nil, the constraint behaves as if MinDomains is equal to 1. + Valid values are integers greater than 0. + When value is not nil, WhenUnsatisfiable must be DoNotSchedule. + + + For example, in a 3-zone cluster, MaxSkew is set to 2, MinDomains is set to 5 and pods with the same + labelSelector spread as 2/2/2: + | zone1 | zone2 | zone3 | + | P P | P P | P P | + The number of domains is less than 5(MinDomains), so "global minimum" is treated as 0. + In this situation, new pod with the same labelSelector cannot be scheduled, + because computed skew will be 3(3 - 0) if new Pod is scheduled to any of the three zones, + it will violate MaxSkew. + + + This is a beta field and requires the MinDomainsInPodTopologySpread feature gate to be enabled (enabled by default). + format: int32 + type: integer + nodeAffinityPolicy: + description: |- + NodeAffinityPolicy indicates how we will treat Pod's nodeAffinity/nodeSelector + when calculating pod topology spread skew. Options are: + - Honor: only nodes matching nodeAffinity/nodeSelector are included in the calculations. + - Ignore: nodeAffinity/nodeSelector are ignored. All nodes are included in the calculations. + + + If this value is nil, the behavior is equivalent to the Honor policy. + This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag. + type: string + nodeTaintsPolicy: + description: |- + NodeTaintsPolicy indicates how we will treat node taints when calculating + pod topology spread skew. Options are: + - Honor: nodes without taints, along with tainted nodes for which the incoming pod + has a toleration, are included. + - Ignore: node taints are ignored. All nodes are included. + + + If this value is nil, the behavior is equivalent to the Ignore policy. + This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag. + type: string + topologyKey: + description: |- + TopologyKey is the key of node labels. Nodes that have a label with this key + and identical values are considered to be in the same topology. + We consider each as a "bucket", and try to put balanced number + of pods into each bucket. + We define a domain as a particular instance of a topology. + Also, we define an eligible domain as a domain whose nodes meet the requirements of + nodeAffinityPolicy and nodeTaintsPolicy. + e.g. If TopologyKey is "kubernetes.io/hostname", each Node is a domain of that topology. + And, if TopologyKey is "topology.kubernetes.io/zone", each zone is a domain of that topology. + It's a required field. + type: string + whenUnsatisfiable: + description: |- + WhenUnsatisfiable indicates how to deal with a pod if it doesn't satisfy + the spread constraint. + - DoNotSchedule (default) tells the scheduler not to schedule it. + - ScheduleAnyway tells the scheduler to schedule the pod in any location, + but giving higher precedence to topologies that would help reduce the + skew. + A constraint is considered "Unsatisfiable" for an incoming pod + if and only if every possible node assignment for that pod would violate + "MaxSkew" on some topology. + For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same + labelSelector spread as 3/1/1: + | zone1 | zone2 | zone3 | + | P P P | P | P | + If WhenUnsatisfiable is set to DoNotSchedule, incoming pod can only be scheduled + to zone2(zone3) to become 3/2/1(3/1/2) as ActualSkew(2-1) on zone2(zone3) satisfies + MaxSkew(1). In other words, the cluster can still be imbalanced, but scheduler + won't make it *more* imbalanced. + It's a required field. + type: string + required: + - maxSkew + - topologyKey + - whenUnsatisfiable + type: object + type: array + type: object + serviceAccountName: + description: |- + Specifies the name of the ServiceAccount required by the running Component. + This ServiceAccount is used to grant necessary permissions for the Component's Pods to interact + with other Kubernetes resources, such as modifying Pod labels or sending events. + + + Defaults: + To perform certain operational tasks, agent sidecars running in Pods require specific RBAC permissions. + The service account will be bound to a default role named "kubeblocks-cluster-pod-role" which is installed together with KubeBlocks. + If not specified, KubeBlocks automatically assigns a default ServiceAccount named "kb-{cluster.name}" + + + Future Changes: + Future versions might change the default ServiceAccount creation strategy to one per Component, + potentially revising the naming to "kb-{cluster.name}-{component.name}". + + + Users can override the automatic ServiceAccount assignment by explicitly setting the name of + an existed ServiceAccount in this field. + type: string + serviceRefs: + description: |- + Defines a list of ServiceRef for a Component, enabling access to both external services and + Services provided by other Clusters. + + + Types of services: + + + - External services: Not managed by KubeBlocks or managed by a different KubeBlocks operator; + Require a ServiceDescriptor for connection details. + - Services provided by a Cluster: Managed by the same KubeBlocks operator; + identified using Cluster, Component and Service names. + + + ServiceRefs with identical `serviceRef.name` in the same Cluster are considered the same. + + + Example: + ```yaml + serviceRefs: + - name: "redis-sentinel" + serviceDescriptor: + name: "external-redis-sentinel" + - name: "postgres-cluster" + clusterServiceSelector: + cluster: "my-postgres-cluster" + service: + component: "postgresql" + ``` + The example above includes ServiceRefs to an external Redis Sentinel service and a PostgreSQL Cluster. + items: + properties: + cluster: + description: |- + Specifies the name of the KubeBlocks Cluster being referenced. + This is used when services from another KubeBlocks Cluster are consumed. + + + By default, the referenced KubeBlocks Cluster's `clusterDefinition.spec.connectionCredential` + will be utilized to bind to the current Component. This credential should include: + `endpoint`, `port`, `username`, and `password`. + + + Note: + + + - The `ServiceKind` and `ServiceVersion` specified in the service reference within the + ClusterDefinition are not validated when using this approach. + - If both `cluster` and `serviceDescriptor` are present, `cluster` will take precedence. + + + Deprecated since v0.9 since `clusterDefinition.spec.connectionCredential` is deprecated, + use `clusterServiceSelector` instead. + This field is maintained for backward compatibility and its use is discouraged. + Existing usage should be updated to the current preferred approach to avoid compatibility issues in future releases. + type: string + clusterServiceSelector: + description: |- + References a service provided by another KubeBlocks Cluster. + It specifies the ClusterService and the account credentials needed for access. + properties: + cluster: + description: The name of the Cluster being referenced. + type: string + credential: + description: |- + Specifies the SystemAccount to authenticate and establish a connection with the referenced Cluster. + The SystemAccount should be defined in `componentDefinition.spec.systemAccounts` + of the Component providing the service in the referenced Cluster. + properties: + component: + description: The name of the Component where the + credential resides in. + type: string + name: + description: The name of the credential (SystemAccount) + to reference. + type: string + required: + - component + - name + type: object + service: + description: Identifies a ClusterService from the + list of Services defined in `cluster.spec.services` + of the referenced Cluster. + properties: + component: + description: |- + The name of the Component where the Service resides in. + + + It is required when referencing a Component's Service. + type: string + port: + description: |- + The port name of the Service to be referenced. + + + If there is a non-zero node-port exist for the matched Service port, the node-port will be selected first. + + + If the referenced Service is of pod-service type (a Service per Pod), there will be multiple Service objects matched, + and the resolved value will be presented in the following format: service1.name:port1,service2.name:port2... + type: string + service: + description: |- + The name of the Service to be referenced. + + + Leave it empty to reference the default Service. Set it to "headless" to reference the default headless Service. + + + If the referenced Service is of pod-service type (a Service per Pod), there will be multiple Service objects matched, + and the resolved value will be presented in the following format: service1.name,service2.name... + type: string + required: + - service + type: object + required: + - cluster + type: object + name: + description: |- + Specifies the identifier of the service reference declaration. + It corresponds to the serviceRefDeclaration name defined in either: + + + - `componentDefinition.spec.serviceRefDeclarations[*].name` + - `clusterDefinition.spec.componentDefs[*].serviceRefDeclarations[*].name` (deprecated) + type: string + namespace: + description: |- + Specifies the namespace of the referenced Cluster or the namespace of the referenced ServiceDescriptor object. + If not provided, the referenced Cluster and ServiceDescriptor will be searched in the namespace of the current + Cluster by default. + type: string + serviceDescriptor: + description: |- + Specifies the name of the ServiceDescriptor object that describes a service provided by external sources. + + + When referencing a service provided by external sources, a ServiceDescriptor object is required to establish + the service binding. + The `serviceDescriptor.spec.serviceKind` and `serviceDescriptor.spec.serviceVersion` should match the serviceKind + and serviceVersion declared in the definition. + + + If both `cluster` and `serviceDescriptor` are specified, the `cluster` takes precedence. + type: string + required: + - name + type: object + type: array + serviceVersion: + description: |- + ServiceVersion specifies the version of the Service expected to be provisioned by this Component. + The version should follow the syntax and semantics of the "Semantic Versioning" specification (http://semver.org/). + If no version is specified, the latest available version will be used. + maxLength: 32 + type: string + services: + description: Overrides services defined in referenced ComponentDefinition + and expose endpoints that can be accessed by clients. + items: + properties: + annotations: + additionalProperties: + type: string + description: |- + If ServiceType is LoadBalancer, cloud provider related parameters can be put here. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#loadbalancer. + type: object + name: + description: References the ComponentService name defined + in the `componentDefinition.spec.services[*].name`. + maxLength: 25 + type: string + podService: + description: |- + Indicates whether to generate individual Services for each Pod. + If set to true, a separate Service will be created for each Pod in the Cluster. + type: boolean + serviceType: + default: ClusterIP + description: |- + Determines how the Service is exposed. Valid options are `ClusterIP`, `NodePort`, and `LoadBalancer`. + + + - `ClusterIP` allocates a Cluster-internal IP address for load-balancing to endpoints. + Endpoints are determined by the selector or if that is not specified, + they are determined by manual construction of an Endpoints object or EndpointSlice objects. + - `NodePort` builds on ClusterIP and allocates a port on every node which routes to the same endpoints as the ClusterIP. + - `LoadBalancer` builds on NodePort and creates an external load-balancer (if supported in the current cloud) + which routes to the same endpoints as the ClusterIP. + + + Note: although K8s Service type allows the 'ExternalName' type, it is not a valid option for ClusterComponentService. + + + For more info, see: + https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types. + enum: + - ClusterIP + - NodePort + - LoadBalancer + type: string + x-kubernetes-preserve-unknown-fields: true + required: + - name + type: object + type: array + stop: + description: |- + Stop the Component. + If set, all the computing resources will be released. + type: boolean + systemAccounts: + description: Overrides system accounts defined in referenced + ComponentDefinition. + items: + properties: + name: + description: The name of the system account. + type: string + passwordConfig: + description: |- + Specifies the policy for generating the account's password. + + + This field is immutable once set. + properties: + length: + default: 16 + description: The length of the password. + format: int32 + maximum: 32 + minimum: 8 + type: integer + letterCase: + default: MixedCases + description: The case of the letters in the password. + enum: + - LowerCases + - UpperCases + - MixedCases + type: string + numDigits: + default: 4 + description: The number of digits in the password. + format: int32 + maximum: 8 + minimum: 0 + type: integer + numSymbols: + default: 0 + description: The number of symbols in the password. + format: int32 + maximum: 8 + minimum: 0 + type: integer + seed: + description: |- + Seed to generate the account's password. + Cannot be updated. + type: string + type: object + secretRef: + description: |- + Refers to the secret from which data will be copied to create the new account. + + + This field is immutable once set. + properties: + name: + description: The unique identifier of the secret. + type: string + namespace: + description: The namespace where the secret is located. + type: string + required: + - name + - namespace + type: object + required: + - name + type: object + type: array + tls: + description: |- + A boolean flag that indicates whether the Component should use Transport Layer Security (TLS) + for secure communication. + When set to true, the Component will be configured to use TLS encryption for its network connections. + This ensures that the data transmitted between the Component and its clients or other Components is encrypted + and protected from unauthorized access. + If TLS is enabled, the Component may require additional configuration, such as specifying TLS certificates and keys, + to properly set up the secure communication channel. + type: boolean + updateStrategy: + description: |- + Defines the update strategy for the Component. + + + Deprecated since v0.9. + This field is maintained for backward compatibility and its use is discouraged. + Existing usage should be updated to the current preferred approach to avoid compatibility issues in future releases. + enum: + - Serial + - BestEffortParallel + - Parallel + type: string + userResourceRefs: + description: |- + Allows users to specify custom ConfigMaps and Secrets to be mounted as volumes + in the Cluster's Pods. + This is useful in scenarios where users need to provide additional resources to the Cluster, such as: + + + - Mounting custom scripts or configuration files during Cluster startup. + - Mounting Secrets as volumes to provide sensitive information, like S3 AK/SK, to the Cluster. + properties: + configMapRefs: + description: ConfigMapRefs defines the user-defined ConfigMaps. + items: + description: ConfigMapRef defines a reference to a ConfigMap. + properties: + asVolumeFrom: + description: AsVolumeFrom lists the names of containers + in which the volume should be mounted. + items: + type: string + type: array + x-kubernetes-list-type: set + configMap: + description: ConfigMap specifies the ConfigMap to + be mounted as a volume. + properties: + defaultMode: + description: |- + defaultMode is optional: mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + items: + description: |- + items if unspecified, each key-value pair in the Data field of the referenced + ConfigMap will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the ConfigMap, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within + a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + 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 + optional: + description: optional specify whether the ConfigMap + or its keys must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + mountPoint: + description: MountPoint is the filesystem path where + the volume will be mounted. + maxLength: 256 + pattern: ^/[a-z]([a-z0-9\-]*[a-z0-9])?$ + type: string + name: + description: Name is the name of the referenced ConfigMap + or Secret object. It must conform to DNS label standards. + maxLength: 63 + pattern: ^[a-z0-9]([a-z0-9\.\-]*[a-z0-9])?$ + type: string + subPath: + description: SubPath specifies a path within the volume + from which to mount. + type: string + required: + - configMap + - mountPoint + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + secretRefs: + description: SecretRefs defines the user-defined Secrets. + items: + description: SecretRef defines a reference to a Secret. + properties: + asVolumeFrom: + description: AsVolumeFrom lists the names of containers + in which the volume should be mounted. + items: + type: string + type: array + x-kubernetes-list-type: set + mountPoint: + description: MountPoint is the filesystem path where + the volume will be mounted. + maxLength: 256 + pattern: ^/[a-z]([a-z0-9\-]*[a-z0-9])?$ + type: string + name: + description: Name is the name of the referenced ConfigMap + or Secret object. It must conform to DNS label standards. + maxLength: 63 + pattern: ^[a-z0-9]([a-z0-9\.\-]*[a-z0-9])?$ + type: string + secret: + description: Secret specifies the Secret to be mounted + as a volume. + properties: + defaultMode: + description: |- + defaultMode is Optional: mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values + for mode bits. Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + items: + description: |- + items If unspecified, each key-value pair in the Data field of the referenced + Secret will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the Secret, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within + a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + optional: + description: optional field specify whether the + Secret or its keys must be defined + type: boolean + secretName: + description: |- + secretName is the name of the secret in the pod's namespace to use. + More info: https://kubernetes.io/docs/concepts/storage/volumes#secret + type: string + type: object + subPath: + description: SubPath specifies a path within the volume + from which to mount. + type: string + required: + - mountPoint + - name + - secret + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + volumeClaimTemplates: + description: |- + Specifies a list of PersistentVolumeClaim templates that represent the storage requirements for the Component. + Each template specifies the desired characteristics of a persistent volume, such as storage class, + size, and access modes. + These templates are used to dynamically provision persistent volumes for the Component. + items: + properties: + name: + description: |- + Refers to the name of a volumeMount defined in either: + + + - `componentDefinition.spec.runtime.containers[*].volumeMounts` + - `clusterDefinition.spec.componentDefs[*].podSpec.containers[*].volumeMounts` (deprecated) + + + The value of `name` must match the `name` field of a volumeMount specified in the corresponding `volumeMounts` array. + type: string + spec: + description: |- + Defines the desired characteristics of a PersistentVolumeClaim that will be created for the volume + with the mount name specified in the `name` field. + + + When a Pod is created for this ClusterComponent, a new PVC will be created based on the specification + defined in the `spec` field. The PVC will be associated with the volume mount specified by the `name` field. + properties: + accessModes: + description: |- + Contains the desired access modes the volume should have. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1. + items: + type: string + type: array + x-kubernetes-preserve-unknown-fields: true + resources: + description: |- + Represents the minimum resources the volume should have. + If the RecoverVolumeExpansionFailure feature is enabled, users are allowed to specify resource requirements that + are lower than the previous value but must still be higher than the capacity recorded in the status field of the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources. + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + x-kubernetes-preserve-unknown-fields: true + storageClassName: + description: |- + The name of the StorageClass required by the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1. + type: string + volumeMode: + description: Defines what type of volume is required + by the claim, either Block or Filesystem. + type: string + type: object + required: + - name + type: object + type: array + volumes: + description: List of volumes to override. + items: + description: Volume represents a named volume in a pod that + may be accessed by any container in the pod. + properties: + awsElasticBlockStore: + description: |- + awsElasticBlockStore represents an AWS Disk resource that is attached to a + kubelet's host machine and then exposed to the pod. + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + properties: + fsType: + description: |- + fsType is the filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + partition: + description: |- + partition is the partition in the volume that you want to mount. + If omitted, the default is to mount by volume name. + Examples: For volume /dev/sda1, you specify the partition as "1". + Similarly, the volume partition for /dev/sda is "0" (or you can leave the property empty). + format: int32 + type: integer + readOnly: + description: |- + readOnly value true will force the readOnly setting in VolumeMounts. + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + type: boolean + volumeID: + description: |- + volumeID is unique ID of the persistent disk resource in AWS (Amazon EBS volume). + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + type: string + required: + - volumeID + type: object + azureDisk: + description: azureDisk represents an Azure Data Disk mount + on the host and bind mount to the pod. + properties: + cachingMode: + description: 'cachingMode is the Host Caching mode: + None, Read Only, Read Write.' + type: string + diskName: + description: diskName is the Name of the data disk + in the blob storage + type: string + diskURI: + description: diskURI is the URI of data disk in the + blob storage + type: string + fsType: + description: |- + fsType is Filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + kind: + description: 'kind expected values are Shared: multiple + blob disks per storage account Dedicated: single + blob disk per storage account Managed: azure managed + data disk (only in managed availability set). defaults + to shared' + type: string + readOnly: + description: |- + readOnly Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + description: azureFile represents an Azure File Service + mount on the host and bind mount to the pod. + properties: + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretName: + description: secretName is the name of secret that + contains Azure Storage Account Name and Key + type: string + shareName: + description: shareName is the azure share Name + type: string + required: + - secretName + - shareName + type: object + cephfs: + description: cephFS represents a Ceph FS mount on the + host that shares a pod's lifetime + properties: + monitors: + description: |- + monitors is Required: Monitors is a collection of Ceph monitors + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + items: + type: string + type: array + path: + description: 'path is Optional: Used as the mounted + root, rather than the full Ceph tree, default is + /' + type: string + readOnly: + description: |- + readOnly is Optional: Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + type: boolean + secretFile: + description: |- + secretFile is Optional: SecretFile is the path to key ring for User, default is /etc/ceph/user.secret + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + type: string + secretRef: + description: |- + secretRef is Optional: SecretRef is reference to the authentication secret for User, default is empty. + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + 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 + user: + description: |- + user is optional: User is the rados user name, default is admin + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + type: string + required: + - monitors + type: object + cinder: + description: |- + cinder represents a cinder volume attached and mounted on kubelets host machine. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + type: string + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + type: boolean + secretRef: + description: |- + secretRef is optional: points to a secret object containing parameters used to connect + to OpenStack. + 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 + volumeID: + description: |- + volumeID used to identify the volume in cinder. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + type: string + required: + - volumeID + type: object + configMap: + description: configMap represents a configMap that should + populate this volume + properties: + defaultMode: + description: |- + defaultMode is optional: mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + items: + description: |- + items if unspecified, each key-value pair in the Data field of the referenced + ConfigMap will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the ConfigMap, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within + a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + 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 + optional: + description: optional specify whether the ConfigMap + or its keys must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + csi: + description: csi (Container Storage Interface) represents + ephemeral storage that is handled by certain external + CSI drivers (Beta feature). + properties: + driver: + description: |- + driver is the name of the CSI driver that handles this volume. + Consult with your admin for the correct name as registered in the cluster. + type: string + fsType: + description: |- + fsType to mount. Ex. "ext4", "xfs", "ntfs". + If not provided, the empty value is passed to the associated CSI driver + which will determine the default filesystem to apply. + type: string + nodePublishSecretRef: + description: |- + nodePublishSecretRef is a reference to the secret object containing + sensitive information to pass to the CSI driver to complete the CSI + NodePublishVolume and NodeUnpublishVolume calls. + This field is optional, and may be empty if no secret is required. If the + secret object contains more than one secret, all secret references are passed. + 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 + readOnly: + description: |- + readOnly specifies a read-only configuration for the volume. + Defaults to false (read/write). + type: boolean + volumeAttributes: + additionalProperties: + type: string + description: |- + volumeAttributes stores driver-specific properties that are passed to the CSI + driver. Consult your driver's documentation for supported values. + type: object + required: + - driver + type: object + downwardAPI: + description: downwardAPI represents downward API about + the pod that should populate this volume + properties: + defaultMode: + description: |- + Optional: mode bits to use on created files by default. Must be a + Optional: mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + items: + description: Items is a list of downward API volume + file + items: + description: DownwardAPIVolumeFile represents information + to create the file containing the pod field + properties: + fieldRef: + description: 'Required: Selects a field of the + pod: only annotations, labels, name and namespace + are supported.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select + in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + description: |- + Optional: mode bits used to set permissions on this file, must be an octal value + between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: 'Required: Path is the relative + path name of the file to be created. Must + not be absolute or contain the ''..'' path. + Must be utf-8 encoded. The first item of the + relative path must not start with ''..''' + type: string + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported. + properties: + containerName: + description: 'Container name: required for + volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format + of the exposed resources, defaults to + "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + type: object + emptyDir: + description: |- + emptyDir represents a temporary directory that shares a pod's lifetime. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir + properties: + medium: + description: |- + medium represents what type of storage medium should back this directory. + The default is "" which means to use the node's default medium. + Must be an empty string (default) or Memory. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + description: |- + sizeLimit is the total amount of local storage required for this EmptyDir volume. + The size limit is also applicable for memory medium. + The maximum usage on memory medium EmptyDir would be the minimum value between + the SizeLimit specified here and the sum of memory limits of all containers in a pod. + The default is nil which means that the limit is undefined. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + description: |- + ephemeral represents a volume that is handled by a cluster storage driver. + The volume's lifecycle is tied to the pod that defines it - it will be created before the pod starts, + and deleted when the pod is removed. + + + Use this if: + a) the volume is only needed while the pod runs, + b) features of normal volumes like restoring from snapshot or capacity + tracking are needed, + c) the storage driver is specified through a storage class, and + d) the storage driver supports dynamic volume provisioning through + a PersistentVolumeClaim (see EphemeralVolumeSource for more + information on the connection between this volume type + and PersistentVolumeClaim). + + + Use PersistentVolumeClaim or one of the vendor-specific + APIs for volumes that persist for longer than the lifecycle + of an individual pod. + + + Use CSI for light-weight local ephemeral volumes if the CSI driver is meant to + be used that way - see the documentation of the driver for + more information. + + + A pod can use both types of ephemeral volumes and + persistent volumes at the same time. + properties: + volumeClaimTemplate: + description: |- + Will be used to create a stand-alone PVC to provision the volume. + The pod in which this EphemeralVolumeSource is embedded will be the + owner of the PVC, i.e. the PVC will be deleted together with the + pod. The name of the PVC will be `-` where + `` is the name from the `PodSpec.Volumes` array + entry. Pod validation will reject the pod if the concatenated name + is not valid for a PVC (for example, too long). + + + An existing PVC with that name that is not owned by the pod + will *not* be used for the pod to avoid using an unrelated + volume by mistake. Starting the pod is then blocked until + the unrelated PVC is removed. If such a pre-created PVC is + meant to be used by the pod, the PVC has to updated with an + owner reference to the pod once the pod exists. Normally + this should not be necessary, but it may be useful when + manually reconstructing a broken cluster. + + + This field is read-only and no changes will be made by Kubernetes + to the PVC after it has been created. + + + Required, must not be nil. + properties: + metadata: + description: |- + May contain labels and annotations that will be copied into the PVC + when creating it. No other fields are allowed and will be rejected during + validation. + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + description: |- + The specification for the PersistentVolumeClaim. The entire content is + copied unchanged into the PVC that gets created from this + template. The same fields as in a PersistentVolumeClaim + are also valid here. + properties: + accessModes: + description: |- + accessModes contains the desired access modes the volume should have. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1 + items: + type: string + type: array + dataSource: + description: |- + dataSource field can be used to specify either: + * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) + * An existing PVC (PersistentVolumeClaim) + If the provisioner or an external controller can support the specified data source, + it will create a new volume based on the contents of the specified data source. + When the AnyVolumeDataSource feature gate is enabled, dataSource contents will be copied to dataSourceRef, + and dataSourceRef contents will be copied to dataSource when dataSourceRef.namespace is not specified. + If the namespace is specified, then dataSourceRef will not be copied to dataSource. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource + being referenced + type: string + name: + description: Name is the name of resource + being referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + description: |- + dataSourceRef specifies the object from which to populate the volume with data, if a non-empty + volume is desired. This may be any object from a non-empty API group (non + core object) or a PersistentVolumeClaim object. + When this field is specified, volume binding will only succeed if the type of + the specified object matches some installed volume populator or dynamic + provisioner. + This field will replace the functionality of the dataSource field and as such + if both fields are non-empty, they must have the same value. For backwards + compatibility, when namespace isn't specified in dataSourceRef, + both fields (dataSource and dataSourceRef) will be set to the same + value automatically if one of them is empty and the other is non-empty. + When namespace is specified in dataSourceRef, + dataSource isn't set to the same value and must be empty. + There are three important differences between dataSource and dataSourceRef: + * While dataSource only allows two specific types of objects, dataSourceRef + allows any non-core object, as well as PersistentVolumeClaim objects. + * While dataSource ignores disallowed values (dropping them), dataSourceRef + preserves all values, and generates an error if a disallowed value is + specified. + * While dataSource only allows local objects, dataSourceRef allows objects + in any namespaces. + (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled. + (Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource + being referenced + type: string + name: + description: Name is the name of resource + being referenced + type: string + namespace: + description: |- + Namespace is the namespace of resource being referenced + Note that when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details. + (Alpha) This field requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + type: string + required: + - kind + - name + type: object + resources: + description: |- + resources represents the minimum resources the volume should have. + If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements + that are lower than previous value but must still be higher than capacity recorded in the + status field of the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + selector: + description: selector is a label query over + volumes to consider for binding. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + description: |- + storageClassName is the name of the StorageClass required by the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1 + type: string + volumeAttributesClassName: + description: |- + volumeAttributesClassName may be used to set the VolumeAttributesClass used by this claim. + If specified, the CSI driver will create or update the volume with the attributes defined + in the corresponding VolumeAttributesClass. This has a different purpose than storageClassName, + it can be changed after the claim is created. An empty string value means that no VolumeAttributesClass + will be applied to the claim but it's not allowed to reset this field to empty string once it is set. + If unspecified and the PersistentVolumeClaim is unbound, the default VolumeAttributesClass + will be set by the persistentvolume controller if it exists. + If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be + set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource + exists. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#volumeattributesclass + (Alpha) Using this field requires the VolumeAttributesClass feature gate to be enabled. + type: string + volumeMode: + description: |- + volumeMode defines what type of volume is required by the claim. + Value of Filesystem is implied when not included in claim spec. + type: string + volumeName: + description: volumeName is the binding reference + to the PersistentVolume backing this claim. + type: string + type: object + required: + - spec + type: object + type: object + fc: + description: fc represents a Fibre Channel resource that + is attached to a kubelet's host machine and then exposed + to the pod. + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + lun: + description: 'lun is Optional: FC target lun number' + format: int32 + type: integer + readOnly: + description: |- + readOnly is Optional: Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + targetWWNs: + description: 'targetWWNs is Optional: FC target worldwide + names (WWNs)' + items: + type: string + type: array + wwids: + description: |- + wwids Optional: FC volume world wide identifiers (wwids) + Either wwids or combination of targetWWNs and lun must be set, but not both simultaneously. + items: + type: string + type: array + type: object + flexVolume: + description: |- + flexVolume represents a generic volume resource that is + provisioned/attached using an exec based plugin. + properties: + driver: + description: driver is the name of the driver to use + for this volume. + type: string + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". The default filesystem depends on FlexVolume script. + type: string + options: + additionalProperties: + type: string + description: 'options is Optional: this field holds + extra command options if any.' + type: object + readOnly: + description: |- + readOnly is Optional: defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: |- + secretRef is Optional: secretRef is reference to the secret object containing + sensitive information to pass to the plugin scripts. This may be + empty if no secret object is specified. If the secret object + contains more than one secret, all secrets are passed to the plugin + scripts. + 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 + required: + - driver + type: object + flocker: + description: flocker represents a Flocker volume attached + to a kubelet's host machine. This depends on the Flocker + control service being running + properties: + datasetName: + description: |- + datasetName is Name of the dataset stored as metadata -> name on the dataset for Flocker + should be considered as deprecated + type: string + datasetUUID: + description: datasetUUID is the UUID of the dataset. + This is unique identifier of a Flocker dataset + type: string + type: object + gcePersistentDisk: + description: |- + gcePersistentDisk represents a GCE Disk resource that is attached to a + kubelet's host machine and then exposed to the pod. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + properties: + fsType: + description: |- + fsType is filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + partition: + description: |- + partition is the partition in the volume that you want to mount. + If omitted, the default is to mount by volume name. + Examples: For volume /dev/sda1, you specify the partition as "1". + Similarly, the volume partition for /dev/sda is "0" (or you can leave the property empty). + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + format: int32 + type: integer + pdName: + description: |- + pdName is unique name of the PD resource in GCE. Used to identify the disk in GCE. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + type: string + readOnly: + description: |- + readOnly here will force the ReadOnly setting in VolumeMounts. + Defaults to false. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + type: boolean + required: + - pdName + type: object + gitRepo: + description: |- + gitRepo represents a git repository at a particular revision. + DEPRECATED: GitRepo is deprecated. To provision a container with a git repo, mount an + EmptyDir into an InitContainer that clones the repo using git, then mount the EmptyDir + into the Pod's container. + properties: + directory: + description: |- + directory is the target directory name. + Must not contain or start with '..'. If '.' is supplied, the volume directory will be the + git repository. Otherwise, if specified, the volume will contain the git repository in + the subdirectory with the given name. + type: string + repository: + description: repository is the URL + type: string + revision: + description: revision is the commit hash for the specified + revision. + type: string + required: + - repository + type: object + glusterfs: + description: |- + glusterfs represents a Glusterfs mount on the host that shares a pod's lifetime. + More info: https://examples.k8s.io/volumes/glusterfs/README.md + properties: + endpoints: + description: |- + endpoints is the endpoint name that details Glusterfs topology. + More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod + type: string + path: + description: |- + path is the Glusterfs volume path. + More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod + type: string + readOnly: + description: |- + readOnly here will force the Glusterfs volume to be mounted with read-only permissions. + Defaults to false. + More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod + type: boolean + required: + - endpoints + - path + type: object + hostPath: + description: |- + hostPath represents a pre-existing file or directory on the host + machine that is directly exposed to the container. This is generally + used for system agents or other privileged things that are allowed + to see the host machine. Most containers will NOT need this. + More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + --- + TODO(jonesdl) We need to restrict who can use host directory mounts and who can/can not + mount host directories as read/write. + properties: + path: + description: |- + path of the directory on the host. + If the path is a symlink, it will follow the link to the real path. + More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + type: string + type: + description: |- + type for HostPath Volume + Defaults to "" + More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + type: string + required: + - path + type: object + iscsi: + description: |- + iscsi represents an ISCSI Disk resource that is attached to a + kubelet's host machine and then exposed to the pod. + More info: https://examples.k8s.io/volumes/iscsi/README.md + properties: + chapAuthDiscovery: + description: chapAuthDiscovery defines whether support + iSCSI Discovery CHAP authentication + type: boolean + chapAuthSession: + description: chapAuthSession defines whether support + iSCSI Session CHAP authentication + type: boolean + fsType: + description: |- + fsType is the filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#iscsi + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + initiatorName: + description: |- + initiatorName is the custom iSCSI Initiator Name. + If initiatorName is specified with iscsiInterface simultaneously, new iSCSI interface + : will be created for the connection. + type: string + iqn: + description: iqn is the target iSCSI Qualified Name. + type: string + iscsiInterface: + description: |- + iscsiInterface is the interface Name that uses an iSCSI transport. + Defaults to 'default' (tcp). + type: string + lun: + description: lun represents iSCSI Target Lun number. + format: int32 + type: integer + portals: + description: |- + portals is the iSCSI Target Portal List. The portal is either an IP or ip_addr:port if the port + is other than default (typically TCP ports 860 and 3260). + items: + type: string + type: array + readOnly: + description: |- + readOnly here will force the ReadOnly setting in VolumeMounts. + Defaults to false. + type: boolean + secretRef: + description: secretRef is the CHAP Secret for iSCSI + target and initiator authentication + 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 + targetPortal: + description: |- + targetPortal is iSCSI Target Portal. The Portal is either an IP or ip_addr:port if the port + is other than default (typically TCP ports 860 and 3260). + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + description: |- + name of the volume. + Must be a DNS_LABEL and unique within the pod. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + nfs: + description: |- + nfs represents an NFS mount on the host that shares a pod's lifetime + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + properties: + path: + description: |- + path that is exported by the NFS server. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + type: string + readOnly: + description: |- + readOnly here will force the NFS export to be mounted with read-only permissions. + Defaults to false. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + type: boolean + server: + description: |- + server is the hostname or IP address of the NFS server. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + description: |- + persistentVolumeClaimVolumeSource represents a reference to a + PersistentVolumeClaim in the same namespace. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims + properties: + claimName: + description: |- + claimName is the name of a PersistentVolumeClaim in the same namespace as the pod using this volume. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims + type: string + readOnly: + description: |- + readOnly Will force the ReadOnly setting in VolumeMounts. + Default false. + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + description: photonPersistentDisk represents a PhotonController + persistent disk attached and mounted on kubelets host + machine + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + pdID: + description: pdID is the ID that identifies Photon + Controller persistent disk + type: string + required: + - pdID + type: object + portworxVolume: + description: portworxVolume represents a portworx volume + attached and mounted on kubelets host machine + properties: + fsType: + description: |- + fSType represents the filesystem type to mount + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs". Implicitly inferred to be "ext4" if unspecified. + type: string + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + volumeID: + description: volumeID uniquely identifies a Portworx + volume + type: string + required: + - volumeID + type: object + projected: + description: projected items for all in one resources + secrets, configmaps, and downward API + properties: + defaultMode: + description: |- + defaultMode are the mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + sources: + description: sources is the list of volume projections + items: + description: Projection that may be projected along + with other supported volume types + properties: + clusterTrustBundle: + description: |- + ClusterTrustBundle allows a pod to access the `.spec.trustBundle` field + of ClusterTrustBundle objects in an auto-updating file. + + + Alpha, gated by the ClusterTrustBundleProjection feature gate. + + + ClusterTrustBundle objects can either be selected by name, or by the + combination of signer name and a label selector. + + + Kubelet performs aggressive normalization of the PEM contents written + into the pod filesystem. Esoteric PEM features such as inter-block + comments and block headers are stripped. Certificates are deduplicated. + The ordering of certificates within the file is arbitrary, and Kubelet + may change the order over time. + properties: + labelSelector: + description: |- + Select all ClusterTrustBundles that match this label selector. Only has + effect if signerName is set. Mutually-exclusive with name. If unset, + interpreted as "match nothing". If set but empty, interpreted as "match + everything". + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + name: + description: |- + Select a single ClusterTrustBundle by object name. Mutually-exclusive + with signerName and labelSelector. + type: string + optional: + description: |- + If true, don't block pod startup if the referenced ClusterTrustBundle(s) + aren't available. If using name, then the named ClusterTrustBundle is + allowed not to exist. If using signerName, then the combination of + signerName and labelSelector is allowed to match zero + ClusterTrustBundles. + type: boolean + path: + description: Relative path from the volume + root to write the bundle. + type: string + signerName: + description: |- + Select all ClusterTrustBundles that match this signer name. + Mutually-exclusive with name. The contents of all selected + ClusterTrustBundles will be unified and deduplicated. + type: string + required: + - path + type: object + configMap: + description: configMap information about the + configMap data to project + properties: + items: + description: |- + items if unspecified, each key-value pair in the Data field of the referenced + ConfigMap will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the ConfigMap, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path + within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + 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 + optional: + description: optional specify whether the + ConfigMap or its keys must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + downwardAPI: + description: downwardAPI information about the + downwardAPI data to project + properties: + items: + description: Items is a list of DownwardAPIVolume + file + items: + description: DownwardAPIVolumeFile represents + information to create the file containing + the pod field + properties: + fieldRef: + description: 'Required: Selects a + field of the pod: only annotations, + labels, name and namespace are supported.' + properties: + apiVersion: + description: Version of the schema + the FieldPath is written in + terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field + to select in the specified API + version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + description: |- + Optional: mode bits used to set permissions on this file, must be an octal value + between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: 'Required: Path is the + relative path name of the file to + be created. Must not be absolute + or contain the ''..'' path. Must + be utf-8 encoded. The first item + of the relative path must not start + with ''..''' + type: string + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported. + properties: + containerName: + description: 'Container name: + required for volumes, optional + for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output + format of the exposed resources, + defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource + to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + type: object + secret: + description: secret information about the secret + data to project + properties: + items: + description: |- + items if unspecified, each key-value pair in the Data field of the referenced + Secret will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the Secret, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path + within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + 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 + optional: + description: optional field specify whether + the Secret or its key must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + serviceAccountToken: + description: serviceAccountToken is information + about the serviceAccountToken data to project + properties: + audience: + description: |- + audience is the intended audience of the token. A recipient of a token + must identify itself with an identifier specified in the audience of the + token, and otherwise should reject the token. The audience defaults to the + identifier of the apiserver. + type: string + expirationSeconds: + description: |- + expirationSeconds is the requested duration of validity of the service + account token. As the token approaches expiration, the kubelet volume + plugin will proactively rotate the service account token. The kubelet will + start trying to rotate the token if the token is older than 80 percent of + its time to live or if the token is older than 24 hours.Defaults to 1 hour + and must be at least 10 minutes. + format: int64 + type: integer + path: + description: |- + path is the path relative to the mount point of the file to project the + token into. + type: string + required: + - path + type: object + type: object + type: array + type: object + quobyte: + description: quobyte represents a Quobyte mount on the + host that shares a pod's lifetime + properties: + group: + description: |- + group to map volume access to + Default is no group + type: string + readOnly: + description: |- + readOnly here will force the Quobyte volume to be mounted with read-only permissions. + Defaults to false. + type: boolean + registry: + description: |- + registry represents a single or multiple Quobyte Registry services + specified as a string as host:port pair (multiple entries are separated with commas) + which acts as the central registry for volumes + type: string + tenant: + description: |- + tenant owning the given Quobyte volume in the Backend + Used with dynamically provisioned Quobyte volumes, value is set by the plugin + type: string + user: + description: |- + user to map volume access to + Defaults to serivceaccount user + type: string + volume: + description: volume is a string that references an + already created Quobyte volume by name. + type: string + required: + - registry + - volume + type: object + rbd: + description: |- + rbd represents a Rados Block Device mount on the host that shares a pod's lifetime. + More info: https://examples.k8s.io/volumes/rbd/README.md + properties: + fsType: + description: |- + fsType is the filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#rbd + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + image: + description: |- + image is the rados image name. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + keyring: + description: |- + keyring is the path to key ring for RBDUser. + Default is /etc/ceph/keyring. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + monitors: + description: |- + monitors is a collection of Ceph monitors. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + items: + type: string + type: array + pool: + description: |- + pool is the rados pool name. + Default is rbd. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + readOnly: + description: |- + readOnly here will force the ReadOnly setting in VolumeMounts. + Defaults to false. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: boolean + secretRef: + description: |- + secretRef is name of the authentication secret for RBDUser. If provided + overrides keyring. + Default is nil. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + 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 + user: + description: |- + user is the rados user name. + Default is admin. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + required: + - image + - monitors + type: object + scaleIO: + description: scaleIO represents a ScaleIO persistent volume + attached and mounted on Kubernetes nodes. + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". + Default is "xfs". + type: string + gateway: + description: gateway is the host address of the ScaleIO + API Gateway. + type: string + protectionDomain: + description: protectionDomain is the name of the ScaleIO + Protection Domain for the configured storage. + type: string + readOnly: + description: |- + readOnly Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: |- + secretRef references to the secret for ScaleIO user and other + sensitive information. If this is not provided, Login operation will fail. + 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 + sslEnabled: + description: sslEnabled Flag enable/disable SSL communication + with Gateway, default false + type: boolean + storageMode: + description: |- + storageMode indicates whether the storage for a volume should be ThickProvisioned or ThinProvisioned. + Default is ThinProvisioned. + type: string + storagePool: + description: storagePool is the ScaleIO Storage Pool + associated with the protection domain. + type: string + system: + description: system is the name of the storage system + as configured in ScaleIO. + type: string + volumeName: + description: |- + volumeName is the name of a volume already created in the ScaleIO system + that is associated with this volume source. + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + description: |- + secret represents a secret that should populate this volume. + More info: https://kubernetes.io/docs/concepts/storage/volumes#secret + properties: + defaultMode: + description: |- + defaultMode is Optional: mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values + for mode bits. Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + items: + description: |- + items If unspecified, each key-value pair in the Data field of the referenced + Secret will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the Secret, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within + a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + optional: + description: optional field specify whether the Secret + or its keys must be defined + type: boolean + secretName: + description: |- + secretName is the name of the secret in the pod's namespace to use. + More info: https://kubernetes.io/docs/concepts/storage/volumes#secret + type: string + type: object + storageos: + description: storageOS represents a StorageOS volume attached + and mounted on Kubernetes nodes. + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: |- + secretRef specifies the secret to use for obtaining the StorageOS API + credentials. If not specified, default values will be attempted. + 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 + volumeName: + description: |- + volumeName is the human-readable name of the StorageOS volume. Volume + names are only unique within a namespace. + type: string + volumeNamespace: + description: |- + volumeNamespace specifies the scope of the volume within StorageOS. If no + namespace is specified then the Pod's namespace will be used. This allows the + Kubernetes name scoping to be mirrored within StorageOS for tighter integration. + Set VolumeName to any name to override the default behaviour. + Set to "default" if you are not using namespaces within StorageOS. + Namespaces that do not pre-exist within StorageOS will be created. + type: string + type: object + vsphereVolume: + description: vsphereVolume represents a vSphere volume + attached and mounted on kubelets host machine + properties: + fsType: + description: |- + fsType is filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + storagePolicyID: + description: storagePolicyID is the storage Policy + Based Management (SPBM) profile ID associated with + the StoragePolicyName. + type: string + storagePolicyName: + description: storagePolicyName is the storage Policy + Based Management (SPBM) profile name. + type: string + volumePath: + description: volumePath is the path that identifies + vSphere volume vmdk + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + required: + - replicas + type: object + maxItems: 128 + minItems: 1 + type: array + x-kubernetes-validations: + - message: duplicated component + rule: self.all(x, size(self.filter(c, c.name == x.name)) == 1) + - message: two kinds of definition API can not be used simultaneously + rule: self.all(x, size(self.filter(c, has(c.componentDef))) == 0) + || self.all(x, size(self.filter(c, has(c.componentDef))) == size(self)) + runtimeClassName: + description: Specifies runtimeClassName for all Pods managed by this + Cluster. + type: string + schedulingPolicy: + description: Specifies the scheduling policy for the Cluster. + properties: + affinity: + description: Specifies a group of affinity scheduling rules of + the Cluster, including NodeAffinity, PodAffinity, and PodAntiAffinity. + properties: + nodeAffinity: + description: Describes node affinity scheduling rules for + the pod. + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node matches the corresponding matchExpressions; the + node(s) with the highest sum are the most preferred. + items: + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). + properties: + preference: + description: A node selector term, associated with + the corresponding weight. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + weight: + description: Weight associated with matching the + corresponding nodeSelectorTerm, in the range 1-100. + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. + properties: + nodeSelectorTerms: + description: Required. A list of node selector terms. + The terms are ORed. + items: + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + type: array + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + description: Describes pod affinity scheduling rules (e.g. + co-locate this pod in the same node, zone, etc. as some + other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred + node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated + with the corresponding weight. + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. + Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: |- + weight associated with matching the corresponding podAffinityTerm, + in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. + items: + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. + Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + description: Describes pod anti-affinity scheduling rules + (e.g. avoid putting this pod in the same node, zone, etc. + as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the anti-affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred + node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated + with the corresponding weight. + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. + Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: |- + weight associated with matching the corresponding podAffinityTerm, + in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the anti-affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the anti-affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. + items: + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. + Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + nodeName: + description: |- + NodeName is a request to schedule this Pod onto a specific node. If it is non-empty, + the scheduler simply schedules this Pod onto that node, assuming that it fits resource + requirements. + type: string + nodeSelector: + additionalProperties: + type: string + description: |- + NodeSelector is a selector which must be true for the Pod to fit on a node. + Selector which must match a node's labels for the Pod to be scheduled on that node. + More info: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ + type: object + x-kubernetes-map-type: atomic + schedulerName: + description: |- + If specified, the Pod will be dispatched by specified scheduler. + If not specified, the Pod will be dispatched by default scheduler. + type: string + tolerations: + description: |- + Allows Pods to be scheduled onto nodes with matching taints. + Each toleration in the array allows the Pod to tolerate node taints based on + specified `key`, `value`, `effect`, and `operator`. + + + - The `key`, `value`, and `effect` identify the taint that the toleration matches. + - The `operator` determines how the toleration matches the taint. + + + Pods with matching tolerations are allowed to be scheduled on tainted nodes, typically reserved for specific purposes. + items: + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . + properties: + effect: + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. + type: string + operator: + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. + type: string + tolerationSeconds: + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. + format: int64 + type: integer + value: + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. + type: string + type: object + type: array + topologySpreadConstraints: + description: |- + TopologySpreadConstraints describes how a group of Pods ought to spread across topology + domains. Scheduler will schedule Pods in a way which abides by the constraints. + All topologySpreadConstraints are ANDed. + items: + description: TopologySpreadConstraint specifies how to spread + matching pods among the given topology. + properties: + labelSelector: + description: |- + LabelSelector is used to find matching pods. + Pods that match this label selector are counted to determine the number of pods + in their corresponding topology domain. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select the pods over which + spreading will be calculated. The keys are used to lookup values from the + incoming pod labels, those key-value labels are ANDed with labelSelector + to select the group of existing pods over which spreading will be calculated + for the incoming pod. The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + MatchLabelKeys cannot be set when LabelSelector isn't set. + Keys that don't exist in the incoming pod labels will + be ignored. A null or empty list means only match against labelSelector. + + + This is a beta field and requires the MatchLabelKeysInPodTopologySpread feature gate to be enabled (enabled by default). + items: + type: string + type: array + x-kubernetes-list-type: atomic + maxSkew: + description: |- + MaxSkew describes the degree to which pods may be unevenly distributed. + When `whenUnsatisfiable=DoNotSchedule`, it is the maximum permitted difference + between the number of matching pods in the target topology and the global minimum. + The global minimum is the minimum number of matching pods in an eligible domain + or zero if the number of eligible domains is less than MinDomains. + For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same + labelSelector spread as 2/2/1: + In this case, the global minimum is 1. + | zone1 | zone2 | zone3 | + | P P | P P | P | + - if MaxSkew is 1, incoming pod can only be scheduled to zone3 to become 2/2/2; + scheduling it onto zone1(zone2) would make the ActualSkew(3-1) on zone1(zone2) + violate MaxSkew(1). + - if MaxSkew is 2, incoming pod can be scheduled onto any zone. + When `whenUnsatisfiable=ScheduleAnyway`, it is used to give higher precedence + to topologies that satisfy it. + It's a required field. Default value is 1 and 0 is not allowed. + format: int32 + type: integer + minDomains: + description: |- + MinDomains indicates a minimum number of eligible domains. + When the number of eligible domains with matching topology keys is less than minDomains, + Pod Topology Spread treats "global minimum" as 0, and then the calculation of Skew is performed. + And when the number of eligible domains with matching topology keys equals or greater than minDomains, + this value has no effect on scheduling. + As a result, when the number of eligible domains is less than minDomains, + scheduler won't schedule more than maxSkew Pods to those domains. + If value is nil, the constraint behaves as if MinDomains is equal to 1. + Valid values are integers greater than 0. + When value is not nil, WhenUnsatisfiable must be DoNotSchedule. + + + For example, in a 3-zone cluster, MaxSkew is set to 2, MinDomains is set to 5 and pods with the same + labelSelector spread as 2/2/2: + | zone1 | zone2 | zone3 | + | P P | P P | P P | + The number of domains is less than 5(MinDomains), so "global minimum" is treated as 0. + In this situation, new pod with the same labelSelector cannot be scheduled, + because computed skew will be 3(3 - 0) if new Pod is scheduled to any of the three zones, + it will violate MaxSkew. + + + This is a beta field and requires the MinDomainsInPodTopologySpread feature gate to be enabled (enabled by default). + format: int32 + type: integer + nodeAffinityPolicy: + description: |- + NodeAffinityPolicy indicates how we will treat Pod's nodeAffinity/nodeSelector + when calculating pod topology spread skew. Options are: + - Honor: only nodes matching nodeAffinity/nodeSelector are included in the calculations. + - Ignore: nodeAffinity/nodeSelector are ignored. All nodes are included in the calculations. + + + If this value is nil, the behavior is equivalent to the Honor policy. + This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag. + type: string + nodeTaintsPolicy: + description: |- + NodeTaintsPolicy indicates how we will treat node taints when calculating + pod topology spread skew. Options are: + - Honor: nodes without taints, along with tainted nodes for which the incoming pod + has a toleration, are included. + - Ignore: node taints are ignored. All nodes are included. + + + If this value is nil, the behavior is equivalent to the Ignore policy. + This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag. + type: string + topologyKey: + description: |- + TopologyKey is the key of node labels. Nodes that have a label with this key + and identical values are considered to be in the same topology. + We consider each as a "bucket", and try to put balanced number + of pods into each bucket. + We define a domain as a particular instance of a topology. + Also, we define an eligible domain as a domain whose nodes meet the requirements of + nodeAffinityPolicy and nodeTaintsPolicy. + e.g. If TopologyKey is "kubernetes.io/hostname", each Node is a domain of that topology. + And, if TopologyKey is "topology.kubernetes.io/zone", each zone is a domain of that topology. + It's a required field. + type: string + whenUnsatisfiable: + description: |- + WhenUnsatisfiable indicates how to deal with a pod if it doesn't satisfy + the spread constraint. + - DoNotSchedule (default) tells the scheduler not to schedule it. + - ScheduleAnyway tells the scheduler to schedule the pod in any location, + but giving higher precedence to topologies that would help reduce the + skew. + A constraint is considered "Unsatisfiable" for an incoming pod + if and only if every possible node assignment for that pod would violate + "MaxSkew" on some topology. + For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same + labelSelector spread as 3/1/1: + | zone1 | zone2 | zone3 | + | P P P | P | P | + If WhenUnsatisfiable is set to DoNotSchedule, incoming pod can only be scheduled + to zone2(zone3) to become 3/2/1(3/1/2) as ActualSkew(2-1) on zone2(zone3) satisfies + MaxSkew(1). In other words, the cluster can still be imbalanced, but scheduler + won't make it *more* imbalanced. + It's a required field. + type: string + required: + - maxSkew + - topologyKey + - whenUnsatisfiable + type: object + type: array + type: object + services: + description: |- + Defines a list of additional Services that are exposed by a Cluster. + This field allows Services of selected Components, either from `componentSpecs` or `shardingSpecs` to be exposed, + alongside Services defined with ComponentService. + + + Services defined here can be referenced by other clusters using the ServiceRefClusterSelector. + items: + description: |- + ClusterService defines a service that is exposed externally, allowing entities outside the cluster to access it. + For example, external applications, or other Clusters. + And another Cluster managed by the same KubeBlocks operator can resolve the address exposed by a ClusterService + using the `serviceRef` field. + + + When a Component needs to access another Cluster's ClusterService using the `serviceRef` field, + it must also define the service type and version information in the `componentDefinition.spec.serviceRefDeclarations` + section. + properties: + annotations: + additionalProperties: + type: string + description: |- + If ServiceType is LoadBalancer, cloud provider related parameters can be put here + More info: https://kubernetes.io/docs/concepts/services-networking/service/#loadbalancer. + type: object + componentSelector: + description: |- + Extends the ServiceSpec.Selector by allowing the specification of a component, to be used as a selector for the service. + Note that this and the `shardingSelector` are mutually exclusive and cannot be set simultaneously. + type: string + name: + description: |- + Name defines the name of the service. + otherwise, it indicates the name of the service. + Others can refer to this service by its name. (e.g., connection credential) + Cannot be updated. + maxLength: 25 + type: string + roleSelector: + description: "Extends the above `serviceSpec.selector` by allowing + you to specify defined role as selector for the service.\nWhen + `roleSelector` is set, it adds a label selector \"kubeblocks.io/role: + {roleSelector}\"\nto the `serviceSpec.selector`.\nExample + usage:\n\n\n\t roleSelector: \"leader\"\n\n\nIn this example, + setting `roleSelector` to \"leader\" will add a label selector\n\"kubeblocks.io/role: + leader\" to the `serviceSpec.selector`.\nThis means that the + service will select and route traffic to Pods with the label\n\"kubeblocks.io/role\" + set to \"leader\".\n\n\nNote that if `podService` sets to + true, RoleSelector will be ignored.\nThe `podService` flag + takes precedence over `roleSelector` and generates a service + for each Pod." + type: string + serviceName: + description: |- + ServiceName defines the name of the underlying service object. + If not specified, the default service name with different patterns will be used: + + + - CLUSTER_NAME: for cluster-level services + - CLUSTER_NAME-COMPONENT_NAME: for component-level services + + + Only one default service name is allowed. + Cannot be updated. + maxLength: 25 + pattern: ^[a-z]([a-z0-9\-]*[a-z0-9])?$ + type: string + shardingSelector: + description: |- + Extends the ServiceSpec.Selector by allowing the specification of a sharding name, which is defined in + `cluster.spec.shardingSpecs[*].name`, to be used as a selector for the service. + Note that this and the `componentSelector` are mutually exclusive and cannot be set simultaneously. + type: string + spec: + description: |- + Spec defines the behavior of a service. + https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status + properties: + allocateLoadBalancerNodePorts: + description: |- + allocateLoadBalancerNodePorts defines if NodePorts will be automatically + allocated for services with type LoadBalancer. Default is "true". It + may be set to "false" if the cluster load-balancer does not rely on + NodePorts. If the caller requests specific NodePorts (by specifying a + value), those requests will be respected, regardless of this field. + This field may only be set for services with type LoadBalancer and will + be cleared if the type is changed to any other type. + type: boolean + clusterIP: + description: |- + clusterIP is the IP address of the service and is usually assigned + randomly. If an address is specified manually, is in-range (as per + system configuration), and is not in use, it will be allocated to the + service; otherwise creation of the service will fail. This field may not + be changed through updates unless the type field is also being changed + to ExternalName (which requires this field to be blank) or the type + field is being changed from ExternalName (in which case this field may + optionally be specified, as describe above). Valid values are "None", + empty string (""), or a valid IP address. Setting this to "None" makes a + "headless service" (no virtual IP), which is useful when direct endpoint + connections are preferred and proxying is not required. Only applies to + types ClusterIP, NodePort, and LoadBalancer. If this field is specified + when creating a Service of type ExternalName, creation will fail. This + field will be wiped when updating a Service to type ExternalName. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + type: string + clusterIPs: + description: |- + ClusterIPs is a list of IP addresses assigned to this service, and are + usually assigned randomly. If an address is specified manually, is + in-range (as per system configuration), and is not in use, it will be + allocated to the service; otherwise creation of the service will fail. + This field may not be changed through updates unless the type field is + also being changed to ExternalName (which requires this field to be + empty) or the type field is being changed from ExternalName (in which + case this field may optionally be specified, as describe above). Valid + values are "None", empty string (""), or a valid IP address. Setting + this to "None" makes a "headless service" (no virtual IP), which is + useful when direct endpoint connections are preferred and proxying is + not required. Only applies to types ClusterIP, NodePort, and + LoadBalancer. If this field is specified when creating a Service of type + ExternalName, creation will fail. This field will be wiped when updating + a Service to type ExternalName. If this field is not specified, it will + be initialized from the clusterIP field. If this field is specified, + clients must ensure that clusterIPs[0] and clusterIP have the same + value. + + + This field may hold a maximum of two entries (dual-stack IPs, in either order). + These IPs must correspond to the values of the ipFamilies field. Both + clusterIPs and ipFamilies are governed by the ipFamilyPolicy field. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalIPs: + description: |- + externalIPs is a list of IP addresses for which nodes in the cluster + will also accept traffic for this service. These IPs are not managed by + Kubernetes. The user is responsible for ensuring that traffic arrives + at a node with this IP. A common example is external load-balancers + that are not part of the Kubernetes system. + items: + type: string + type: array + externalName: + description: |- + externalName is the external reference that discovery mechanisms will + return as an alias for this service (e.g. a DNS CNAME record). No + proxying will be involved. Must be a lowercase RFC-1123 hostname + (https://tools.ietf.org/html/rfc1123) and requires `type` to be "ExternalName". + type: string + externalTrafficPolicy: + description: |- + externalTrafficPolicy describes how nodes distribute service traffic they + receive on one of the Service's "externally-facing" addresses (NodePorts, + ExternalIPs, and LoadBalancer IPs). If set to "Local", the proxy will configure + the service in a way that assumes that external load balancers will take care + of balancing the service traffic between nodes, and so each node will deliver + traffic only to the node-local endpoints of the service, without masquerading + the client source IP. (Traffic mistakenly sent to a node with no endpoints will + be dropped.) The default value, "Cluster", uses the standard behavior of + routing to all endpoints evenly (possibly modified by topology and other + features). Note that traffic sent to an External IP or LoadBalancer IP from + within the cluster will always get "Cluster" semantics, but clients sending to + a NodePort from within the cluster may need to take traffic policy into account + when picking a node. + type: string + healthCheckNodePort: + description: |- + healthCheckNodePort specifies the healthcheck nodePort for the service. + This only applies when type is set to LoadBalancer and + externalTrafficPolicy is set to Local. If a value is specified, is + in-range, and is not in use, it will be used. If not specified, a value + will be automatically allocated. External systems (e.g. load-balancers) + can use this port to determine if a given node holds endpoints for this + service or not. If this field is specified when creating a Service + which does not need it, creation will fail. This field will be wiped + when updating a Service to no longer need it (e.g. changing type). + This field cannot be updated once set. + format: int32 + type: integer + internalTrafficPolicy: + description: |- + InternalTrafficPolicy describes how nodes distribute service traffic they + receive on the ClusterIP. If set to "Local", the proxy will assume that pods + only want to talk to endpoints of the service on the same node as the pod, + dropping the traffic if there are no local endpoints. The default value, + "Cluster", uses the standard behavior of routing to all endpoints evenly + (possibly modified by topology and other features). + type: string + ipFamilies: + description: |- + IPFamilies is a list of IP families (e.g. IPv4, IPv6) assigned to this + service. This field is usually assigned automatically based on cluster + configuration and the ipFamilyPolicy field. If this field is specified + manually, the requested family is available in the cluster, + and ipFamilyPolicy allows it, it will be used; otherwise creation of + the service will fail. This field is conditionally mutable: it allows + for adding or removing a secondary IP family, but it does not allow + changing the primary IP family of the Service. Valid values are "IPv4" + and "IPv6". This field only applies to Services of types ClusterIP, + NodePort, and LoadBalancer, and does apply to "headless" services. + This field will be wiped when updating a Service to type ExternalName. + + + This field may hold a maximum of two entries (dual-stack families, in + either order). These families must correspond to the values of the + clusterIPs field, if specified. Both clusterIPs and ipFamilies are + governed by the ipFamilyPolicy field. + items: + description: |- + IPFamily represents the IP Family (IPv4 or IPv6). This type is used + to express the family of an IP expressed by a type (e.g. service.spec.ipFamilies). + type: string + type: array + x-kubernetes-list-type: atomic + ipFamilyPolicy: + description: |- + IPFamilyPolicy represents the dual-stack-ness requested or required by + this Service. If there is no value provided, then this field will be set + to SingleStack. Services can be "SingleStack" (a single IP family), + "PreferDualStack" (two IP families on dual-stack configured clusters or + a single IP family on single-stack clusters), or "RequireDualStack" + (two IP families on dual-stack configured clusters, otherwise fail). The + ipFamilies and clusterIPs fields depend on the value of this field. This + field will be wiped when updating a service to type ExternalName. + type: string + loadBalancerClass: + description: |- + loadBalancerClass is the class of the load balancer implementation this Service belongs to. + If specified, the value of this field must be a label-style identifier, with an optional prefix, + e.g. "internal-vip" or "example.com/internal-vip". Unprefixed names are reserved for end-users. + This field can only be set when the Service type is 'LoadBalancer'. If not set, the default load + balancer implementation is used, today this is typically done through the cloud provider integration, + but should apply for any default implementation. If set, it is assumed that a load balancer + implementation is watching for Services with a matching class. Any default load balancer + implementation (e.g. cloud providers) should ignore Services that set this field. + This field can only be set when creating or updating a Service to type 'LoadBalancer'. + Once set, it can not be changed. This field will be wiped when a service is updated to a non 'LoadBalancer' type. + type: string + loadBalancerIP: + description: |- + Only applies to Service Type: LoadBalancer. + This feature depends on whether the underlying cloud-provider supports specifying + the loadBalancerIP when a load balancer is created. + This field will be ignored if the cloud-provider does not support the feature. + Deprecated: This field was under-specified and its meaning varies across implementations. + Using it is non-portable and it may not support dual-stack. + Users are encouraged to use implementation-specific annotations when available. + type: string + loadBalancerSourceRanges: + description: |- + If specified and supported by the platform, this will restrict traffic through the cloud-provider + load-balancer will be restricted to the specified client IPs. This field will be ignored if the + cloud-provider does not support the feature." + More info: https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/ + items: + type: string + type: array + ports: + description: |- + The list of ports that are exposed by this service. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + items: + description: ServicePort contains information on service's + port. + properties: + appProtocol: + description: |- + The application protocol for this port. + This is used as a hint for implementations to offer richer behavior for protocols that they understand. + This field follows standard Kubernetes label syntax. + Valid values are either: + + + * Un-prefixed protocol names - reserved for IANA standard service names (as per + RFC-6335 and https://www.iana.org/assignments/service-names). + + + * Kubernetes-defined prefixed names: + * 'kubernetes.io/h2c' - HTTP/2 prior knowledge over cleartext as described in https://www.rfc-editor.org/rfc/rfc9113.html#name-starting-http-2-with-prior- + * 'kubernetes.io/ws' - WebSocket over cleartext as described in https://www.rfc-editor.org/rfc/rfc6455 + * 'kubernetes.io/wss' - WebSocket over TLS as described in https://www.rfc-editor.org/rfc/rfc6455 + + + * Other protocols should use implementation-defined prefixed names such as + mycompany.com/my-custom-protocol. + type: string + name: + description: |- + The name of this port within the service. This must be a DNS_LABEL. + All ports within a ServiceSpec must have unique names. When considering + the endpoints for a Service, this must match the 'name' field in the + EndpointPort. + Optional if only one ServicePort is defined on this service. + type: string + nodePort: + description: |- + The port on each node on which this service is exposed when type is + NodePort or LoadBalancer. Usually assigned by the system. If a value is + specified, in-range, and not in use it will be used, otherwise the + operation will fail. If not specified, a port will be allocated if this + Service requires one. If this field is specified when creating a + Service which does not need it, creation will fail. This field will be + wiped when updating a Service to no longer need it (e.g. changing type + from NodePort to ClusterIP). + More info: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport + format: int32 + type: integer + port: + description: The port that will be exposed by this + service. + format: int32 + type: integer + protocol: + default: TCP + description: |- + The IP protocol for this port. Supports "TCP", "UDP", and "SCTP". + Default is TCP. + type: string + targetPort: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the pods targeted by the service. + Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + If this is a string, it will be looked up as a named port in the + target Pod's container ports. If this is not specified, the value + of the 'port' field is used (an identity map). + This field is ignored for services with clusterIP=None, and should be + omitted or set equal to the 'port' field. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#defining-a-service + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-map-keys: + - port + - protocol + x-kubernetes-list-type: map + publishNotReadyAddresses: + description: |- + publishNotReadyAddresses indicates that any agent which deals with endpoints for this + Service should disregard any indications of ready/not-ready. + The primary use case for setting this field is for a StatefulSet's Headless Service to + propagate SRV DNS records for its Pods for the purpose of peer discovery. + The Kubernetes controllers that generate Endpoints and EndpointSlice resources for + Services interpret this to mean that all endpoints are considered "ready" even if the + Pods themselves are not. Agents which consume only Kubernetes generated endpoints + through the Endpoints or EndpointSlice resources can safely assume this behavior. + type: boolean + selector: + additionalProperties: + type: string + description: |- + Route service traffic to pods with label keys and values matching this + selector. If empty or not present, the service is assumed to have an + external process managing its endpoints, which Kubernetes will not + modify. Only applies to types ClusterIP, NodePort, and LoadBalancer. + Ignored if type is ExternalName. + More info: https://kubernetes.io/docs/concepts/services-networking/service/ + type: object + x-kubernetes-map-type: atomic + sessionAffinity: + description: |- + Supports "ClientIP" and "None". Used to maintain session affinity. + Enable client IP based session affinity. + Must be ClientIP or None. + Defaults to None. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + type: string + sessionAffinityConfig: + description: sessionAffinityConfig contains the configurations + of session affinity. + properties: + clientIP: + description: clientIP contains the configurations of + Client IP based session affinity. + properties: + timeoutSeconds: + description: |- + timeoutSeconds specifies the seconds of ClientIP type session sticky time. + The value must be >0 && <=86400(for 1 day) if ServiceAffinity == "ClientIP". + Default value is 10800(for 3 hours). + format: int32 + type: integer + type: object + type: object + type: + description: |- + type determines how the Service is exposed. Defaults to ClusterIP. Valid + options are ExternalName, ClusterIP, NodePort, and LoadBalancer. + "ClusterIP" allocates a cluster-internal IP address for load-balancing + to endpoints. Endpoints are determined by the selector or if that is not + specified, by manual construction of an Endpoints object or + EndpointSlice objects. If clusterIP is "None", no virtual IP is + allocated and the endpoints are published as a set of endpoints rather + than a virtual IP. + "NodePort" builds on ClusterIP and allocates a port on every node which + routes to the same endpoints as the clusterIP. + "LoadBalancer" builds on NodePort and creates an external load-balancer + (if supported in the current cloud) which routes to the same endpoints + as the clusterIP. + "ExternalName" aliases this service to the specified externalName. + Several other fields do not apply to ExternalName services. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types + type: string + type: object + required: + - name + type: object + type: array + x-kubernetes-preserve-unknown-fields: true + shardingSpecs: + description: |- + Specifies a list of ShardingSpec objects that manage the sharding topology for Cluster Components. + Each ShardingSpec organizes components into shards, with each shard corresponding to a Component. + Components within a shard are all based on a common ClusterComponentSpec template, ensuring uniform configurations. + + + This field supports dynamic resharding by facilitating the addition or removal of shards + through the `shards` field in ShardingSpec. + + + Note: `shardingSpecs` and `componentSpecs` cannot both be empty; at least one must be defined to configure a Cluster. + items: + description: |- + ShardingSpec defines how KubeBlocks manage dynamic provisioned shards. + A typical design pattern for distributed databases is to distribute data across multiple shards, + with each shard consisting of multiple replicas. + Therefore, KubeBlocks supports representing a shard with a Component and dynamically instantiating Components + using a template when shards are added. + When shards are removed, the corresponding Components are also deleted. + properties: + name: + description: |- + Represents the common parent part of all shard names. + This identifier is included as part of the Service DNS name and must comply with IANA service naming rules. + It is used to generate the names of underlying Components following the pattern `$(shardingSpec.name)-$(ShardID)`. + ShardID is a random string that is appended to the Name to generate unique identifiers for each shard. + For example, if the sharding specification name is "my-shard" and the ShardID is "abc", the resulting Component name + would be "my-shard-abc". + + + Note that the name defined in Component template(`shardingSpec.template.name`) will be disregarded + when generating the Component names of the shards. The `shardingSpec.name` field takes precedence. + maxLength: 15 + pattern: ^[a-z0-9]([a-z0-9\.\-]*[a-z0-9])?$ + type: string + x-kubernetes-validations: + - message: name is immutable + rule: self == oldSelf + shards: + description: |- + Specifies the desired number of shards. + Users can declare the desired number of shards through this field. + KubeBlocks dynamically creates and deletes Components based on the difference + between the desired and actual number of shards. + KubeBlocks provides lifecycle management for sharding, including: + + + - Executing the postProvision Action defined in the ComponentDefinition when the number of shards increases. + This allows for custom actions to be performed after a new shard is provisioned. + - Executing the preTerminate Action defined in the ComponentDefinition when the number of shards decreases. + This enables custom cleanup or data migration tasks to be executed before a shard is terminated. + Resources and data associated with the corresponding Component will also be deleted. + format: int32 + maximum: 2048 + minimum: 0 + type: integer + template: + description: |- + The template for generating Components for shards, where each shard consists of one Component. + This field is of type ClusterComponentSpec, which encapsulates all the required details and + definitions for creating and managing the Components. + KubeBlocks uses this template to generate a set of identical Components or shards. + All the generated Components will have the same specifications and definitions as specified in the `template` field. + + + This allows for the creation of multiple Components with consistent configurations, + enabling sharding and distribution of workloads across Components. + properties: + annotations: + additionalProperties: + type: string + description: Specifies Annotations to override or add for + underlying Pods. + type: object + componentDef: + description: |- + References the name of a ComponentDefinition object. + The ComponentDefinition specifies the behavior and characteristics of the Component. + If both `componentDefRef` and `componentDef` are provided, + the `componentDef` will take precedence over `componentDefRef`. + maxLength: 64 + pattern: ^[a-z0-9]([a-z0-9\.\-]*[a-z0-9])?$ + type: string + componentDefRef: + description: |- + References a ClusterComponentDefinition defined in the `clusterDefinition.spec.componentDef` field. + Must comply with the IANA service naming rule. + + + Deprecated since v0.9, + because defining Components in `clusterDefinition.spec.componentDef` field has been deprecated. + This field is replaced by the `componentDef` field, use `componentDef` instead. + This field is maintained for backward compatibility and its use is discouraged. + Existing usage should be updated to the current preferred approach to avoid compatibility issues in future releases. + + + TODO +kubebuilder:validation:XValidation:rule="self == oldSelf",message="componentDefRef is immutable" + maxLength: 22 + pattern: ^[a-z]([a-z0-9\-]*[a-z0-9])?$ + type: string + configs: + description: Specifies the configuration content of a config + template. + items: + description: ClusterComponentConfig represents a config + with its source bound. + properties: + configMap: + description: ConfigMap source for the config. + properties: + defaultMode: + description: |- + defaultMode is optional: mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + items: + description: |- + items if unspecified, each key-value pair in the Data field of the referenced + ConfigMap will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the ConfigMap, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within + a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + 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 + optional: + description: optional specify whether the ConfigMap + or its keys must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + name: + description: The name of the config. + type: string + type: object + type: array + disableExporter: + description: |- + Determines whether metrics exporter information is annotated on the Component's headless Service. + + + If set to true, the following annotations will not be patched into the Service: + + + - "monitor.kubeblocks.io/path" + - "monitor.kubeblocks.io/port" + - "monitor.kubeblocks.io/scheme" + + + These annotations allow the Prometheus installed by KubeBlocks to discover and scrape metrics from the exporter. + type: boolean + enabledLogs: + description: |- + Specifies which types of logs should be collected for the Component. + The log types are defined in the `componentDefinition.spec.logConfigs` field with the LogConfig entries. + + + The elements in the `enabledLogs` array correspond to the names of the LogConfig entries. + For example, if the `componentDefinition.spec.logConfigs` defines LogConfig entries with + names "slow_query_log" and "error_log", + you can enable the collection of these logs by including their names in the `enabledLogs` array: + ```yaml + enabledLogs: + - slow_query_log + - error_log + ``` + items: + type: string + type: array + x-kubernetes-list-type: set + env: + description: |- + List of environment variables to add. + These environment variables will be placed after the environment variables declared in the Pod. + items: + description: EnvVar represents an environment variable + present in a Container. + properties: + name: + description: Name of the environment variable. Must + be a C_IDENTIFIER. + type: string + value: + description: |- + Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in the container and + any service environment variables. If a variable cannot be resolved, + the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless of whether the variable + exists or not. + Defaults to "". + type: string + valueFrom: + description: Source for the environment variable's + value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in + the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required for + volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of + the exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in the + pod's namespace + properties: + key: + description: The key of the secret to select + from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or + its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + instances: + description: |- + Allows for the customization of configuration values for each instance within a Component. + An instance represent a single replica (Pod and associated K8s resources like PVCs, Services, and ConfigMaps). + While instances typically share a common configuration as defined in the ClusterComponentSpec, + they can require unique settings in various scenarios: + + + For example: + - A database Component might require different resource allocations for primary and secondary instances, + with primaries needing more resources. + - During a rolling upgrade, a Component may first update the image for one or a few instances, + and then update the remaining instances after verifying that the updated instances are functioning correctly. + + + InstanceTemplate allows for specifying these unique configurations per instance. + Each instance's name is constructed using the pattern: $(component.name)-$(template.name)-$(ordinal), + starting with an ordinal of 0. + It is crucial to maintain unique names for each InstanceTemplate to avoid conflicts. + + + The sum of replicas across all InstanceTemplates should not exceed the total number of replicas specified for the Component. + Any remaining replicas will be generated using the default template and will follow the default naming rules. + items: + description: InstanceTemplate allows customization of + individual replica configurations in a Component. + properties: + annotations: + additionalProperties: + type: string + description: |- + Specifies a map of key-value pairs to be merged into the Pod's existing annotations. + Existing keys will have their values overwritten, while new keys will be added to the annotations. + type: object + env: + description: |- + Defines Env to override. + Add new or override existing envs. + items: + description: EnvVar represents an environment variable + present in a Container. + properties: + name: + description: Name of the environment variable. + Must be a C_IDENTIFIER. + type: string + value: + description: |- + Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in the container and + any service environment variables. If a variable cannot be resolved, + the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless of whether the variable + exists or not. + Defaults to "". + type: string + valueFrom: + description: Source for the environment variable's + value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the + FieldPath is written in terms of, + defaults to "v1". + type: string + fieldPath: + description: Path of the field to select + in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required + for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format + of the exposed resources, defaults + to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to + select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in + the pod's namespace + properties: + key: + description: The key of the secret to + select from. Must be a valid secret + key. + type: string + 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 + optional: + description: Specify whether the Secret + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + image: + description: Specifies an override for the first container's + image in the Pod. + type: string + labels: + additionalProperties: + type: string + description: |- + Specifies a map of key-value pairs that will be merged into the Pod's existing labels. + Values for existing keys will be overwritten, and new keys will be added. + type: object + name: + description: |- + Name specifies the unique name of the instance Pod created using this InstanceTemplate. + This name is constructed by concatenating the Component's name, the template's name, and the instance's ordinal + using the pattern: $(cluster.name)-$(component.name)-$(template.name)-$(ordinal). Ordinals start from 0. + The specified name overrides any default naming conventions or patterns. + maxLength: 54 + pattern: ^[a-z0-9]([a-z0-9\.\-]*[a-z0-9])?$ + type: string + replicas: + default: 1 + description: |- + Specifies the number of instances (Pods) to create from this InstanceTemplate. + This field allows setting how many replicated instances of the Component, + with the specific overrides in the InstanceTemplate, are created. + The default value is 1. A value of 0 disables instance creation. + format: int32 + minimum: 0 + type: integer + resources: + description: |- + Specifies an override for the resource requirements of the first container in the Pod. + This field allows for customizing resource allocation (CPU, memory, etc.) for the container. + properties: + claims: + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + + + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + + + This field is immutable. It can only be set for containers. + items: + description: ResourceClaim references one entry + in PodSpec.ResourceClaims. + properties: + name: + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + schedulingPolicy: + description: Specifies the scheduling policy for the + Component. + properties: + affinity: + description: Specifies a group of affinity scheduling + rules of the Cluster, including NodeAffinity, + PodAffinity, and PodAntiAffinity. + properties: + nodeAffinity: + description: Describes node affinity scheduling + rules for the pod. + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node matches the corresponding matchExpressions; the + node(s) with the highest sum are the most preferred. + items: + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). + properties: + preference: + description: A node selector term, + associated with the corresponding + weight. + properties: + matchExpressions: + description: A list of node + selector requirements by node's + labels. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label + key that the selector + applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node + selector requirements by node's + fields. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label + key that the selector + applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + weight: + description: Weight associated with + matching the corresponding nodeSelectorTerm, + in the range 1-100. + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. + properties: + nodeSelectorTerms: + description: Required. A list of node + selector terms. The terms are ORed. + items: + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. + properties: + matchExpressions: + description: A list of node + selector requirements by node's + labels. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label + key that the selector + applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node + selector requirements by node's + fields. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label + key that the selector + applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + type: array + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + description: Describes pod affinity scheduling + rules (e.g. co-locate this pod in the same + node, zone, etc. as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the + matched WeightedPodAffinityTerm fields + are added per-node to find the most + preferred node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity + term, associated with the corresponding + weight. + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions + is a list of label selector + requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is + the label key that + the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. + Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions + is a list of label selector + requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is + the label key that + the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: |- + weight associated with matching the corresponding podAffinityTerm, + in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. + items: + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions + is a list of label selector + requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the + label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. + Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions + is a list of label selector + requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the + label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + description: Describes pod anti-affinity scheduling + rules (e.g. avoid putting this pod in the + same node, zone, etc. as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the anti-affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the + matched WeightedPodAffinityTerm fields + are added per-node to find the most + preferred node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity + term, associated with the corresponding + weight. + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions + is a list of label selector + requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is + the label key that + the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. + Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions + is a list of label selector + requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is + the label key that + the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: |- + weight associated with matching the corresponding podAffinityTerm, + in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the anti-affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the anti-affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. + items: + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions + is a list of label selector + requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the + label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. + Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions + is a list of label selector + requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the + label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + nodeName: + description: |- + NodeName is a request to schedule this Pod onto a specific node. If it is non-empty, + the scheduler simply schedules this Pod onto that node, assuming that it fits resource + requirements. + type: string + nodeSelector: + additionalProperties: + type: string + description: |- + NodeSelector is a selector which must be true for the Pod to fit on a node. + Selector which must match a node's labels for the Pod to be scheduled on that node. + More info: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ + type: object + x-kubernetes-map-type: atomic + schedulerName: + description: |- + If specified, the Pod will be dispatched by specified scheduler. + If not specified, the Pod will be dispatched by default scheduler. + type: string + tolerations: + description: |- + Allows Pods to be scheduled onto nodes with matching taints. + Each toleration in the array allows the Pod to tolerate node taints based on + specified `key`, `value`, `effect`, and `operator`. + + + - The `key`, `value`, and `effect` identify the taint that the toleration matches. + - The `operator` determines how the toleration matches the taint. + + + Pods with matching tolerations are allowed to be scheduled on tainted nodes, typically reserved for specific purposes. + items: + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . + properties: + effect: + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. + type: string + operator: + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. + type: string + tolerationSeconds: + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. + format: int64 + type: integer + value: + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. + type: string + type: object + type: array + topologySpreadConstraints: + description: |- + TopologySpreadConstraints describes how a group of Pods ought to spread across topology + domains. Scheduler will schedule Pods in a way which abides by the constraints. + All topologySpreadConstraints are ANDed. + items: + description: TopologySpreadConstraint specifies + how to spread matching pods among the given + topology. + properties: + labelSelector: + description: |- + LabelSelector is used to find matching pods. + Pods that match this label selector are counted to determine the number of pods + in their corresponding topology domain. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select the pods over which + spreading will be calculated. The keys are used to lookup values from the + incoming pod labels, those key-value labels are ANDed with labelSelector + to select the group of existing pods over which spreading will be calculated + for the incoming pod. The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + MatchLabelKeys cannot be set when LabelSelector isn't set. + Keys that don't exist in the incoming pod labels will + be ignored. A null or empty list means only match against labelSelector. + + + This is a beta field and requires the MatchLabelKeysInPodTopologySpread feature gate to be enabled (enabled by default). + items: + type: string + type: array + x-kubernetes-list-type: atomic + maxSkew: + description: |- + MaxSkew describes the degree to which pods may be unevenly distributed. + When `whenUnsatisfiable=DoNotSchedule`, it is the maximum permitted difference + between the number of matching pods in the target topology and the global minimum. + The global minimum is the minimum number of matching pods in an eligible domain + or zero if the number of eligible domains is less than MinDomains. + For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same + labelSelector spread as 2/2/1: + In this case, the global minimum is 1. + | zone1 | zone2 | zone3 | + | P P | P P | P | + - if MaxSkew is 1, incoming pod can only be scheduled to zone3 to become 2/2/2; + scheduling it onto zone1(zone2) would make the ActualSkew(3-1) on zone1(zone2) + violate MaxSkew(1). + - if MaxSkew is 2, incoming pod can be scheduled onto any zone. + When `whenUnsatisfiable=ScheduleAnyway`, it is used to give higher precedence + to topologies that satisfy it. + It's a required field. Default value is 1 and 0 is not allowed. + format: int32 + type: integer + minDomains: + description: |- + MinDomains indicates a minimum number of eligible domains. + When the number of eligible domains with matching topology keys is less than minDomains, + Pod Topology Spread treats "global minimum" as 0, and then the calculation of Skew is performed. + And when the number of eligible domains with matching topology keys equals or greater than minDomains, + this value has no effect on scheduling. + As a result, when the number of eligible domains is less than minDomains, + scheduler won't schedule more than maxSkew Pods to those domains. + If value is nil, the constraint behaves as if MinDomains is equal to 1. + Valid values are integers greater than 0. + When value is not nil, WhenUnsatisfiable must be DoNotSchedule. + + + For example, in a 3-zone cluster, MaxSkew is set to 2, MinDomains is set to 5 and pods with the same + labelSelector spread as 2/2/2: + | zone1 | zone2 | zone3 | + | P P | P P | P P | + The number of domains is less than 5(MinDomains), so "global minimum" is treated as 0. + In this situation, new pod with the same labelSelector cannot be scheduled, + because computed skew will be 3(3 - 0) if new Pod is scheduled to any of the three zones, + it will violate MaxSkew. + + + This is a beta field and requires the MinDomainsInPodTopologySpread feature gate to be enabled (enabled by default). + format: int32 + type: integer + nodeAffinityPolicy: + description: |- + NodeAffinityPolicy indicates how we will treat Pod's nodeAffinity/nodeSelector + when calculating pod topology spread skew. Options are: + - Honor: only nodes matching nodeAffinity/nodeSelector are included in the calculations. + - Ignore: nodeAffinity/nodeSelector are ignored. All nodes are included in the calculations. + + + If this value is nil, the behavior is equivalent to the Honor policy. + This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag. + type: string + nodeTaintsPolicy: + description: |- + NodeTaintsPolicy indicates how we will treat node taints when calculating + pod topology spread skew. Options are: + - Honor: nodes without taints, along with tainted nodes for which the incoming pod + has a toleration, are included. + - Ignore: node taints are ignored. All nodes are included. + + + If this value is nil, the behavior is equivalent to the Ignore policy. + This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag. + type: string + topologyKey: + description: |- + TopologyKey is the key of node labels. Nodes that have a label with this key + and identical values are considered to be in the same topology. + We consider each as a "bucket", and try to put balanced number + of pods into each bucket. + We define a domain as a particular instance of a topology. + Also, we define an eligible domain as a domain whose nodes meet the requirements of + nodeAffinityPolicy and nodeTaintsPolicy. + e.g. If TopologyKey is "kubernetes.io/hostname", each Node is a domain of that topology. + And, if TopologyKey is "topology.kubernetes.io/zone", each zone is a domain of that topology. + It's a required field. + type: string + whenUnsatisfiable: + description: |- + WhenUnsatisfiable indicates how to deal with a pod if it doesn't satisfy + the spread constraint. + - DoNotSchedule (default) tells the scheduler not to schedule it. + - ScheduleAnyway tells the scheduler to schedule the pod in any location, + but giving higher precedence to topologies that would help reduce the + skew. + A constraint is considered "Unsatisfiable" for an incoming pod + if and only if every possible node assignment for that pod would violate + "MaxSkew" on some topology. + For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same + labelSelector spread as 3/1/1: + | zone1 | zone2 | zone3 | + | P P P | P | P | + If WhenUnsatisfiable is set to DoNotSchedule, incoming pod can only be scheduled + to zone2(zone3) to become 3/2/1(3/1/2) as ActualSkew(2-1) on zone2(zone3) satisfies + MaxSkew(1). In other words, the cluster can still be imbalanced, but scheduler + won't make it *more* imbalanced. + It's a required field. + type: string + required: + - maxSkew + - topologyKey + - whenUnsatisfiable + type: object + type: array + type: object + volumeClaimTemplates: + description: |- + Defines VolumeClaimTemplates to override. + Add new or override existing volume claim templates. + items: + properties: + name: + description: |- + Refers to the name of a volumeMount defined in either: + + + - `componentDefinition.spec.runtime.containers[*].volumeMounts` + - `clusterDefinition.spec.componentDefs[*].podSpec.containers[*].volumeMounts` (deprecated) + + + The value of `name` must match the `name` field of a volumeMount specified in the corresponding `volumeMounts` array. + type: string + spec: + description: |- + Defines the desired characteristics of a PersistentVolumeClaim that will be created for the volume + with the mount name specified in the `name` field. + + + When a Pod is created for this ClusterComponent, a new PVC will be created based on the specification + defined in the `spec` field. The PVC will be associated with the volume mount specified by the `name` field. + properties: + accessModes: + description: |- + Contains the desired access modes the volume should have. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1. + items: + type: string + type: array + x-kubernetes-preserve-unknown-fields: true + resources: + description: |- + Represents the minimum resources the volume should have. + If the RecoverVolumeExpansionFailure feature is enabled, users are allowed to specify resource requirements that + are lower than the previous value but must still be higher than the capacity recorded in the status field of the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources. + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + x-kubernetes-preserve-unknown-fields: true + storageClassName: + description: |- + The name of the StorageClass required by the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1. + type: string + volumeMode: + description: Defines what type of volume + is required by the claim, either Block + or Filesystem. + type: string + type: object + required: + - name + type: object + type: array + volumeMounts: + description: |- + Defines VolumeMounts to override. + Add new or override existing volume mounts of the first container in the Pod. + items: + description: VolumeMount describes a mounting of + a Volume within a container. + properties: + mountPath: + description: |- + Path within the container at which the volume should be mounted. Must + not contain ':'. + type: string + mountPropagation: + description: |- + mountPropagation determines how mounts are propagated from the host + to container and the other way around. + When not set, MountPropagationNone is used. + This field is beta in 1.10. + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: |- + Mounted read-only if true, read-write otherwise (false or unspecified). + Defaults to false. + type: boolean + subPath: + description: |- + Path within the volume from which the container's volume should be mounted. + Defaults to "" (volume's root). + type: string + subPathExpr: + description: |- + Expanded path within the volume from which the container's volume should be mounted. + Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment. + Defaults to "" (volume's root). + SubPathExpr and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + volumes: + description: |- + Defines Volumes to override. + Add new or override existing volumes. + items: + description: Volume represents a named volume in + a pod that may be accessed by any container in + the pod. + properties: + awsElasticBlockStore: + description: |- + awsElasticBlockStore represents an AWS Disk resource that is attached to a + kubelet's host machine and then exposed to the pod. + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + properties: + fsType: + description: |- + fsType is the filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + partition: + description: |- + partition is the partition in the volume that you want to mount. + If omitted, the default is to mount by volume name. + Examples: For volume /dev/sda1, you specify the partition as "1". + Similarly, the volume partition for /dev/sda is "0" (or you can leave the property empty). + format: int32 + type: integer + readOnly: + description: |- + readOnly value true will force the readOnly setting in VolumeMounts. + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + type: boolean + volumeID: + description: |- + volumeID is unique ID of the persistent disk resource in AWS (Amazon EBS volume). + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + type: string + required: + - volumeID + type: object + azureDisk: + description: azureDisk represents an Azure Data + Disk mount on the host and bind mount to the + pod. + properties: + cachingMode: + description: 'cachingMode is the Host Caching + mode: None, Read Only, Read Write.' + type: string + diskName: + description: diskName is the Name of the + data disk in the blob storage + type: string + diskURI: + description: diskURI is the URI of data + disk in the blob storage + type: string + fsType: + description: |- + fsType is Filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + kind: + description: 'kind expected values are Shared: + multiple blob disks per storage account Dedicated: + single blob disk per storage account Managed: + azure managed data disk (only in managed + availability set). defaults to shared' + type: string + readOnly: + description: |- + readOnly Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + description: azureFile represents an Azure File + Service mount on the host and bind mount to + the pod. + properties: + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretName: + description: secretName is the name of + secret that contains Azure Storage Account + Name and Key + type: string + shareName: + description: shareName is the azure share + Name + type: string + required: + - secretName + - shareName + type: object + cephfs: + description: cephFS represents a Ceph FS mount + on the host that shares a pod's lifetime + properties: + monitors: + description: |- + monitors is Required: Monitors is a collection of Ceph monitors + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + items: + type: string + type: array + path: + description: 'path is Optional: Used as + the mounted root, rather than the full + Ceph tree, default is /' + type: string + readOnly: + description: |- + readOnly is Optional: Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + type: boolean + secretFile: + description: |- + secretFile is Optional: SecretFile is the path to key ring for User, default is /etc/ceph/user.secret + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + type: string + secretRef: + description: |- + secretRef is Optional: SecretRef is reference to the authentication secret for User, default is empty. + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + 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 + user: + description: |- + user is optional: User is the rados user name, default is admin + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + type: string + required: + - monitors + type: object + cinder: + description: |- + cinder represents a cinder volume attached and mounted on kubelets host machine. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + type: string + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + type: boolean + secretRef: + description: |- + secretRef is optional: points to a secret object containing parameters used to connect + to OpenStack. + 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 + volumeID: + description: |- + volumeID used to identify the volume in cinder. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + type: string + required: + - volumeID + type: object + configMap: + description: configMap represents a configMap + that should populate this volume + properties: + defaultMode: + description: |- + defaultMode is optional: mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + items: + description: |- + items if unspecified, each key-value pair in the Data field of the referenced + ConfigMap will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the ConfigMap, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path + within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + 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 + optional: + description: optional specify whether the + ConfigMap or its keys must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + csi: + description: csi (Container Storage Interface) + represents ephemeral storage that is handled + by certain external CSI drivers (Beta feature). + properties: + driver: + description: |- + driver is the name of the CSI driver that handles this volume. + Consult with your admin for the correct name as registered in the cluster. + type: string + fsType: + description: |- + fsType to mount. Ex. "ext4", "xfs", "ntfs". + If not provided, the empty value is passed to the associated CSI driver + which will determine the default filesystem to apply. + type: string + nodePublishSecretRef: + description: |- + nodePublishSecretRef is a reference to the secret object containing + sensitive information to pass to the CSI driver to complete the CSI + NodePublishVolume and NodeUnpublishVolume calls. + This field is optional, and may be empty if no secret is required. If the + secret object contains more than one secret, all secret references are passed. + 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 + readOnly: + description: |- + readOnly specifies a read-only configuration for the volume. + Defaults to false (read/write). + type: boolean + volumeAttributes: + additionalProperties: + type: string + description: |- + volumeAttributes stores driver-specific properties that are passed to the CSI + driver. Consult your driver's documentation for supported values. + type: object + required: + - driver + type: object + downwardAPI: + description: downwardAPI represents downward + API about the pod that should populate this + volume + properties: + defaultMode: + description: |- + Optional: mode bits to use on created files by default. Must be a + Optional: mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + items: + description: Items is a list of downward + API volume file + items: + description: DownwardAPIVolumeFile represents + information to create the file containing + the pod field + properties: + fieldRef: + description: 'Required: Selects a + field of the pod: only annotations, + labels, name and namespace are supported.' + properties: + apiVersion: + description: Version of the schema + the FieldPath is written in + terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field + to select in the specified API + version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + description: |- + Optional: mode bits used to set permissions on this file, must be an octal value + between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: 'Required: Path is the + relative path name of the file to + be created. Must not be absolute + or contain the ''..'' path. Must + be utf-8 encoded. The first item + of the relative path must not start + with ''..''' + type: string + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported. + properties: + containerName: + description: 'Container name: + required for volumes, optional + for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output + format of the exposed resources, + defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource + to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + type: object + emptyDir: + description: |- + emptyDir represents a temporary directory that shares a pod's lifetime. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir + properties: + medium: + description: |- + medium represents what type of storage medium should back this directory. + The default is "" which means to use the node's default medium. + Must be an empty string (default) or Memory. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + description: |- + sizeLimit is the total amount of local storage required for this EmptyDir volume. + The size limit is also applicable for memory medium. + The maximum usage on memory medium EmptyDir would be the minimum value between + the SizeLimit specified here and the sum of memory limits of all containers in a pod. + The default is nil which means that the limit is undefined. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + description: |- + ephemeral represents a volume that is handled by a cluster storage driver. + The volume's lifecycle is tied to the pod that defines it - it will be created before the pod starts, + and deleted when the pod is removed. + + + Use this if: + a) the volume is only needed while the pod runs, + b) features of normal volumes like restoring from snapshot or capacity + tracking are needed, + c) the storage driver is specified through a storage class, and + d) the storage driver supports dynamic volume provisioning through + a PersistentVolumeClaim (see EphemeralVolumeSource for more + information on the connection between this volume type + and PersistentVolumeClaim). + + + Use PersistentVolumeClaim or one of the vendor-specific + APIs for volumes that persist for longer than the lifecycle + of an individual pod. + + + Use CSI for light-weight local ephemeral volumes if the CSI driver is meant to + be used that way - see the documentation of the driver for + more information. + + + A pod can use both types of ephemeral volumes and + persistent volumes at the same time. + properties: + volumeClaimTemplate: + description: |- + Will be used to create a stand-alone PVC to provision the volume. + The pod in which this EphemeralVolumeSource is embedded will be the + owner of the PVC, i.e. the PVC will be deleted together with the + pod. The name of the PVC will be `-` where + `` is the name from the `PodSpec.Volumes` array + entry. Pod validation will reject the pod if the concatenated name + is not valid for a PVC (for example, too long). + + + An existing PVC with that name that is not owned by the pod + will *not* be used for the pod to avoid using an unrelated + volume by mistake. Starting the pod is then blocked until + the unrelated PVC is removed. If such a pre-created PVC is + meant to be used by the pod, the PVC has to updated with an + owner reference to the pod once the pod exists. Normally + this should not be necessary, but it may be useful when + manually reconstructing a broken cluster. + + + This field is read-only and no changes will be made by Kubernetes + to the PVC after it has been created. + + + Required, must not be nil. + properties: + metadata: + description: |- + May contain labels and annotations that will be copied into the PVC + when creating it. No other fields are allowed and will be rejected during + validation. + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + description: |- + The specification for the PersistentVolumeClaim. The entire content is + copied unchanged into the PVC that gets created from this + template. The same fields as in a PersistentVolumeClaim + are also valid here. + properties: + accessModes: + description: |- + accessModes contains the desired access modes the volume should have. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1 + items: + type: string + type: array + dataSource: + description: |- + dataSource field can be used to specify either: + * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) + * An existing PVC (PersistentVolumeClaim) + If the provisioner or an external controller can support the specified data source, + it will create a new volume based on the contents of the specified data source. + When the AnyVolumeDataSource feature gate is enabled, dataSource contents will be copied to dataSourceRef, + and dataSourceRef contents will be copied to dataSource when dataSourceRef.namespace is not specified. + If the namespace is specified, then dataSourceRef will not be copied to dataSource. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type + of resource being referenced + type: string + name: + description: Name is the name + of resource being referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + description: |- + dataSourceRef specifies the object from which to populate the volume with data, if a non-empty + volume is desired. This may be any object from a non-empty API group (non + core object) or a PersistentVolumeClaim object. + When this field is specified, volume binding will only succeed if the type of + the specified object matches some installed volume populator or dynamic + provisioner. + This field will replace the functionality of the dataSource field and as such + if both fields are non-empty, they must have the same value. For backwards + compatibility, when namespace isn't specified in dataSourceRef, + both fields (dataSource and dataSourceRef) will be set to the same + value automatically if one of them is empty and the other is non-empty. + When namespace is specified in dataSourceRef, + dataSource isn't set to the same value and must be empty. + There are three important differences between dataSource and dataSourceRef: + * While dataSource only allows two specific types of objects, dataSourceRef + allows any non-core object, as well as PersistentVolumeClaim objects. + * While dataSource ignores disallowed values (dropping them), dataSourceRef + preserves all values, and generates an error if a disallowed value is + specified. + * While dataSource only allows local objects, dataSourceRef allows objects + in any namespaces. + (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled. + (Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type + of resource being referenced + type: string + name: + description: Name is the name + of resource being referenced + type: string + namespace: + description: |- + Namespace is the namespace of resource being referenced + Note that when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details. + (Alpha) This field requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + type: string + required: + - kind + - name + type: object + resources: + description: |- + resources represents the minimum resources the volume should have. + If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements + that are lower than previous value but must still be higher than capacity recorded in the + status field of the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + selector: + description: selector is a label + query over volumes to consider + for binding. + properties: + matchExpressions: + description: matchExpressions + is a list of label selector + requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the + label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + description: |- + storageClassName is the name of the StorageClass required by the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1 + type: string + volumeAttributesClassName: + description: |- + volumeAttributesClassName may be used to set the VolumeAttributesClass used by this claim. + If specified, the CSI driver will create or update the volume with the attributes defined + in the corresponding VolumeAttributesClass. This has a different purpose than storageClassName, + it can be changed after the claim is created. An empty string value means that no VolumeAttributesClass + will be applied to the claim but it's not allowed to reset this field to empty string once it is set. + If unspecified and the PersistentVolumeClaim is unbound, the default VolumeAttributesClass + will be set by the persistentvolume controller if it exists. + If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be + set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource + exists. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#volumeattributesclass + (Alpha) Using this field requires the VolumeAttributesClass feature gate to be enabled. + type: string + volumeMode: + description: |- + volumeMode defines what type of volume is required by the claim. + Value of Filesystem is implied when not included in claim spec. + type: string + volumeName: + description: volumeName is the binding + reference to the PersistentVolume + backing this claim. + type: string + type: object + required: + - spec + type: object + type: object + fc: + description: fc represents a Fibre Channel resource + that is attached to a kubelet's host machine + and then exposed to the pod. + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + lun: + description: 'lun is Optional: FC target + lun number' + format: int32 + type: integer + readOnly: + description: |- + readOnly is Optional: Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + targetWWNs: + description: 'targetWWNs is Optional: FC + target worldwide names (WWNs)' + items: + type: string + type: array + wwids: + description: |- + wwids Optional: FC volume world wide identifiers (wwids) + Either wwids or combination of targetWWNs and lun must be set, but not both simultaneously. + items: + type: string + type: array + type: object + flexVolume: + description: |- + flexVolume represents a generic volume resource that is + provisioned/attached using an exec based plugin. + properties: + driver: + description: driver is the name of the driver + to use for this volume. + type: string + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". The default filesystem depends on FlexVolume script. + type: string + options: + additionalProperties: + type: string + description: 'options is Optional: this + field holds extra command options if any.' + type: object + readOnly: + description: |- + readOnly is Optional: defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: |- + secretRef is Optional: secretRef is reference to the secret object containing + sensitive information to pass to the plugin scripts. This may be + empty if no secret object is specified. If the secret object + contains more than one secret, all secrets are passed to the plugin + scripts. + 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 + required: + - driver + type: object + flocker: + description: flocker represents a Flocker volume + attached to a kubelet's host machine. This + depends on the Flocker control service being + running + properties: + datasetName: + description: |- + datasetName is Name of the dataset stored as metadata -> name on the dataset for Flocker + should be considered as deprecated + type: string + datasetUUID: + description: datasetUUID is the UUID of + the dataset. This is unique identifier + of a Flocker dataset + type: string + type: object + gcePersistentDisk: + description: |- + gcePersistentDisk represents a GCE Disk resource that is attached to a + kubelet's host machine and then exposed to the pod. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + properties: + fsType: + description: |- + fsType is filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + partition: + description: |- + partition is the partition in the volume that you want to mount. + If omitted, the default is to mount by volume name. + Examples: For volume /dev/sda1, you specify the partition as "1". + Similarly, the volume partition for /dev/sda is "0" (or you can leave the property empty). + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + format: int32 + type: integer + pdName: + description: |- + pdName is unique name of the PD resource in GCE. Used to identify the disk in GCE. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + type: string + readOnly: + description: |- + readOnly here will force the ReadOnly setting in VolumeMounts. + Defaults to false. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + type: boolean + required: + - pdName + type: object + gitRepo: + description: |- + gitRepo represents a git repository at a particular revision. + DEPRECATED: GitRepo is deprecated. To provision a container with a git repo, mount an + EmptyDir into an InitContainer that clones the repo using git, then mount the EmptyDir + into the Pod's container. + properties: + directory: + description: |- + directory is the target directory name. + Must not contain or start with '..'. If '.' is supplied, the volume directory will be the + git repository. Otherwise, if specified, the volume will contain the git repository in + the subdirectory with the given name. + type: string + repository: + description: repository is the URL + type: string + revision: + description: revision is the commit hash + for the specified revision. + type: string + required: + - repository + type: object + glusterfs: + description: |- + glusterfs represents a Glusterfs mount on the host that shares a pod's lifetime. + More info: https://examples.k8s.io/volumes/glusterfs/README.md + properties: + endpoints: + description: |- + endpoints is the endpoint name that details Glusterfs topology. + More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod + type: string + path: + description: |- + path is the Glusterfs volume path. + More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod + type: string + readOnly: + description: |- + readOnly here will force the Glusterfs volume to be mounted with read-only permissions. + Defaults to false. + More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod + type: boolean + required: + - endpoints + - path + type: object + hostPath: + description: |- + hostPath represents a pre-existing file or directory on the host + machine that is directly exposed to the container. This is generally + used for system agents or other privileged things that are allowed + to see the host machine. Most containers will NOT need this. + More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + --- + TODO(jonesdl) We need to restrict who can use host directory mounts and who can/can not + mount host directories as read/write. + properties: + path: + description: |- + path of the directory on the host. + If the path is a symlink, it will follow the link to the real path. + More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + type: string + type: + description: |- + type for HostPath Volume + Defaults to "" + More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + type: string + required: + - path + type: object + iscsi: + description: |- + iscsi represents an ISCSI Disk resource that is attached to a + kubelet's host machine and then exposed to the pod. + More info: https://examples.k8s.io/volumes/iscsi/README.md + properties: + chapAuthDiscovery: + description: chapAuthDiscovery defines whether + support iSCSI Discovery CHAP authentication + type: boolean + chapAuthSession: + description: chapAuthSession defines whether + support iSCSI Session CHAP authentication + type: boolean + fsType: + description: |- + fsType is the filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#iscsi + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + initiatorName: + description: |- + initiatorName is the custom iSCSI Initiator Name. + If initiatorName is specified with iscsiInterface simultaneously, new iSCSI interface + : will be created for the connection. + type: string + iqn: + description: iqn is the target iSCSI Qualified + Name. + type: string + iscsiInterface: + description: |- + iscsiInterface is the interface Name that uses an iSCSI transport. + Defaults to 'default' (tcp). + type: string + lun: + description: lun represents iSCSI Target + Lun number. + format: int32 + type: integer + portals: + description: |- + portals is the iSCSI Target Portal List. The portal is either an IP or ip_addr:port if the port + is other than default (typically TCP ports 860 and 3260). + items: + type: string + type: array + readOnly: + description: |- + readOnly here will force the ReadOnly setting in VolumeMounts. + Defaults to false. + type: boolean + secretRef: + description: secretRef is the CHAP Secret + for iSCSI target and initiator authentication + 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 + targetPortal: + description: |- + targetPortal is iSCSI Target Portal. The Portal is either an IP or ip_addr:port if the port + is other than default (typically TCP ports 860 and 3260). + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + description: |- + name of the volume. + Must be a DNS_LABEL and unique within the pod. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + nfs: + description: |- + nfs represents an NFS mount on the host that shares a pod's lifetime + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + properties: + path: + description: |- + path that is exported by the NFS server. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + type: string + readOnly: + description: |- + readOnly here will force the NFS export to be mounted with read-only permissions. + Defaults to false. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + type: boolean + server: + description: |- + server is the hostname or IP address of the NFS server. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + description: |- + persistentVolumeClaimVolumeSource represents a reference to a + PersistentVolumeClaim in the same namespace. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims + properties: + claimName: + description: |- + claimName is the name of a PersistentVolumeClaim in the same namespace as the pod using this volume. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims + type: string + readOnly: + description: |- + readOnly Will force the ReadOnly setting in VolumeMounts. + Default false. + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + description: photonPersistentDisk represents + a PhotonController persistent disk attached + and mounted on kubelets host machine + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + pdID: + description: pdID is the ID that identifies + Photon Controller persistent disk + type: string + required: + - pdID + type: object + portworxVolume: + description: portworxVolume represents a portworx + volume attached and mounted on kubelets host + machine + properties: + fsType: + description: |- + fSType represents the filesystem type to mount + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs". Implicitly inferred to be "ext4" if unspecified. + type: string + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + volumeID: + description: volumeID uniquely identifies + a Portworx volume + type: string + required: + - volumeID + type: object + projected: + description: projected items for all in one + resources secrets, configmaps, and downward + API + properties: + defaultMode: + description: |- + defaultMode are the mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + sources: + description: sources is the list of volume + projections + items: + description: Projection that may be projected + along with other supported volume types + properties: + clusterTrustBundle: + description: |- + ClusterTrustBundle allows a pod to access the `.spec.trustBundle` field + of ClusterTrustBundle objects in an auto-updating file. + + + Alpha, gated by the ClusterTrustBundleProjection feature gate. + + + ClusterTrustBundle objects can either be selected by name, or by the + combination of signer name and a label selector. + + + Kubelet performs aggressive normalization of the PEM contents written + into the pod filesystem. Esoteric PEM features such as inter-block + comments and block headers are stripped. Certificates are deduplicated. + The ordering of certificates within the file is arbitrary, and Kubelet + may change the order over time. + properties: + labelSelector: + description: |- + Select all ClusterTrustBundles that match this label selector. Only has + effect if signerName is set. Mutually-exclusive with name. If unset, + interpreted as "match nothing". If set but empty, interpreted as "match + everything". + properties: + matchExpressions: + description: matchExpressions + is a list of label selector + requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is + the label key that + the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + name: + description: |- + Select a single ClusterTrustBundle by object name. Mutually-exclusive + with signerName and labelSelector. + type: string + optional: + description: |- + If true, don't block pod startup if the referenced ClusterTrustBundle(s) + aren't available. If using name, then the named ClusterTrustBundle is + allowed not to exist. If using signerName, then the combination of + signerName and labelSelector is allowed to match zero + ClusterTrustBundles. + type: boolean + path: + description: Relative path from + the volume root to write the + bundle. + type: string + signerName: + description: |- + Select all ClusterTrustBundles that match this signer name. + Mutually-exclusive with name. The contents of all selected + ClusterTrustBundles will be unified and deduplicated. + type: string + required: + - path + type: object + configMap: + description: configMap information + about the configMap data to project + properties: + items: + description: |- + items if unspecified, each key-value pair in the Data field of the referenced + ConfigMap will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the ConfigMap, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key + to a path within a volume. + properties: + key: + description: key is the + key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + 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 + optional: + description: optional specify + whether the ConfigMap or its + keys must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + downwardAPI: + description: downwardAPI information + about the downwardAPI data to project + properties: + items: + description: Items is a list of + DownwardAPIVolume file + items: + description: DownwardAPIVolumeFile + represents information to + create the file containing + the pod field + properties: + fieldRef: + description: 'Required: + Selects a field of the + pod: only annotations, + labels, name and namespace + are supported.' + properties: + apiVersion: + description: Version + of the schema the + FieldPath is written + in terms of, defaults + to "v1". + type: string + fieldPath: + description: Path of + the field to select + in the specified API + version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + description: |- + Optional: mode bits used to set permissions on this file, must be an octal value + between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: 'Required: + Path is the relative + path name of the file + to be created. Must not + be absolute or contain + the ''..'' path. Must + be utf-8 encoded. The + first item of the relative + path must not start with + ''..''' + type: string + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported. + properties: + containerName: + description: 'Container + name: required for + volumes, optional + for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies + the output format + of the exposed resources, + defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: + resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + type: object + secret: + description: secret information about + the secret data to project + properties: + items: + description: |- + items if unspecified, each key-value pair in the Data field of the referenced + Secret will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the Secret, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key + to a path within a volume. + properties: + key: + description: key is the + key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + 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 + optional: + description: optional field specify + whether the Secret or its key + must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + serviceAccountToken: + description: serviceAccountToken is + information about the serviceAccountToken + data to project + properties: + audience: + description: |- + audience is the intended audience of the token. A recipient of a token + must identify itself with an identifier specified in the audience of the + token, and otherwise should reject the token. The audience defaults to the + identifier of the apiserver. + type: string + expirationSeconds: + description: |- + expirationSeconds is the requested duration of validity of the service + account token. As the token approaches expiration, the kubelet volume + plugin will proactively rotate the service account token. The kubelet will + start trying to rotate the token if the token is older than 80 percent of + its time to live or if the token is older than 24 hours.Defaults to 1 hour + and must be at least 10 minutes. + format: int64 + type: integer + path: + description: |- + path is the path relative to the mount point of the file to project the + token into. + type: string + required: + - path + type: object + type: object + type: array + type: object + quobyte: + description: quobyte represents a Quobyte mount + on the host that shares a pod's lifetime + properties: + group: + description: |- + group to map volume access to + Default is no group + type: string + readOnly: + description: |- + readOnly here will force the Quobyte volume to be mounted with read-only permissions. + Defaults to false. + type: boolean + registry: + description: |- + registry represents a single or multiple Quobyte Registry services + specified as a string as host:port pair (multiple entries are separated with commas) + which acts as the central registry for volumes + type: string + tenant: + description: |- + tenant owning the given Quobyte volume in the Backend + Used with dynamically provisioned Quobyte volumes, value is set by the plugin + type: string + user: + description: |- + user to map volume access to + Defaults to serivceaccount user + type: string + volume: + description: volume is a string that references + an already created Quobyte volume by name. + type: string + required: + - registry + - volume + type: object + rbd: + description: |- + rbd represents a Rados Block Device mount on the host that shares a pod's lifetime. + More info: https://examples.k8s.io/volumes/rbd/README.md + properties: + fsType: + description: |- + fsType is the filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#rbd + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + image: + description: |- + image is the rados image name. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + keyring: + description: |- + keyring is the path to key ring for RBDUser. + Default is /etc/ceph/keyring. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + monitors: + description: |- + monitors is a collection of Ceph monitors. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + items: + type: string + type: array + pool: + description: |- + pool is the rados pool name. + Default is rbd. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + readOnly: + description: |- + readOnly here will force the ReadOnly setting in VolumeMounts. + Defaults to false. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: boolean + secretRef: + description: |- + secretRef is name of the authentication secret for RBDUser. If provided + overrides keyring. + Default is nil. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + 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 + user: + description: |- + user is the rados user name. + Default is admin. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + required: + - image + - monitors + type: object + scaleIO: + description: scaleIO represents a ScaleIO persistent + volume attached and mounted on Kubernetes + nodes. + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". + Default is "xfs". + type: string + gateway: + description: gateway is the host address + of the ScaleIO API Gateway. + type: string + protectionDomain: + description: protectionDomain is the name + of the ScaleIO Protection Domain for the + configured storage. + type: string + readOnly: + description: |- + readOnly Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: |- + secretRef references to the secret for ScaleIO user and other + sensitive information. If this is not provided, Login operation will fail. + 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 + sslEnabled: + description: sslEnabled Flag enable/disable + SSL communication with Gateway, default + false + type: boolean + storageMode: + description: |- + storageMode indicates whether the storage for a volume should be ThickProvisioned or ThinProvisioned. + Default is ThinProvisioned. + type: string + storagePool: + description: storagePool is the ScaleIO + Storage Pool associated with the protection + domain. + type: string + system: + description: system is the name of the storage + system as configured in ScaleIO. + type: string + volumeName: + description: |- + volumeName is the name of a volume already created in the ScaleIO system + that is associated with this volume source. + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + description: |- + secret represents a secret that should populate this volume. + More info: https://kubernetes.io/docs/concepts/storage/volumes#secret + properties: + defaultMode: + description: |- + defaultMode is Optional: mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values + for mode bits. Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + items: + description: |- + items If unspecified, each key-value pair in the Data field of the referenced + Secret will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the Secret, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path + within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + optional: + description: optional field specify whether + the Secret or its keys must be defined + type: boolean + secretName: + description: |- + secretName is the name of the secret in the pod's namespace to use. + More info: https://kubernetes.io/docs/concepts/storage/volumes#secret + type: string + type: object + storageos: + description: storageOS represents a StorageOS + volume attached and mounted on Kubernetes + nodes. + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: |- + secretRef specifies the secret to use for obtaining the StorageOS API + credentials. If not specified, default values will be attempted. + 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 + volumeName: + description: |- + volumeName is the human-readable name of the StorageOS volume. Volume + names are only unique within a namespace. + type: string + volumeNamespace: + description: |- + volumeNamespace specifies the scope of the volume within StorageOS. If no + namespace is specified then the Pod's namespace will be used. This allows the + Kubernetes name scoping to be mirrored within StorageOS for tighter integration. + Set VolumeName to any name to override the default behaviour. + Set to "default" if you are not using namespaces within StorageOS. + Namespaces that do not pre-exist within StorageOS will be created. + type: string + type: object + vsphereVolume: + description: vsphereVolume represents a vSphere + volume attached and mounted on kubelets host + machine + properties: + fsType: + description: |- + fsType is filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + storagePolicyID: + description: storagePolicyID is the storage + Policy Based Management (SPBM) profile + ID associated with the StoragePolicyName. + type: string + storagePolicyName: + description: storagePolicyName is the storage + Policy Based Management (SPBM) profile + name. + type: string + volumePath: + description: volumePath is the path that + identifies vSphere volume vmdk + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + issuer: + description: |- + Specifies the configuration for the TLS certificates issuer. + It allows defining the issuer name and the reference to the secret containing the TLS certificates and key. + The secret should contain the CA certificate, TLS certificate, and private key in the specified keys. + Required when TLS is enabled. + properties: + name: + allOf: + - enum: + - KubeBlocks + - UserProvided + - enum: + - KubeBlocks + - UserProvided + default: KubeBlocks + description: |- + The issuer for TLS certificates. + It only allows two enum values: `KubeBlocks` and `UserProvided`. + + + - `KubeBlocks` indicates that the self-signed TLS certificates generated by the KubeBlocks Operator will be used. + - `UserProvided` means that the user is responsible for providing their own CA, Cert, and Key. + In this case, the user-provided CA certificate, server certificate, and private key will be used + for TLS communication. + type: string + secretRef: + description: |- + SecretRef is the reference to the secret that contains user-provided certificates. + It is required when the issuer is set to `UserProvided`. + properties: + ca: + description: Key of CA cert in Secret + type: string + cert: + description: Key of Cert in Secret + type: string + key: + description: Key of TLS private key in Secret + type: string + name: + description: Name of the Secret that contains user-provided + certificates. + type: string + required: + - ca + - cert + - key + - name + type: object + required: + - name + type: object + labels: + additionalProperties: + type: string + description: Specifies Labels to override or add for underlying + Pods. + type: object + monitor: + description: |- + Deprecated since v0.9 + Determines whether metrics exporter information is annotated on the Component's headless Service. + + + If set to true, the following annotations will be patched into the Service: + + + - "monitor.kubeblocks.io/path" + - "monitor.kubeblocks.io/port" + - "monitor.kubeblocks.io/scheme" + + + These annotations allow the Prometheus installed by KubeBlocks to discover and scrape metrics from the exporter. + type: boolean + name: + description: |- + Specifies the Component's name. + It's part of the Service DNS name and must comply with the IANA service naming rule. + The name is optional when ClusterComponentSpec is used as a template (e.g., in `shardingSpec`), + but required otherwise. + + + TODO +kubebuilder:validation:XValidation:rule="self == oldSelf",message="name is immutable" + maxLength: 22 + pattern: ^[a-z]([a-z0-9\-]*[a-z0-9])?$ + type: string + offlineInstances: + description: |- + Specifies the names of instances to be transitioned to offline status. + + + Marking an instance as offline results in the following: + + + 1. The associated Pod is stopped, and its PersistentVolumeClaim (PVC) is retained for potential + future reuse or data recovery, but it is no longer actively used. + 2. The ordinal number assigned to this instance is preserved, ensuring it remains unique + and avoiding conflicts with new instances. + + + Setting instances to offline allows for a controlled scale-in process, preserving their data and maintaining + ordinal consistency within the Cluster. + Note that offline instances and their associated resources, such as PVCs, are not automatically deleted. + The administrator must manually manage the cleanup and removal of these resources when they are no longer needed. + items: + type: string + type: array + parallelPodManagementConcurrency: + anyOf: + - type: integer + - type: string + description: |- + Controls the concurrency of pods during initial scale up, when replacing pods on nodes, + or when scaling down. It only used when `PodManagementPolicy` is set to `Parallel`. + The default Concurrency is 100%. + x-kubernetes-int-or-string: true + podUpdatePolicy: + description: |- + PodUpdatePolicy indicates how pods should be updated + + + - `StrictInPlace` indicates that only allows in-place upgrades. + Any attempt to modify other fields will be rejected. + - `PreferInPlace` indicates that we will first attempt an in-place upgrade of the Pod. + If that fails, it will fall back to the ReCreate, where pod will be recreated. + Default value is "PreferInPlace" + enum: + - StrictInPlace + - PreferInPlace + type: string + replicas: + default: 1 + description: Specifies the desired number of replicas in + the Component for enhancing availability and durability, + or load balancing. + format: int32 + minimum: 0 + type: integer + resources: + description: |- + Specifies the resources required by the Component. + It allows defining the CPU, memory requirements and limits for the Component's containers. + properties: + claims: + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + + + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + + + This field is immutable. It can only be set for containers. + items: + description: ResourceClaim references one entry in + PodSpec.ResourceClaims. + properties: + name: + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + x-kubernetes-preserve-unknown-fields: true + schedulingPolicy: + description: Specifies the scheduling policy for the Component. + properties: + affinity: + description: Specifies a group of affinity scheduling + rules of the Cluster, including NodeAffinity, PodAffinity, + and PodAntiAffinity. + properties: + nodeAffinity: + description: Describes node affinity scheduling + rules for the pod. + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node matches the corresponding matchExpressions; the + node(s) with the highest sum are the most preferred. + items: + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). + properties: + preference: + description: A node selector term, associated + with the corresponding weight. + properties: + matchExpressions: + description: A list of node selector + requirements by node's labels. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that + the selector applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector + requirements by node's fields. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that + the selector applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + weight: + description: Weight associated with matching + the corresponding nodeSelectorTerm, + in the range 1-100. + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. + properties: + nodeSelectorTerms: + description: Required. A list of node selector + terms. The terms are ORed. + items: + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. + properties: + matchExpressions: + description: A list of node selector + requirements by node's labels. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that + the selector applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector + requirements by node's fields. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that + the selector applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + type: array + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + description: Describes pod affinity scheduling rules + (e.g. co-locate this pod in the same node, zone, + etc. as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched + WeightedPodAffinityTerm fields are added + per-node to find the most preferred node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity + term, associated with the corresponding + weight. + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions + is a list of label selector + requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the + label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. + Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions + is a list of label selector + requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the + label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: |- + weight associated with matching the corresponding podAffinityTerm, + in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. + items: + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a + list of label selector requirements. + The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. + Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a + list of label selector requirements. + The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + description: Describes pod anti-affinity scheduling + rules (e.g. avoid putting this pod in the same + node, zone, etc. as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the anti-affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched + WeightedPodAffinityTerm fields are added + per-node to find the most preferred node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity + term, associated with the corresponding + weight. + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions + is a list of label selector + requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the + label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. + Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions + is a list of label selector + requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the + label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: |- + weight associated with matching the corresponding podAffinityTerm, + in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the anti-affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the anti-affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. + items: + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a + list of label selector requirements. + The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. + Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a + list of label selector requirements. + The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + nodeName: + description: |- + NodeName is a request to schedule this Pod onto a specific node. If it is non-empty, + the scheduler simply schedules this Pod onto that node, assuming that it fits resource + requirements. + type: string + nodeSelector: + additionalProperties: + type: string + description: |- + NodeSelector is a selector which must be true for the Pod to fit on a node. + Selector which must match a node's labels for the Pod to be scheduled on that node. + More info: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ + type: object + x-kubernetes-map-type: atomic + schedulerName: + description: |- + If specified, the Pod will be dispatched by specified scheduler. + If not specified, the Pod will be dispatched by default scheduler. + type: string + tolerations: + description: |- + Allows Pods to be scheduled onto nodes with matching taints. + Each toleration in the array allows the Pod to tolerate node taints based on + specified `key`, `value`, `effect`, and `operator`. + + + - The `key`, `value`, and `effect` identify the taint that the toleration matches. + - The `operator` determines how the toleration matches the taint. + + + Pods with matching tolerations are allowed to be scheduled on tainted nodes, typically reserved for specific purposes. + items: + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . + properties: + effect: + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. + type: string + operator: + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. + type: string + tolerationSeconds: + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. + format: int64 + type: integer + value: + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. + type: string + type: object + type: array + topologySpreadConstraints: + description: |- + TopologySpreadConstraints describes how a group of Pods ought to spread across topology + domains. Scheduler will schedule Pods in a way which abides by the constraints. + All topologySpreadConstraints are ANDed. + items: + description: TopologySpreadConstraint specifies how + to spread matching pods among the given topology. + properties: + labelSelector: + description: |- + LabelSelector is used to find matching pods. + Pods that match this label selector are counted to determine the number of pods + in their corresponding topology domain. + properties: + matchExpressions: + description: matchExpressions is a list of + label selector requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select the pods over which + spreading will be calculated. The keys are used to lookup values from the + incoming pod labels, those key-value labels are ANDed with labelSelector + to select the group of existing pods over which spreading will be calculated + for the incoming pod. The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + MatchLabelKeys cannot be set when LabelSelector isn't set. + Keys that don't exist in the incoming pod labels will + be ignored. A null or empty list means only match against labelSelector. + + + This is a beta field and requires the MatchLabelKeysInPodTopologySpread feature gate to be enabled (enabled by default). + items: + type: string + type: array + x-kubernetes-list-type: atomic + maxSkew: + description: |- + MaxSkew describes the degree to which pods may be unevenly distributed. + When `whenUnsatisfiable=DoNotSchedule`, it is the maximum permitted difference + between the number of matching pods in the target topology and the global minimum. + The global minimum is the minimum number of matching pods in an eligible domain + or zero if the number of eligible domains is less than MinDomains. + For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same + labelSelector spread as 2/2/1: + In this case, the global minimum is 1. + | zone1 | zone2 | zone3 | + | P P | P P | P | + - if MaxSkew is 1, incoming pod can only be scheduled to zone3 to become 2/2/2; + scheduling it onto zone1(zone2) would make the ActualSkew(3-1) on zone1(zone2) + violate MaxSkew(1). + - if MaxSkew is 2, incoming pod can be scheduled onto any zone. + When `whenUnsatisfiable=ScheduleAnyway`, it is used to give higher precedence + to topologies that satisfy it. + It's a required field. Default value is 1 and 0 is not allowed. + format: int32 + type: integer + minDomains: + description: |- + MinDomains indicates a minimum number of eligible domains. + When the number of eligible domains with matching topology keys is less than minDomains, + Pod Topology Spread treats "global minimum" as 0, and then the calculation of Skew is performed. + And when the number of eligible domains with matching topology keys equals or greater than minDomains, + this value has no effect on scheduling. + As a result, when the number of eligible domains is less than minDomains, + scheduler won't schedule more than maxSkew Pods to those domains. + If value is nil, the constraint behaves as if MinDomains is equal to 1. + Valid values are integers greater than 0. + When value is not nil, WhenUnsatisfiable must be DoNotSchedule. + + + For example, in a 3-zone cluster, MaxSkew is set to 2, MinDomains is set to 5 and pods with the same + labelSelector spread as 2/2/2: + | zone1 | zone2 | zone3 | + | P P | P P | P P | + The number of domains is less than 5(MinDomains), so "global minimum" is treated as 0. + In this situation, new pod with the same labelSelector cannot be scheduled, + because computed skew will be 3(3 - 0) if new Pod is scheduled to any of the three zones, + it will violate MaxSkew. + + + This is a beta field and requires the MinDomainsInPodTopologySpread feature gate to be enabled (enabled by default). + format: int32 + type: integer + nodeAffinityPolicy: + description: |- + NodeAffinityPolicy indicates how we will treat Pod's nodeAffinity/nodeSelector + when calculating pod topology spread skew. Options are: + - Honor: only nodes matching nodeAffinity/nodeSelector are included in the calculations. + - Ignore: nodeAffinity/nodeSelector are ignored. All nodes are included in the calculations. + + + If this value is nil, the behavior is equivalent to the Honor policy. + This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag. + type: string + nodeTaintsPolicy: + description: |- + NodeTaintsPolicy indicates how we will treat node taints when calculating + pod topology spread skew. Options are: + - Honor: nodes without taints, along with tainted nodes for which the incoming pod + has a toleration, are included. + - Ignore: node taints are ignored. All nodes are included. + + + If this value is nil, the behavior is equivalent to the Ignore policy. + This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag. + type: string + topologyKey: + description: |- + TopologyKey is the key of node labels. Nodes that have a label with this key + and identical values are considered to be in the same topology. + We consider each as a "bucket", and try to put balanced number + of pods into each bucket. + We define a domain as a particular instance of a topology. + Also, we define an eligible domain as a domain whose nodes meet the requirements of + nodeAffinityPolicy and nodeTaintsPolicy. + e.g. If TopologyKey is "kubernetes.io/hostname", each Node is a domain of that topology. + And, if TopologyKey is "topology.kubernetes.io/zone", each zone is a domain of that topology. + It's a required field. + type: string + whenUnsatisfiable: + description: |- + WhenUnsatisfiable indicates how to deal with a pod if it doesn't satisfy + the spread constraint. + - DoNotSchedule (default) tells the scheduler not to schedule it. + - ScheduleAnyway tells the scheduler to schedule the pod in any location, + but giving higher precedence to topologies that would help reduce the + skew. + A constraint is considered "Unsatisfiable" for an incoming pod + if and only if every possible node assignment for that pod would violate + "MaxSkew" on some topology. + For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same + labelSelector spread as 3/1/1: + | zone1 | zone2 | zone3 | + | P P P | P | P | + If WhenUnsatisfiable is set to DoNotSchedule, incoming pod can only be scheduled + to zone2(zone3) to become 3/2/1(3/1/2) as ActualSkew(2-1) on zone2(zone3) satisfies + MaxSkew(1). In other words, the cluster can still be imbalanced, but scheduler + won't make it *more* imbalanced. + It's a required field. + type: string + required: + - maxSkew + - topologyKey + - whenUnsatisfiable + type: object + type: array + type: object + serviceAccountName: + description: |- + Specifies the name of the ServiceAccount required by the running Component. + This ServiceAccount is used to grant necessary permissions for the Component's Pods to interact + with other Kubernetes resources, such as modifying Pod labels or sending events. + + + Defaults: + To perform certain operational tasks, agent sidecars running in Pods require specific RBAC permissions. + The service account will be bound to a default role named "kubeblocks-cluster-pod-role" which is installed together with KubeBlocks. + If not specified, KubeBlocks automatically assigns a default ServiceAccount named "kb-{cluster.name}" + + + Future Changes: + Future versions might change the default ServiceAccount creation strategy to one per Component, + potentially revising the naming to "kb-{cluster.name}-{component.name}". + + + Users can override the automatic ServiceAccount assignment by explicitly setting the name of + an existed ServiceAccount in this field. + type: string + serviceRefs: + description: |- + Defines a list of ServiceRef for a Component, enabling access to both external services and + Services provided by other Clusters. + + + Types of services: + + + - External services: Not managed by KubeBlocks or managed by a different KubeBlocks operator; + Require a ServiceDescriptor for connection details. + - Services provided by a Cluster: Managed by the same KubeBlocks operator; + identified using Cluster, Component and Service names. + + + ServiceRefs with identical `serviceRef.name` in the same Cluster are considered the same. + + + Example: + ```yaml + serviceRefs: + - name: "redis-sentinel" + serviceDescriptor: + name: "external-redis-sentinel" + - name: "postgres-cluster" + clusterServiceSelector: + cluster: "my-postgres-cluster" + service: + component: "postgresql" + ``` + The example above includes ServiceRefs to an external Redis Sentinel service and a PostgreSQL Cluster. + items: + properties: + cluster: + description: |- + Specifies the name of the KubeBlocks Cluster being referenced. + This is used when services from another KubeBlocks Cluster are consumed. + + + By default, the referenced KubeBlocks Cluster's `clusterDefinition.spec.connectionCredential` + will be utilized to bind to the current Component. This credential should include: + `endpoint`, `port`, `username`, and `password`. + + + Note: + + + - The `ServiceKind` and `ServiceVersion` specified in the service reference within the + ClusterDefinition are not validated when using this approach. + - If both `cluster` and `serviceDescriptor` are present, `cluster` will take precedence. + + + Deprecated since v0.9 since `clusterDefinition.spec.connectionCredential` is deprecated, + use `clusterServiceSelector` instead. + This field is maintained for backward compatibility and its use is discouraged. + Existing usage should be updated to the current preferred approach to avoid compatibility issues in future releases. + type: string + clusterServiceSelector: + description: |- + References a service provided by another KubeBlocks Cluster. + It specifies the ClusterService and the account credentials needed for access. + properties: + cluster: + description: The name of the Cluster being referenced. + type: string + credential: + description: |- + Specifies the SystemAccount to authenticate and establish a connection with the referenced Cluster. + The SystemAccount should be defined in `componentDefinition.spec.systemAccounts` + of the Component providing the service in the referenced Cluster. + properties: + component: + description: The name of the Component where + the credential resides in. + type: string + name: + description: The name of the credential (SystemAccount) + to reference. + type: string + required: + - component + - name + type: object + service: + description: Identifies a ClusterService from + the list of Services defined in `cluster.spec.services` + of the referenced Cluster. + properties: + component: + description: |- + The name of the Component where the Service resides in. + + + It is required when referencing a Component's Service. + type: string + port: + description: |- + The port name of the Service to be referenced. + + + If there is a non-zero node-port exist for the matched Service port, the node-port will be selected first. + + + If the referenced Service is of pod-service type (a Service per Pod), there will be multiple Service objects matched, + and the resolved value will be presented in the following format: service1.name:port1,service2.name:port2... + type: string + service: + description: |- + The name of the Service to be referenced. + + + Leave it empty to reference the default Service. Set it to "headless" to reference the default headless Service. + + + If the referenced Service is of pod-service type (a Service per Pod), there will be multiple Service objects matched, + and the resolved value will be presented in the following format: service1.name,service2.name... + type: string + required: + - service + type: object + required: + - cluster + type: object + name: + description: |- + Specifies the identifier of the service reference declaration. + It corresponds to the serviceRefDeclaration name defined in either: + + + - `componentDefinition.spec.serviceRefDeclarations[*].name` + - `clusterDefinition.spec.componentDefs[*].serviceRefDeclarations[*].name` (deprecated) + type: string + namespace: + description: |- + Specifies the namespace of the referenced Cluster or the namespace of the referenced ServiceDescriptor object. + If not provided, the referenced Cluster and ServiceDescriptor will be searched in the namespace of the current + Cluster by default. + type: string + serviceDescriptor: + description: |- + Specifies the name of the ServiceDescriptor object that describes a service provided by external sources. + + + When referencing a service provided by external sources, a ServiceDescriptor object is required to establish + the service binding. + The `serviceDescriptor.spec.serviceKind` and `serviceDescriptor.spec.serviceVersion` should match the serviceKind + and serviceVersion declared in the definition. + + + If both `cluster` and `serviceDescriptor` are specified, the `cluster` takes precedence. + type: string + required: + - name + type: object + type: array + serviceVersion: + description: |- + ServiceVersion specifies the version of the Service expected to be provisioned by this Component. + The version should follow the syntax and semantics of the "Semantic Versioning" specification (http://semver.org/). + If no version is specified, the latest available version will be used. + maxLength: 32 + type: string + services: + description: Overrides services defined in referenced ComponentDefinition + and expose endpoints that can be accessed by clients. + items: + properties: + annotations: + additionalProperties: + type: string + description: |- + If ServiceType is LoadBalancer, cloud provider related parameters can be put here. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#loadbalancer. + type: object + name: + description: References the ComponentService name + defined in the `componentDefinition.spec.services[*].name`. + maxLength: 25 + type: string + podService: + description: |- + Indicates whether to generate individual Services for each Pod. + If set to true, a separate Service will be created for each Pod in the Cluster. + type: boolean + serviceType: + default: ClusterIP + description: |- + Determines how the Service is exposed. Valid options are `ClusterIP`, `NodePort`, and `LoadBalancer`. + + + - `ClusterIP` allocates a Cluster-internal IP address for load-balancing to endpoints. + Endpoints are determined by the selector or if that is not specified, + they are determined by manual construction of an Endpoints object or EndpointSlice objects. + - `NodePort` builds on ClusterIP and allocates a port on every node which routes to the same endpoints as the ClusterIP. + - `LoadBalancer` builds on NodePort and creates an external load-balancer (if supported in the current cloud) + which routes to the same endpoints as the ClusterIP. + + + Note: although K8s Service type allows the 'ExternalName' type, it is not a valid option for ClusterComponentService. + + + For more info, see: + https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types. + enum: + - ClusterIP + - NodePort + - LoadBalancer + type: string + x-kubernetes-preserve-unknown-fields: true + required: + - name + type: object + type: array + stop: + description: |- + Stop the Component. + If set, all the computing resources will be released. + type: boolean + systemAccounts: + description: Overrides system accounts defined in referenced + ComponentDefinition. + items: + properties: + name: + description: The name of the system account. + type: string + passwordConfig: + description: |- + Specifies the policy for generating the account's password. + + + This field is immutable once set. + properties: + length: + default: 16 + description: The length of the password. + format: int32 + maximum: 32 + minimum: 8 + type: integer + letterCase: + default: MixedCases + description: The case of the letters in the password. + enum: + - LowerCases + - UpperCases + - MixedCases + type: string + numDigits: + default: 4 + description: The number of digits in the password. + format: int32 + maximum: 8 + minimum: 0 + type: integer + numSymbols: + default: 0 + description: The number of symbols in the password. + format: int32 + maximum: 8 + minimum: 0 + type: integer + seed: + description: |- + Seed to generate the account's password. + Cannot be updated. + type: string + type: object + secretRef: + description: |- + Refers to the secret from which data will be copied to create the new account. + + + This field is immutable once set. + properties: + name: + description: The unique identifier of the secret. + type: string + namespace: + description: The namespace where the secret is + located. + type: string + required: + - name + - namespace + type: object + required: + - name + type: object + type: array + tls: + description: |- + A boolean flag that indicates whether the Component should use Transport Layer Security (TLS) + for secure communication. + When set to true, the Component will be configured to use TLS encryption for its network connections. + This ensures that the data transmitted between the Component and its clients or other Components is encrypted + and protected from unauthorized access. + If TLS is enabled, the Component may require additional configuration, such as specifying TLS certificates and keys, + to properly set up the secure communication channel. + type: boolean + updateStrategy: + description: |- + Defines the update strategy for the Component. + + + Deprecated since v0.9. + This field is maintained for backward compatibility and its use is discouraged. + Existing usage should be updated to the current preferred approach to avoid compatibility issues in future releases. + enum: + - Serial + - BestEffortParallel + - Parallel + type: string + userResourceRefs: + description: |- + Allows users to specify custom ConfigMaps and Secrets to be mounted as volumes + in the Cluster's Pods. + This is useful in scenarios where users need to provide additional resources to the Cluster, such as: + + + - Mounting custom scripts or configuration files during Cluster startup. + - Mounting Secrets as volumes to provide sensitive information, like S3 AK/SK, to the Cluster. + properties: + configMapRefs: + description: ConfigMapRefs defines the user-defined + ConfigMaps. + items: + description: ConfigMapRef defines a reference to a + ConfigMap. + properties: + asVolumeFrom: + description: AsVolumeFrom lists the names of containers + in which the volume should be mounted. + items: + type: string + type: array + x-kubernetes-list-type: set + configMap: + description: ConfigMap specifies the ConfigMap + to be mounted as a volume. + properties: + defaultMode: + description: |- + defaultMode is optional: mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + items: + description: |- + items if unspecified, each key-value pair in the Data field of the referenced + ConfigMap will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the ConfigMap, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path + within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + 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 + optional: + description: optional specify whether the + ConfigMap or its keys must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + mountPoint: + description: MountPoint is the filesystem path + where the volume will be mounted. + maxLength: 256 + pattern: ^/[a-z]([a-z0-9\-]*[a-z0-9])?$ + type: string + name: + description: Name is the name of the referenced + ConfigMap or Secret object. It must conform + to DNS label standards. + maxLength: 63 + pattern: ^[a-z0-9]([a-z0-9\.\-]*[a-z0-9])?$ + type: string + subPath: + description: SubPath specifies a path within the + volume from which to mount. + type: string + required: + - configMap + - mountPoint + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + secretRefs: + description: SecretRefs defines the user-defined Secrets. + items: + description: SecretRef defines a reference to a Secret. + properties: + asVolumeFrom: + description: AsVolumeFrom lists the names of containers + in which the volume should be mounted. + items: + type: string + type: array + x-kubernetes-list-type: set + mountPoint: + description: MountPoint is the filesystem path + where the volume will be mounted. + maxLength: 256 + pattern: ^/[a-z]([a-z0-9\-]*[a-z0-9])?$ + type: string + name: + description: Name is the name of the referenced + ConfigMap or Secret object. It must conform + to DNS label standards. + maxLength: 63 + pattern: ^[a-z0-9]([a-z0-9\.\-]*[a-z0-9])?$ + type: string + secret: + description: Secret specifies the Secret to be + mounted as a volume. + properties: + defaultMode: + description: |- + defaultMode is Optional: mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values + for mode bits. Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + items: + description: |- + items If unspecified, each key-value pair in the Data field of the referenced + Secret will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the Secret, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path + within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + optional: + description: optional field specify whether + the Secret or its keys must be defined + type: boolean + secretName: + description: |- + secretName is the name of the secret in the pod's namespace to use. + More info: https://kubernetes.io/docs/concepts/storage/volumes#secret + type: string + type: object + subPath: + description: SubPath specifies a path within the + volume from which to mount. + type: string + required: + - mountPoint + - name + - secret + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + volumeClaimTemplates: + description: |- + Specifies a list of PersistentVolumeClaim templates that represent the storage requirements for the Component. + Each template specifies the desired characteristics of a persistent volume, such as storage class, + size, and access modes. + These templates are used to dynamically provision persistent volumes for the Component. + items: + properties: + name: + description: |- + Refers to the name of a volumeMount defined in either: + + + - `componentDefinition.spec.runtime.containers[*].volumeMounts` + - `clusterDefinition.spec.componentDefs[*].podSpec.containers[*].volumeMounts` (deprecated) + + + The value of `name` must match the `name` field of a volumeMount specified in the corresponding `volumeMounts` array. + type: string + spec: + description: |- + Defines the desired characteristics of a PersistentVolumeClaim that will be created for the volume + with the mount name specified in the `name` field. + + + When a Pod is created for this ClusterComponent, a new PVC will be created based on the specification + defined in the `spec` field. The PVC will be associated with the volume mount specified by the `name` field. + properties: + accessModes: + description: |- + Contains the desired access modes the volume should have. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1. + items: + type: string + type: array + x-kubernetes-preserve-unknown-fields: true + resources: + description: |- + Represents the minimum resources the volume should have. + If the RecoverVolumeExpansionFailure feature is enabled, users are allowed to specify resource requirements that + are lower than the previous value but must still be higher than the capacity recorded in the status field of the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources. + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + x-kubernetes-preserve-unknown-fields: true + storageClassName: + description: |- + The name of the StorageClass required by the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1. + type: string + volumeMode: + description: Defines what type of volume is required + by the claim, either Block or Filesystem. + type: string + type: object + required: + - name + type: object + type: array + volumes: + description: List of volumes to override. + items: + description: Volume represents a named volume in a pod + that may be accessed by any container in the pod. + properties: + awsElasticBlockStore: + description: |- + awsElasticBlockStore represents an AWS Disk resource that is attached to a + kubelet's host machine and then exposed to the pod. + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + properties: + fsType: + description: |- + fsType is the filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + partition: + description: |- + partition is the partition in the volume that you want to mount. + If omitted, the default is to mount by volume name. + Examples: For volume /dev/sda1, you specify the partition as "1". + Similarly, the volume partition for /dev/sda is "0" (or you can leave the property empty). + format: int32 + type: integer + readOnly: + description: |- + readOnly value true will force the readOnly setting in VolumeMounts. + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + type: boolean + volumeID: + description: |- + volumeID is unique ID of the persistent disk resource in AWS (Amazon EBS volume). + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + type: string + required: + - volumeID + type: object + azureDisk: + description: azureDisk represents an Azure Data Disk + mount on the host and bind mount to the pod. + properties: + cachingMode: + description: 'cachingMode is the Host Caching + mode: None, Read Only, Read Write.' + type: string + diskName: + description: diskName is the Name of the data + disk in the blob storage + type: string + diskURI: + description: diskURI is the URI of data disk in + the blob storage + type: string + fsType: + description: |- + fsType is Filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + kind: + description: 'kind expected values are Shared: + multiple blob disks per storage account Dedicated: + single blob disk per storage account Managed: + azure managed data disk (only in managed availability + set). defaults to shared' + type: string + readOnly: + description: |- + readOnly Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + description: azureFile represents an Azure File Service + mount on the host and bind mount to the pod. + properties: + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretName: + description: secretName is the name of secret + that contains Azure Storage Account Name and + Key + type: string + shareName: + description: shareName is the azure share Name + type: string + required: + - secretName + - shareName + type: object + cephfs: + description: cephFS represents a Ceph FS mount on + the host that shares a pod's lifetime + properties: + monitors: + description: |- + monitors is Required: Monitors is a collection of Ceph monitors + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + items: + type: string + type: array + path: + description: 'path is Optional: Used as the mounted + root, rather than the full Ceph tree, default + is /' + type: string + readOnly: + description: |- + readOnly is Optional: Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + type: boolean + secretFile: + description: |- + secretFile is Optional: SecretFile is the path to key ring for User, default is /etc/ceph/user.secret + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + type: string + secretRef: + description: |- + secretRef is Optional: SecretRef is reference to the authentication secret for User, default is empty. + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + 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 + user: + description: |- + user is optional: User is the rados user name, default is admin + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + type: string + required: + - monitors + type: object + cinder: + description: |- + cinder represents a cinder volume attached and mounted on kubelets host machine. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + type: string + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + type: boolean + secretRef: + description: |- + secretRef is optional: points to a secret object containing parameters used to connect + to OpenStack. + 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 + volumeID: + description: |- + volumeID used to identify the volume in cinder. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + type: string + required: + - volumeID + type: object + configMap: + description: configMap represents a configMap that + should populate this volume + properties: + defaultMode: + description: |- + defaultMode is optional: mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + items: + description: |- + items if unspecified, each key-value pair in the Data field of the referenced + ConfigMap will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the ConfigMap, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within + a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + 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 + optional: + description: optional specify whether the ConfigMap + or its keys must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + csi: + description: csi (Container Storage Interface) represents + ephemeral storage that is handled by certain external + CSI drivers (Beta feature). + properties: + driver: + description: |- + driver is the name of the CSI driver that handles this volume. + Consult with your admin for the correct name as registered in the cluster. + type: string + fsType: + description: |- + fsType to mount. Ex. "ext4", "xfs", "ntfs". + If not provided, the empty value is passed to the associated CSI driver + which will determine the default filesystem to apply. + type: string + nodePublishSecretRef: + description: |- + nodePublishSecretRef is a reference to the secret object containing + sensitive information to pass to the CSI driver to complete the CSI + NodePublishVolume and NodeUnpublishVolume calls. + This field is optional, and may be empty if no secret is required. If the + secret object contains more than one secret, all secret references are passed. + 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 + readOnly: + description: |- + readOnly specifies a read-only configuration for the volume. + Defaults to false (read/write). + type: boolean + volumeAttributes: + additionalProperties: + type: string + description: |- + volumeAttributes stores driver-specific properties that are passed to the CSI + driver. Consult your driver's documentation for supported values. + type: object + required: + - driver + type: object + downwardAPI: + description: downwardAPI represents downward API about + the pod that should populate this volume + properties: + defaultMode: + description: |- + Optional: mode bits to use on created files by default. Must be a + Optional: mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + items: + description: Items is a list of downward API volume + file + items: + description: DownwardAPIVolumeFile represents + information to create the file containing + the pod field + properties: + fieldRef: + description: 'Required: Selects a field + of the pod: only annotations, labels, + name and namespace are supported.' + properties: + apiVersion: + description: Version of the schema the + FieldPath is written in terms of, + defaults to "v1". + type: string + fieldPath: + description: Path of the field to select + in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + description: |- + Optional: mode bits used to set permissions on this file, must be an octal value + between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: 'Required: Path is the relative + path name of the file to be created. Must + not be absolute or contain the ''..'' + path. Must be utf-8 encoded. The first + item of the relative path must not start + with ''..''' + type: string + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported. + properties: + containerName: + description: 'Container name: required + for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format + of the exposed resources, defaults + to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to + select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + type: object + emptyDir: + description: |- + emptyDir represents a temporary directory that shares a pod's lifetime. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir + properties: + medium: + description: |- + medium represents what type of storage medium should back this directory. + The default is "" which means to use the node's default medium. + Must be an empty string (default) or Memory. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + description: |- + sizeLimit is the total amount of local storage required for this EmptyDir volume. + The size limit is also applicable for memory medium. + The maximum usage on memory medium EmptyDir would be the minimum value between + the SizeLimit specified here and the sum of memory limits of all containers in a pod. + The default is nil which means that the limit is undefined. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + description: |- + ephemeral represents a volume that is handled by a cluster storage driver. + The volume's lifecycle is tied to the pod that defines it - it will be created before the pod starts, + and deleted when the pod is removed. + + + Use this if: + a) the volume is only needed while the pod runs, + b) features of normal volumes like restoring from snapshot or capacity + tracking are needed, + c) the storage driver is specified through a storage class, and + d) the storage driver supports dynamic volume provisioning through + a PersistentVolumeClaim (see EphemeralVolumeSource for more + information on the connection between this volume type + and PersistentVolumeClaim). + + + Use PersistentVolumeClaim or one of the vendor-specific + APIs for volumes that persist for longer than the lifecycle + of an individual pod. + + + Use CSI for light-weight local ephemeral volumes if the CSI driver is meant to + be used that way - see the documentation of the driver for + more information. + + + A pod can use both types of ephemeral volumes and + persistent volumes at the same time. + properties: + volumeClaimTemplate: + description: |- + Will be used to create a stand-alone PVC to provision the volume. + The pod in which this EphemeralVolumeSource is embedded will be the + owner of the PVC, i.e. the PVC will be deleted together with the + pod. The name of the PVC will be `-` where + `` is the name from the `PodSpec.Volumes` array + entry. Pod validation will reject the pod if the concatenated name + is not valid for a PVC (for example, too long). + + + An existing PVC with that name that is not owned by the pod + will *not* be used for the pod to avoid using an unrelated + volume by mistake. Starting the pod is then blocked until + the unrelated PVC is removed. If such a pre-created PVC is + meant to be used by the pod, the PVC has to updated with an + owner reference to the pod once the pod exists. Normally + this should not be necessary, but it may be useful when + manually reconstructing a broken cluster. + + + This field is read-only and no changes will be made by Kubernetes + to the PVC after it has been created. + + + Required, must not be nil. + properties: + metadata: + description: |- + May contain labels and annotations that will be copied into the PVC + when creating it. No other fields are allowed and will be rejected during + validation. + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + description: |- + The specification for the PersistentVolumeClaim. The entire content is + copied unchanged into the PVC that gets created from this + template. The same fields as in a PersistentVolumeClaim + are also valid here. + properties: + accessModes: + description: |- + accessModes contains the desired access modes the volume should have. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1 + items: + type: string + type: array + dataSource: + description: |- + dataSource field can be used to specify either: + * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) + * An existing PVC (PersistentVolumeClaim) + If the provisioner or an external controller can support the specified data source, + it will create a new volume based on the contents of the specified data source. + When the AnyVolumeDataSource feature gate is enabled, dataSource contents will be copied to dataSourceRef, + and dataSourceRef contents will be copied to dataSource when dataSourceRef.namespace is not specified. + If the namespace is specified, then dataSourceRef will not be copied to dataSource. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource + being referenced + type: string + name: + description: Name is the name of resource + being referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + description: |- + dataSourceRef specifies the object from which to populate the volume with data, if a non-empty + volume is desired. This may be any object from a non-empty API group (non + core object) or a PersistentVolumeClaim object. + When this field is specified, volume binding will only succeed if the type of + the specified object matches some installed volume populator or dynamic + provisioner. + This field will replace the functionality of the dataSource field and as such + if both fields are non-empty, they must have the same value. For backwards + compatibility, when namespace isn't specified in dataSourceRef, + both fields (dataSource and dataSourceRef) will be set to the same + value automatically if one of them is empty and the other is non-empty. + When namespace is specified in dataSourceRef, + dataSource isn't set to the same value and must be empty. + There are three important differences between dataSource and dataSourceRef: + * While dataSource only allows two specific types of objects, dataSourceRef + allows any non-core object, as well as PersistentVolumeClaim objects. + * While dataSource ignores disallowed values (dropping them), dataSourceRef + preserves all values, and generates an error if a disallowed value is + specified. + * While dataSource only allows local objects, dataSourceRef allows objects + in any namespaces. + (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled. + (Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource + being referenced + type: string + name: + description: Name is the name of resource + being referenced + type: string + namespace: + description: |- + Namespace is the namespace of resource being referenced + Note that when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details. + (Alpha) This field requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + type: string + required: + - kind + - name + type: object + resources: + description: |- + resources represents the minimum resources the volume should have. + If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements + that are lower than previous value but must still be higher than capacity recorded in the + status field of the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + selector: + description: selector is a label query + over volumes to consider for binding. + properties: + matchExpressions: + description: matchExpressions is a + list of label selector requirements. + The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + description: |- + storageClassName is the name of the StorageClass required by the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1 + type: string + volumeAttributesClassName: + description: |- + volumeAttributesClassName may be used to set the VolumeAttributesClass used by this claim. + If specified, the CSI driver will create or update the volume with the attributes defined + in the corresponding VolumeAttributesClass. This has a different purpose than storageClassName, + it can be changed after the claim is created. An empty string value means that no VolumeAttributesClass + will be applied to the claim but it's not allowed to reset this field to empty string once it is set. + If unspecified and the PersistentVolumeClaim is unbound, the default VolumeAttributesClass + will be set by the persistentvolume controller if it exists. + If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be + set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource + exists. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#volumeattributesclass + (Alpha) Using this field requires the VolumeAttributesClass feature gate to be enabled. + type: string + volumeMode: + description: |- + volumeMode defines what type of volume is required by the claim. + Value of Filesystem is implied when not included in claim spec. + type: string + volumeName: + description: volumeName is the binding + reference to the PersistentVolume backing + this claim. + type: string + type: object + required: + - spec + type: object + type: object + fc: + description: fc represents a Fibre Channel resource + that is attached to a kubelet's host machine and + then exposed to the pod. + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + lun: + description: 'lun is Optional: FC target lun number' + format: int32 + type: integer + readOnly: + description: |- + readOnly is Optional: Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + targetWWNs: + description: 'targetWWNs is Optional: FC target + worldwide names (WWNs)' + items: + type: string + type: array + wwids: + description: |- + wwids Optional: FC volume world wide identifiers (wwids) + Either wwids or combination of targetWWNs and lun must be set, but not both simultaneously. + items: + type: string + type: array + type: object + flexVolume: + description: |- + flexVolume represents a generic volume resource that is + provisioned/attached using an exec based plugin. + properties: + driver: + description: driver is the name of the driver + to use for this volume. + type: string + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". The default filesystem depends on FlexVolume script. + type: string + options: + additionalProperties: + type: string + description: 'options is Optional: this field + holds extra command options if any.' + type: object + readOnly: + description: |- + readOnly is Optional: defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: |- + secretRef is Optional: secretRef is reference to the secret object containing + sensitive information to pass to the plugin scripts. This may be + empty if no secret object is specified. If the secret object + contains more than one secret, all secrets are passed to the plugin + scripts. + 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 + required: + - driver + type: object + flocker: + description: flocker represents a Flocker volume attached + to a kubelet's host machine. This depends on the + Flocker control service being running + properties: + datasetName: + description: |- + datasetName is Name of the dataset stored as metadata -> name on the dataset for Flocker + should be considered as deprecated + type: string + datasetUUID: + description: datasetUUID is the UUID of the dataset. + This is unique identifier of a Flocker dataset + type: string + type: object + gcePersistentDisk: + description: |- + gcePersistentDisk represents a GCE Disk resource that is attached to a + kubelet's host machine and then exposed to the pod. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + properties: + fsType: + description: |- + fsType is filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + partition: + description: |- + partition is the partition in the volume that you want to mount. + If omitted, the default is to mount by volume name. + Examples: For volume /dev/sda1, you specify the partition as "1". + Similarly, the volume partition for /dev/sda is "0" (or you can leave the property empty). + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + format: int32 + type: integer + pdName: + description: |- + pdName is unique name of the PD resource in GCE. Used to identify the disk in GCE. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + type: string + readOnly: + description: |- + readOnly here will force the ReadOnly setting in VolumeMounts. + Defaults to false. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + type: boolean + required: + - pdName + type: object + gitRepo: + description: |- + gitRepo represents a git repository at a particular revision. + DEPRECATED: GitRepo is deprecated. To provision a container with a git repo, mount an + EmptyDir into an InitContainer that clones the repo using git, then mount the EmptyDir + into the Pod's container. + properties: + directory: + description: |- + directory is the target directory name. + Must not contain or start with '..'. If '.' is supplied, the volume directory will be the + git repository. Otherwise, if specified, the volume will contain the git repository in + the subdirectory with the given name. + type: string + repository: + description: repository is the URL + type: string + revision: + description: revision is the commit hash for the + specified revision. + type: string + required: + - repository + type: object + glusterfs: + description: |- + glusterfs represents a Glusterfs mount on the host that shares a pod's lifetime. + More info: https://examples.k8s.io/volumes/glusterfs/README.md + properties: + endpoints: + description: |- + endpoints is the endpoint name that details Glusterfs topology. + More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod + type: string + path: + description: |- + path is the Glusterfs volume path. + More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod + type: string + readOnly: + description: |- + readOnly here will force the Glusterfs volume to be mounted with read-only permissions. + Defaults to false. + More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod + type: boolean + required: + - endpoints + - path + type: object + hostPath: + description: |- + hostPath represents a pre-existing file or directory on the host + machine that is directly exposed to the container. This is generally + used for system agents or other privileged things that are allowed + to see the host machine. Most containers will NOT need this. + More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + --- + TODO(jonesdl) We need to restrict who can use host directory mounts and who can/can not + mount host directories as read/write. + properties: + path: + description: |- + path of the directory on the host. + If the path is a symlink, it will follow the link to the real path. + More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + type: string + type: + description: |- + type for HostPath Volume + Defaults to "" + More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + type: string + required: + - path + type: object + iscsi: + description: |- + iscsi represents an ISCSI Disk resource that is attached to a + kubelet's host machine and then exposed to the pod. + More info: https://examples.k8s.io/volumes/iscsi/README.md + properties: + chapAuthDiscovery: + description: chapAuthDiscovery defines whether + support iSCSI Discovery CHAP authentication + type: boolean + chapAuthSession: + description: chapAuthSession defines whether support + iSCSI Session CHAP authentication + type: boolean + fsType: + description: |- + fsType is the filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#iscsi + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + initiatorName: + description: |- + initiatorName is the custom iSCSI Initiator Name. + If initiatorName is specified with iscsiInterface simultaneously, new iSCSI interface + : will be created for the connection. + type: string + iqn: + description: iqn is the target iSCSI Qualified + Name. + type: string + iscsiInterface: + description: |- + iscsiInterface is the interface Name that uses an iSCSI transport. + Defaults to 'default' (tcp). + type: string + lun: + description: lun represents iSCSI Target Lun number. + format: int32 + type: integer + portals: + description: |- + portals is the iSCSI Target Portal List. The portal is either an IP or ip_addr:port if the port + is other than default (typically TCP ports 860 and 3260). + items: + type: string + type: array + readOnly: + description: |- + readOnly here will force the ReadOnly setting in VolumeMounts. + Defaults to false. + type: boolean + secretRef: + description: secretRef is the CHAP Secret for + iSCSI target and initiator authentication + 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 + targetPortal: + description: |- + targetPortal is iSCSI Target Portal. The Portal is either an IP or ip_addr:port if the port + is other than default (typically TCP ports 860 and 3260). + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + description: |- + name of the volume. + Must be a DNS_LABEL and unique within the pod. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + nfs: + description: |- + nfs represents an NFS mount on the host that shares a pod's lifetime + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + properties: + path: + description: |- + path that is exported by the NFS server. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + type: string + readOnly: + description: |- + readOnly here will force the NFS export to be mounted with read-only permissions. + Defaults to false. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + type: boolean + server: + description: |- + server is the hostname or IP address of the NFS server. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + description: |- + persistentVolumeClaimVolumeSource represents a reference to a + PersistentVolumeClaim in the same namespace. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims + properties: + claimName: + description: |- + claimName is the name of a PersistentVolumeClaim in the same namespace as the pod using this volume. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims + type: string + readOnly: + description: |- + readOnly Will force the ReadOnly setting in VolumeMounts. + Default false. + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + description: photonPersistentDisk represents a PhotonController + persistent disk attached and mounted on kubelets + host machine + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + pdID: + description: pdID is the ID that identifies Photon + Controller persistent disk + type: string + required: + - pdID + type: object + portworxVolume: + description: portworxVolume represents a portworx + volume attached and mounted on kubelets host machine + properties: + fsType: + description: |- + fSType represents the filesystem type to mount + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs". Implicitly inferred to be "ext4" if unspecified. + type: string + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + volumeID: + description: volumeID uniquely identifies a Portworx + volume + type: string + required: + - volumeID + type: object + projected: + description: projected items for all in one resources + secrets, configmaps, and downward API + properties: + defaultMode: + description: |- + defaultMode are the mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + sources: + description: sources is the list of volume projections + items: + description: Projection that may be projected + along with other supported volume types + properties: + clusterTrustBundle: + description: |- + ClusterTrustBundle allows a pod to access the `.spec.trustBundle` field + of ClusterTrustBundle objects in an auto-updating file. + + + Alpha, gated by the ClusterTrustBundleProjection feature gate. + + + ClusterTrustBundle objects can either be selected by name, or by the + combination of signer name and a label selector. + + + Kubelet performs aggressive normalization of the PEM contents written + into the pod filesystem. Esoteric PEM features such as inter-block + comments and block headers are stripped. Certificates are deduplicated. + The ordering of certificates within the file is arbitrary, and Kubelet + may change the order over time. + properties: + labelSelector: + description: |- + Select all ClusterTrustBundles that match this label selector. Only has + effect if signerName is set. Mutually-exclusive with name. If unset, + interpreted as "match nothing". If set but empty, interpreted as "match + everything". + properties: + matchExpressions: + description: matchExpressions is + a list of label selector requirements. + The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + name: + description: |- + Select a single ClusterTrustBundle by object name. Mutually-exclusive + with signerName and labelSelector. + type: string + optional: + description: |- + If true, don't block pod startup if the referenced ClusterTrustBundle(s) + aren't available. If using name, then the named ClusterTrustBundle is + allowed not to exist. If using signerName, then the combination of + signerName and labelSelector is allowed to match zero + ClusterTrustBundles. + type: boolean + path: + description: Relative path from the + volume root to write the bundle. + type: string + signerName: + description: |- + Select all ClusterTrustBundles that match this signer name. + Mutually-exclusive with name. The contents of all selected + ClusterTrustBundles will be unified and deduplicated. + type: string + required: + - path + type: object + configMap: + description: configMap information about + the configMap data to project + properties: + items: + description: |- + items if unspecified, each key-value pair in the Data field of the referenced + ConfigMap will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the ConfigMap, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to + a path within a volume. + properties: + key: + description: key is the key to + project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + 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 + optional: + description: optional specify whether + the ConfigMap or its keys must be + defined + type: boolean + type: object + x-kubernetes-map-type: atomic + downwardAPI: + description: downwardAPI information about + the downwardAPI data to project + properties: + items: + description: Items is a list of DownwardAPIVolume + file + items: + description: DownwardAPIVolumeFile + represents information to create + the file containing the pod field + properties: + fieldRef: + description: 'Required: Selects + a field of the pod: only annotations, + labels, name and namespace are + supported.' + properties: + apiVersion: + description: Version of the + schema the FieldPath is + written in terms of, defaults + to "v1". + type: string + fieldPath: + description: Path of the field + to select in the specified + API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + description: |- + Optional: mode bits used to set permissions on this file, must be an octal value + between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: 'Required: Path is the + relative path name of the file + to be created. Must not be absolute + or contain the ''..'' path. + Must be utf-8 encoded. The first + item of the relative path must + not start with ''..''' + type: string + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported. + properties: + containerName: + description: 'Container name: + required for volumes, optional + for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the + output format of the exposed + resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource + to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + type: object + secret: + description: secret information about the + secret data to project + properties: + items: + description: |- + items if unspecified, each key-value pair in the Data field of the referenced + Secret will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the Secret, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to + a path within a volume. + properties: + key: + description: key is the key to + project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + 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 + optional: + description: optional field specify + whether the Secret or its key must + be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + serviceAccountToken: + description: serviceAccountToken is information + about the serviceAccountToken data to + project + properties: + audience: + description: |- + audience is the intended audience of the token. A recipient of a token + must identify itself with an identifier specified in the audience of the + token, and otherwise should reject the token. The audience defaults to the + identifier of the apiserver. + type: string + expirationSeconds: + description: |- + expirationSeconds is the requested duration of validity of the service + account token. As the token approaches expiration, the kubelet volume + plugin will proactively rotate the service account token. The kubelet will + start trying to rotate the token if the token is older than 80 percent of + its time to live or if the token is older than 24 hours.Defaults to 1 hour + and must be at least 10 minutes. + format: int64 + type: integer + path: + description: |- + path is the path relative to the mount point of the file to project the + token into. + type: string + required: + - path + type: object + type: object + type: array + type: object + quobyte: + description: quobyte represents a Quobyte mount on + the host that shares a pod's lifetime + properties: + group: + description: |- + group to map volume access to + Default is no group + type: string + readOnly: + description: |- + readOnly here will force the Quobyte volume to be mounted with read-only permissions. + Defaults to false. + type: boolean + registry: + description: |- + registry represents a single or multiple Quobyte Registry services + specified as a string as host:port pair (multiple entries are separated with commas) + which acts as the central registry for volumes + type: string + tenant: + description: |- + tenant owning the given Quobyte volume in the Backend + Used with dynamically provisioned Quobyte volumes, value is set by the plugin + type: string + user: + description: |- + user to map volume access to + Defaults to serivceaccount user + type: string + volume: + description: volume is a string that references + an already created Quobyte volume by name. + type: string + required: + - registry + - volume + type: object + rbd: + description: |- + rbd represents a Rados Block Device mount on the host that shares a pod's lifetime. + More info: https://examples.k8s.io/volumes/rbd/README.md + properties: + fsType: + description: |- + fsType is the filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#rbd + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + image: + description: |- + image is the rados image name. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + keyring: + description: |- + keyring is the path to key ring for RBDUser. + Default is /etc/ceph/keyring. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + monitors: + description: |- + monitors is a collection of Ceph monitors. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + items: + type: string + type: array + pool: + description: |- + pool is the rados pool name. + Default is rbd. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + readOnly: + description: |- + readOnly here will force the ReadOnly setting in VolumeMounts. + Defaults to false. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: boolean + secretRef: + description: |- + secretRef is name of the authentication secret for RBDUser. If provided + overrides keyring. + Default is nil. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + 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 + user: + description: |- + user is the rados user name. + Default is admin. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + required: + - image + - monitors + type: object + scaleIO: + description: scaleIO represents a ScaleIO persistent + volume attached and mounted on Kubernetes nodes. + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". + Default is "xfs". + type: string + gateway: + description: gateway is the host address of the + ScaleIO API Gateway. + type: string + protectionDomain: + description: protectionDomain is the name of the + ScaleIO Protection Domain for the configured + storage. + type: string + readOnly: + description: |- + readOnly Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: |- + secretRef references to the secret for ScaleIO user and other + sensitive information. If this is not provided, Login operation will fail. + 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 + sslEnabled: + description: sslEnabled Flag enable/disable SSL + communication with Gateway, default false + type: boolean + storageMode: + description: |- + storageMode indicates whether the storage for a volume should be ThickProvisioned or ThinProvisioned. + Default is ThinProvisioned. + type: string + storagePool: + description: storagePool is the ScaleIO Storage + Pool associated with the protection domain. + type: string + system: + description: system is the name of the storage + system as configured in ScaleIO. + type: string + volumeName: + description: |- + volumeName is the name of a volume already created in the ScaleIO system + that is associated with this volume source. + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + description: |- + secret represents a secret that should populate this volume. + More info: https://kubernetes.io/docs/concepts/storage/volumes#secret + properties: + defaultMode: + description: |- + defaultMode is Optional: mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values + for mode bits. Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + items: + description: |- + items If unspecified, each key-value pair in the Data field of the referenced + Secret will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the Secret, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within + a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + optional: + description: optional field specify whether the + Secret or its keys must be defined + type: boolean + secretName: + description: |- + secretName is the name of the secret in the pod's namespace to use. + More info: https://kubernetes.io/docs/concepts/storage/volumes#secret + type: string + type: object + storageos: + description: storageOS represents a StorageOS volume + attached and mounted on Kubernetes nodes. + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: |- + secretRef specifies the secret to use for obtaining the StorageOS API + credentials. If not specified, default values will be attempted. + 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 + volumeName: + description: |- + volumeName is the human-readable name of the StorageOS volume. Volume + names are only unique within a namespace. + type: string + volumeNamespace: + description: |- + volumeNamespace specifies the scope of the volume within StorageOS. If no + namespace is specified then the Pod's namespace will be used. This allows the + Kubernetes name scoping to be mirrored within StorageOS for tighter integration. + Set VolumeName to any name to override the default behaviour. + Set to "default" if you are not using namespaces within StorageOS. + Namespaces that do not pre-exist within StorageOS will be created. + type: string + type: object + vsphereVolume: + description: vsphereVolume represents a vSphere volume + attached and mounted on kubelets host machine + properties: + fsType: + description: |- + fsType is filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + storagePolicyID: + description: storagePolicyID is the storage Policy + Based Management (SPBM) profile ID associated + with the StoragePolicyName. + type: string + storagePolicyName: + description: storagePolicyName is the storage + Policy Based Management (SPBM) profile name. + type: string + volumePath: + description: volumePath is the path that identifies + vSphere volume vmdk + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + required: + - replicas + type: object + required: + - name + - template + type: object + maxItems: 128 + minItems: 1 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + terminationPolicy: + description: |- + Specifies the behavior when a Cluster is deleted. + It defines how resources, data, and backups associated with a Cluster are managed during termination. + Choose a policy based on the desired level of resource cleanup and data preservation: + + + - `DoNotTerminate`: Prevents deletion of the Cluster. This policy ensures that all resources remain intact. + - `Halt`: Deletes Cluster resources like Pods and Services but retains Persistent Volume Claims (PVCs), + allowing for data preservation while stopping other operations. + - `Delete`: Extends the `Halt` policy by also removing PVCs, leading to a thorough cleanup while + removing all persistent data. + - `WipeOut`: An aggressive policy that deletes all Cluster resources, including volume snapshots and + backups in external storage. + This results in complete data removal and should be used cautiously, primarily in non-production environments + to avoid irreversible data loss. + + + Warning: Choosing an inappropriate termination policy can result in data loss. + The `WipeOut` policy is particularly risky in production environments due to its irreversible nature. + enum: + - DoNotTerminate + - Halt + - Delete + - WipeOut + type: string + topology: + description: |- + Specifies the name of the ClusterTopology to be used when creating the Cluster. + + + This field defines which set of Components, as outlined in the ClusterDefinition, will be used to + construct the Cluster based on the named topology. + The ClusterDefinition may list multiple topologies under `clusterdefinition.spec.topologies[*]`, + each tailored to different use cases or environments. + + + If `topology` is not specified, the Cluster will use the default topology defined in the ClusterDefinition. + + + Note: Once set during the Cluster creation, the `topology` field cannot be modified. + It establishes the initial composition and structure of the Cluster and is intended for one-time configuration. + maxLength: 32 type: string + required: + - terminationPolicy type: object status: - description: ClusterStatus defines the observed state of Cluster + description: ClusterStatus defines the observed state of the Cluster. + properties: + clusterDefGeneration: + description: Represents the generation number of the referenced ClusterDefinition. + format: int64 + type: integer + components: + additionalProperties: + description: ClusterComponentStatus records Component status. + properties: + message: + additionalProperties: + type: string + description: |- + Records detailed information about the Component in its current phase. + The keys are either podName, deployName, or statefulSetName, formatted as 'ObjectKind/Name'. + type: object + phase: + description: Specifies the current state of the Component. + enum: + - Creating + - Running + - Updating + - Stopping + - Stopped + - Deleting + - Failed + - Abnormal + type: string + type: object + description: Records the current status information of all Components + within the Cluster. + type: object + conditions: + description: |- + Represents a list of detailed status of the Cluster object. + Each condition in the list provides real-time information about certain aspect of the Cluster object. + + + This field is crucial for administrators and developers to monitor and respond to changes within the Cluster. + It provides a history of state transitions and a snapshot of the current state that can be used for + automated logic or direct inspection. + items: + description: "Condition contains details for one aspect of the current + state of this API Resource.\n---\nThis struct is intended for + direct use as an array at the field path .status.conditions. For + example,\n\n\n\ttype FooStatus struct{\n\t // Represents the + observations of a foo's current state.\n\t // Known .status.conditions.type + are: \"Available\", \"Progressing\", and \"Degraded\"\n\t // + +patchMergeKey=type\n\t // +patchStrategy=merge\n\t // +listType=map\n\t + \ // +listMapKey=type\n\t Conditions []metav1.Condition `json:\"conditions,omitempty\" + patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t + \ // other fields\n\t}" + 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 + message: + description: Provides additional information about the current phase. + type: string + observedGeneration: + description: The most recent generation number of the Cluster object + that has been observed by the controller. + format: int64 + type: integer + phase: + description: |- + The current phase of the Cluster includes: + `Creating`, `Running`, `Updating`, `Stopping`, `Stopped`, `Deleting`, `Failed`, `Abnormal`. + enum: + - Creating + - Running + - Updating + - Stopping + - Stopped + - Deleting + - Failed + - Abnormal + type: string type: object type: object served: true diff --git a/controllers/apps/cluster_controller.go b/controllers/apps/cluster_controller.go index aff10160452..773730adc3b 100644 --- a/controllers/apps/cluster_controller.go +++ b/controllers/apps/cluster_controller.go @@ -32,7 +32,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/controller" "sigs.k8s.io/controller-runtime/pkg/log" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" dpv1alpha1 "github.com/apecloud/kubeblocks/apis/dataprotection/v1alpha1" "github.com/apecloud/kubeblocks/pkg/constant" "github.com/apecloud/kubeblocks/pkg/controller/multicluster" @@ -176,11 +176,11 @@ func (r *ClusterReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ct // SetupWithManager sets up the controller with the Manager. func (r *ClusterReconciler) SetupWithManager(mgr ctrl.Manager) error { return intctrlutil.NewNamespacedControllerManagedBy(mgr). - For(&appsv1alpha1.Cluster{}). + For(&appsv1.Cluster{}). WithOptions(controller.Options{ MaxConcurrentReconciles: int(math.Ceil(viper.GetFloat64(constant.CfgKBReconcileWorkers) / 4)), }). - Owns(&appsv1alpha1.Component{}). + Owns(&appsv1.Component{}). Owns(&corev1.Service{}). // cluster services Owns(&corev1.Secret{}). // cluster conn-credential secret Owns(&dpv1alpha1.BackupPolicy{}). diff --git a/controllers/apps/cluster_controller_test.go b/controllers/apps/cluster_controller_test.go index 9a317944cab..2e6c8b65d50 100644 --- a/controllers/apps/cluster_controller_test.go +++ b/controllers/apps/cluster_controller_test.go @@ -35,12 +35,9 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" dpv1alpha1 "github.com/apecloud/kubeblocks/apis/dataprotection/v1alpha1" "github.com/apecloud/kubeblocks/pkg/constant" "github.com/apecloud/kubeblocks/pkg/controller/builder" - "github.com/apecloud/kubeblocks/pkg/controller/component" - "github.com/apecloud/kubeblocks/pkg/controller/scheduling" "github.com/apecloud/kubeblocks/pkg/generics" testapps "github.com/apecloud/kubeblocks/pkg/testutil/apps" testdp "github.com/apecloud/kubeblocks/pkg/testutil/dataprotection" @@ -63,7 +60,7 @@ var _ = Describe("Cluster Controller", func() { clusterDefObj *appsv1.ClusterDefinition compDefObj *appsv1.ComponentDefinition compVersionObj *appsv1.ComponentVersion - clusterObj *appsv1alpha1.Cluster + clusterObj *appsv1.Cluster clusterKey types.NamespacedName allSettings map[string]interface{} defaultTopology = appsv1.ClusterTopology{ @@ -200,13 +197,13 @@ var _ = Describe("Cluster Controller", func() { waitForCreatingResourceCompletely := func(clusterKey client.ObjectKey, compNames ...string) { Eventually(testapps.GetClusterObservedGeneration(&testCtx, clusterKey)).Should(BeEquivalentTo(1)) - cluster := &appsv1alpha1.Cluster{} + cluster := &appsv1.Cluster{} Eventually(testapps.CheckObjExists(&testCtx, clusterKey, cluster, true)).Should(Succeed()) for _, compName := range compNames { - compPhase := appsv1alpha1.CreatingClusterCompPhase + compPhase := appsv1.CreatingClusterCompPhase for _, spec := range cluster.Spec.ComponentSpecs { if spec.Name == compName && spec.Replicas == 0 { - compPhase = appsv1alpha1.StoppedClusterCompPhase + compPhase = appsv1.StoppedClusterCompPhase } } Eventually(testapps.GetClusterComponentPhase(&testCtx, clusterKey, compName)).Should(Equal(compPhase)) @@ -264,7 +261,7 @@ var _ = Describe("Cluster Controller", func() { By("Waiting for the cluster enter Creating phase") Eventually(testapps.GetClusterObservedGeneration(&testCtx, clusterKey)).Should(BeEquivalentTo(1)) - Eventually(testapps.GetClusterPhase(&testCtx, clusterKey)).Should(Equal(appsv1alpha1.CreatingClusterPhase)) + Eventually(testapps.GetClusterPhase(&testCtx, clusterKey)).Should(Equal(appsv1.CreatingClusterPhase)) By("Wait component created") compKey := types.NamespacedName{ @@ -281,7 +278,7 @@ var _ = Describe("Cluster Controller", func() { By("Waiting for the cluster enter Creating phase") Eventually(testapps.GetClusterObservedGeneration(&testCtx, clusterKey)).Should(BeEquivalentTo(1)) - Eventually(testapps.GetClusterPhase(&testCtx, clusterKey)).Should(Equal(appsv1alpha1.CreatingClusterPhase)) + Eventually(testapps.GetClusterPhase(&testCtx, clusterKey)).Should(Equal(appsv1.CreatingClusterPhase)) By("Wait components created") compKey := types.NamespacedName{ @@ -297,7 +294,7 @@ var _ = Describe("Cluster Controller", func() { By("Waiting for the cluster enter Creating phase") Eventually(testapps.GetClusterObservedGeneration(&testCtx, clusterKey)).Should(BeEquivalentTo(1)) - Eventually(testapps.GetClusterPhase(&testCtx, clusterKey)).Should(Equal(appsv1alpha1.CreatingClusterPhase)) + Eventually(testapps.GetClusterPhase(&testCtx, clusterKey)).Should(Equal(appsv1.CreatingClusterPhase)) By("Wait component created") ml := client.MatchingLabels{ @@ -327,7 +324,7 @@ var _ = Describe("Cluster Controller", func() { By("Waiting for the cluster enter Creating phase") Eventually(testapps.GetClusterObservedGeneration(&testCtx, clusterKey)).Should(BeEquivalentTo(1)) - Eventually(testapps.GetClusterPhase(&testCtx, clusterKey)).Should(Equal(appsv1alpha1.CreatingClusterPhase)) + Eventually(testapps.GetClusterPhase(&testCtx, clusterKey)).Should(Equal(appsv1.CreatingClusterPhase)) By("Wait component created") compKey := types.NamespacedName{ @@ -337,7 +334,7 @@ var _ = Describe("Cluster Controller", func() { compObj := &appsv1.Component{} Eventually(testapps.CheckObjExists(&testCtx, compKey, compObj, true)).Should(Succeed()) - Eventually(testapps.CheckObj(&testCtx, clusterKey, func(g Gomega, cluster *appsv1alpha1.Cluster) { + Eventually(testapps.CheckObj(&testCtx, clusterKey, func(g Gomega, cluster *appsv1.Cluster) { g.Expect(cluster.Spec.ComponentSpecs).Should(HaveLen(1)) clusterJSON, err := json.Marshal(cluster.Spec.ComponentSpecs[0].Instances) g.Expect(err).Should(BeNil()) @@ -372,7 +369,7 @@ var _ = Describe("Cluster Controller", func() { createClusterObjWithTopology(topology, compName, processor) By("check cluster updated") - Eventually(testapps.CheckObj(&testCtx, clusterKey, func(g Gomega, cluster *appsv1alpha1.Cluster) { + Eventually(testapps.CheckObj(&testCtx, clusterKey, func(g Gomega, cluster *appsv1.Cluster) { if len(topology) == 0 { g.Expect(cluster.Spec.Topology).Should(Equal(defaultTopology.Name)) } else { @@ -424,7 +421,7 @@ var _ = Describe("Cluster Controller", func() { waitForCreatingResourceCompletely(clusterKey, compName, otherCompName) By("scale in the target component") - Expect(testapps.GetAndChangeObj(&testCtx, clusterKey, func(cluster *appsv1alpha1.Cluster) { + Expect(testapps.GetAndChangeObj(&testCtx, clusterKey, func(cluster *appsv1.Cluster) { for i, compSpec := range cluster.Spec.ComponentSpecs { if compSpec.Name == compName { // delete the target component @@ -444,7 +441,7 @@ var _ = Describe("Cluster Controller", func() { } Eventually(testapps.CheckObjExists(&testCtx, compKey, &appsv1.Component{}, false)).Should(Succeed()) Eventually(testapps.CheckObjExists(&testCtx, multiCompKey, &appsv1.Component{}, true)).Should(Succeed()) - Eventually(testapps.CheckObjExists(&testCtx, clusterKey, &appsv1alpha1.Cluster{}, true)).Should(Succeed()) + Eventually(testapps.CheckObjExists(&testCtx, clusterKey, &appsv1.Cluster{}, true)).Should(Succeed()) } testClusterShardingComponentScaleIn := func(compName, compDefName string, createObj func(string, string, func(*testapps.MockClusterFactory)), shards int) { @@ -452,7 +449,7 @@ var _ = Describe("Cluster Controller", func() { testShardingClusterComponent(compName, compDefName, createObj, shards) By("scale in the sharding component") - Expect(testapps.GetAndChangeObj(&testCtx, clusterKey, func(cluster *appsv1alpha1.Cluster) { + Expect(testapps.GetAndChangeObj(&testCtx, clusterKey, func(cluster *appsv1.Cluster) { for i := range cluster.Spec.ShardingSpecs { if cluster.Spec.ShardingSpecs[i].Name == compName { cluster.Spec.ShardingSpecs[i].Shards = int32(shards - 1) @@ -488,8 +485,8 @@ var _ = Describe("Cluster Controller", func() { f.SetName(randClusterName). AddAppManagedByLabel(). AddAppInstanceLabel(randClusterName). - AddService(appsv1alpha1.ClusterService{ - Service: appsv1alpha1.Service{ + AddService(appsv1.ClusterService{ + Service: appsv1.Service{ Name: service.Name, ServiceName: service.Name, Spec: service.Spec, @@ -526,121 +523,6 @@ var _ = Describe("Cluster Controller", func() { })).Should(Succeed()) } - testClusterAffinityNToleration := func(compName, compDefName string, createObj func(string, string, func(*testapps.MockClusterFactory))) { - const ( - clusterTopologyKey = "testClusterTopologyKey" - clusterLabelKey = "testClusterNodeLabelKey" - clusterLabelValue = "testClusterNodeLabelValue" - clusterTolerationKey = "testClusterTolerationKey" - clusterTolerationValue = "testClusterTolerationValue" - ) - - By("Creating a cluster with Affinity and Toleration") - affinity := appsv1alpha1.Affinity{ - PodAntiAffinity: appsv1alpha1.Required, - TopologyKeys: []string{clusterTopologyKey}, - NodeLabels: map[string]string{ - clusterLabelKey: clusterLabelValue, - }, - Tenancy: appsv1alpha1.SharedNode, - } - toleration := corev1.Toleration{ - Key: clusterTolerationKey, - Value: clusterTolerationValue, - Operator: corev1.TolerationOpEqual, - Effect: corev1.TaintEffectNoSchedule, - } - createObj(compName, compDefName, func(f *testapps.MockClusterFactory) { - f.SetClusterAffinity(&affinity).AddClusterToleration(toleration) - }) - - By("Checking the Affinity and Toleration") - schedulingPolicy, err := scheduling.BuildSchedulingPolicy4Component(clusterObj.Name, compName, &affinity, []corev1.Toleration{toleration}) - Expect(err).Should(BeNil()) - - compKey := types.NamespacedName{ - Namespace: clusterObj.Namespace, - Name: component.FullName(clusterObj.Name, compName), - } - Eventually(testapps.CheckObj(&testCtx, compKey, func(g Gomega, comp *appsv1.Component) { - g.Expect(comp.Spec.SchedulingPolicy).ShouldNot(BeNil()) - g.Expect(comp.Spec.SchedulingPolicy.Affinity).Should(BeEquivalentTo(schedulingPolicy.Affinity)) - g.Expect(comp.Spec.SchedulingPolicy.Tolerations).Should(HaveLen(2)) - g.Expect(comp.Spec.SchedulingPolicy.Tolerations[0]).Should(BeEquivalentTo(toleration)) - })).Should(Succeed()) - } - - testClusterComponentAffinityNToleration := func(compName, compDefName string, createObj func(string, string, func(*testapps.MockClusterFactory))) { - const ( - clusterTopologyKey = "testClusterTopologyKey" - clusterLabelKey = "testClusterNodeLabelKey" - clusterLabelValue = "testClusterNodeLabelValue" - compTopologyKey = "testCompTopologyKey" - compLabelKey = "testCompNodeLabelKey" - compLabelValue = "testCompNodeLabelValue" - clusterTolerationKey = "testClusterTolerationKey" - clusterTolerationValue = "testClusterTolerationValue" - compTolerationKey = "testCompTolerationKey" - compTolerationValue = "testCompTolerationValue" - ) - - By("Creating a cluster with Affinity and Toleration") - affinity := appsv1alpha1.Affinity{ - PodAntiAffinity: appsv1alpha1.Required, - TopologyKeys: []string{clusterTopologyKey}, - NodeLabels: map[string]string{ - clusterLabelKey: clusterLabelValue, - }, - Tenancy: appsv1alpha1.SharedNode, - } - compAffinity := appsv1alpha1.Affinity{ - PodAntiAffinity: appsv1alpha1.Preferred, - TopologyKeys: []string{compTopologyKey}, - NodeLabels: map[string]string{ - compLabelKey: compLabelValue, - clusterLabelKey: clusterLabelValue, - }, - Tenancy: appsv1alpha1.DedicatedNode, - } - toleration := corev1.Toleration{ - Key: clusterTolerationKey, - Value: clusterTolerationValue, - Operator: corev1.TolerationOpEqual, - Effect: corev1.TaintEffectNoSchedule, - } - compToleration := corev1.Toleration{ - Key: compTolerationKey, - Value: compTolerationValue, - Operator: corev1.TolerationOpEqual, - Effect: corev1.TaintEffectNoSchedule, - } - createObj(compName, compDefName, func(f *testapps.MockClusterFactory) { - f.SetComponentAffinity(&compAffinity). - AddComponentToleration(compToleration). - SetClusterAffinity(&affinity). - AddClusterToleration(toleration) - }) - - By("Checking the Affinity and Toleration") - schedulingPolicy, err := scheduling.BuildSchedulingPolicy4Component(clusterObj.Name, compName, &compAffinity, []corev1.Toleration{compToleration}) - Expect(err).Should(BeNil()) - // key of the MatchExpressions must be sorted. - MatchExpressions := schedulingPolicy.Affinity.NodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution.NodeSelectorTerms[0].MatchExpressions - Expect(MatchExpressions).Should(HaveLen(2)) - Expect(MatchExpressions[0].Key).Should(Equal(clusterLabelKey)) - - compKey := types.NamespacedName{ - Namespace: clusterObj.Namespace, - Name: component.FullName(clusterObj.Name, compName), - } - Eventually(testapps.CheckObj(&testCtx, compKey, func(g Gomega, comp *appsv1.Component) { - g.Expect(comp.Spec.SchedulingPolicy).ShouldNot(BeNil()) - g.Expect(comp.Spec.SchedulingPolicy.Affinity).Should(BeEquivalentTo(schedulingPolicy.Affinity)) - g.Expect(comp.Spec.SchedulingPolicy.Tolerations).Should(HaveLen(2)) - g.Expect(comp.Spec.SchedulingPolicy.Tolerations[0]).Should(BeEquivalentTo(compToleration)) - })).Should(Succeed()) - } - type expectService struct { clusterIP string svcType corev1.ServiceType @@ -714,10 +596,10 @@ var _ = Describe("Cluster Controller", func() { testapps.ServiceInternetName: {"", corev1.ServiceTypeLoadBalancer}, } - services := make([]appsv1alpha1.ClusterService, 0) + services := make([]appsv1.ClusterService, 0) for name, svc := range expectServices { - services = append(services, appsv1alpha1.ClusterService{ - Service: appsv1alpha1.Service{ + services = append(services, appsv1.ClusterService{ + Service: appsv1.Service{ Name: name, ServiceName: name, Spec: corev1.ServiceSpec{ @@ -757,8 +639,8 @@ var _ = Describe("Cluster Controller", func() { By("delete a cluster service") delete(expectServices, deleteService.Name) - Expect(testapps.GetAndChangeObj(&testCtx, clusterKey, func(cluster *appsv1alpha1.Cluster) { - var svcs []appsv1alpha1.ClusterService + Expect(testapps.GetAndChangeObj(&testCtx, clusterKey, func(cluster *appsv1.Cluster) { + var svcs []appsv1.ClusterService for _, item := range cluster.Spec.Services { if item.Name != deleteService.Name { svcs = append(svcs, item) @@ -772,7 +654,7 @@ var _ = Describe("Cluster Controller", func() { By("add the deleted service back") expectServices[deleteService.Name] = expectService{deleteService.Spec.ClusterIP, deleteService.Spec.Type} - Expect(testapps.GetAndChangeObj(&testCtx, clusterKey, func(cluster *appsv1alpha1.Cluster) { + Expect(testapps.GetAndChangeObj(&testCtx, clusterKey, func(cluster *appsv1.Cluster) { cluster.Spec.Services = append(cluster.Spec.Services, deleteService) })()).ShouldNot(HaveOccurred()) Eventually(func(g Gomega) { validateClusterServiceList(g, expectServices, compName, nil, false) }).Should(Succeed()) @@ -784,10 +666,10 @@ var _ = Describe("Cluster Controller", func() { testapps.ServiceHeadlessName: {corev1.ClusterIPNone, corev1.ServiceTypeClusterIP}, } - services := make([]appsv1alpha1.ClusterService, 0) + services := make([]appsv1.ClusterService, 0) for name, svc := range expectServices { - services = append(services, appsv1alpha1.ClusterService{ - Service: appsv1alpha1.Service{ + services = append(services, appsv1.ClusterService{ + Service: appsv1.Service{ Name: name, ServiceName: name, Spec: corev1.ServiceSpec{ @@ -812,7 +694,7 @@ var _ = Describe("Cluster Controller", func() { Eventually(func(g Gomega) { validateClusterServiceList(g, expectServices, compTplName, &shards, false) }).Should(Succeed()) By("check shards number services were created for each shard when ShardSvcAnnotationKey is set") - Expect(testapps.GetAndChangeObj(&testCtx, clusterKey, func(cluster *appsv1alpha1.Cluster) { + Expect(testapps.GetAndChangeObj(&testCtx, clusterKey, func(cluster *appsv1.Cluster) { if cluster.Annotations == nil { cluster.Annotations = map[string]string{} } @@ -822,8 +704,8 @@ var _ = Describe("Cluster Controller", func() { By("delete a cluster shard service") delete(expectServices, deleteService.Name) - Expect(testapps.GetAndChangeObj(&testCtx, clusterKey, func(cluster *appsv1alpha1.Cluster) { - var svcs []appsv1alpha1.ClusterService + Expect(testapps.GetAndChangeObj(&testCtx, clusterKey, func(cluster *appsv1.Cluster) { + var svcs []appsv1.ClusterService for _, item := range cluster.Spec.Services { if item.Name != deleteService.Name { svcs = append(svcs, item) @@ -837,14 +719,14 @@ var _ = Describe("Cluster Controller", func() { By("add the deleted service back") expectServices[deleteService.Name] = expectService{deleteService.Spec.ClusterIP, deleteService.Spec.Type} - Expect(testapps.GetAndChangeObj(&testCtx, clusterKey, func(cluster *appsv1alpha1.Cluster) { + Expect(testapps.GetAndChangeObj(&testCtx, clusterKey, func(cluster *appsv1.Cluster) { cluster.Spec.Services = append(cluster.Spec.Services, deleteService) })()).ShouldNot(HaveOccurred()) Eventually(func(g Gomega) { validateClusterServiceList(g, expectServices, compTplName, &shards, true) }).Should(Succeed()) } - testClusterFinalizer := func(compName string, createObj func(appsv1alpha1.TerminationPolicyType)) { - createObj(appsv1alpha1.WipeOut) + testClusterFinalizer := func(compName string, createObj func(appsv1.TerminationPolicyType)) { + createObj(appsv1.WipeOut) By("wait component created") compKey := types.NamespacedName{ @@ -860,10 +742,10 @@ var _ = Describe("Cluster Controller", func() { })()).ShouldNot(HaveOccurred()) By("delete the cluster") - testapps.DeleteObject(&testCtx, clusterKey, &appsv1alpha1.Cluster{}) + testapps.DeleteObject(&testCtx, clusterKey, &appsv1.Cluster{}) By("check cluster keep existing") - Consistently(testapps.CheckObjExists(&testCtx, clusterKey, &appsv1alpha1.Cluster{}, true)).Should(Succeed()) + Consistently(testapps.CheckObjExists(&testCtx, clusterKey, &appsv1.Cluster{}, true)).Should(Succeed()) By("remove finalizer of component to get it deleted") Expect(testapps.GetAndChangeObj(&testCtx, compKey, func(comp *appsv1.Component) { @@ -872,11 +754,11 @@ var _ = Describe("Cluster Controller", func() { By("wait for the cluster and component to terminate") Eventually(testapps.CheckObjExists(&testCtx, compKey, &appsv1.Component{}, false)).Should(Succeed()) - Eventually(testapps.CheckObjExists(&testCtx, clusterKey, &appsv1alpha1.Cluster{}, false)).Should(Succeed()) + Eventually(testapps.CheckObjExists(&testCtx, clusterKey, &appsv1.Cluster{}, false)).Should(Succeed()) } - testDeleteClusterWithDoNotTerminate := func(createObj func(appsv1alpha1.TerminationPolicyType)) { - createObj(appsv1alpha1.DoNotTerminate) + testDeleteClusterWithDoNotTerminate := func(createObj func(appsv1.TerminationPolicyType)) { + createObj(appsv1.DoNotTerminate) By("check all other resources deleted") transCtx := &clusterTransformContext{ @@ -889,8 +771,8 @@ var _ = Describe("Cluster Controller", func() { Expect(err).Should(Succeed()) By("delete the cluster") - testapps.DeleteObject(&testCtx, clusterKey, &appsv1alpha1.Cluster{}) - Consistently(testapps.CheckObjExists(&testCtx, clusterKey, &appsv1alpha1.Cluster{}, true)).Should(Succeed()) + testapps.DeleteObject(&testCtx, clusterKey, &appsv1.Cluster{}) + Consistently(testapps.CheckObjExists(&testCtx, clusterKey, &appsv1.Cluster{}, true)).Should(Succeed()) By("check all cluster resources again") objs, err := getOwningNamespacedObjects(transCtx.Context, transCtx.Client, clusterObj.Namespace, getAppInstanceML(*clusterObj), allKinds) @@ -902,8 +784,8 @@ var _ = Describe("Cluster Controller", func() { } } - testDeleteClusterWithHalt := func(createObj func(appsv1alpha1.TerminationPolicyType)) { - createObj(appsv1alpha1.Halt) + testDeleteClusterWithHalt := func(createObj func(appsv1.TerminationPolicyType)) { + createObj(appsv1.Halt) transCtx := &clusterTransformContext{ Context: testCtx.Ctx, @@ -918,10 +800,10 @@ var _ = Describe("Cluster Controller", func() { } By("delete the cluster") - testapps.DeleteObject(&testCtx, clusterKey, &appsv1alpha1.Cluster{}) + testapps.DeleteObject(&testCtx, clusterKey, &appsv1.Cluster{}) By("wait for the cluster to terminate") - Eventually(testapps.CheckObjExists(&testCtx, clusterKey, &appsv1alpha1.Cluster{}, false)).Should(Succeed()) + Eventually(testapps.CheckObjExists(&testCtx, clusterKey, &appsv1.Cluster{}, false)).Should(Succeed()) By("check expected preserved objects") keptObjs, err := getOwningNamespacedObjects(transCtx.Context, transCtx.Client, clusterObj.Namespace, getAppInstanceML(*clusterObj), preserveKinds) @@ -942,11 +824,11 @@ var _ = Describe("Cluster Controller", func() { Expect(otherObjs).Should(HaveLen(0)) } - testClusterHaltNRecovery := func(createObj func(appsv1alpha1.TerminationPolicyType)) { + testClusterHaltNRecovery := func(createObj func(appsv1.TerminationPolicyType)) { // TODO(component) } - deleteClusterWithBackup := func(terminationPolicy appsv1alpha1.TerminationPolicyType, backupRetainPolicy string) { + deleteClusterWithBackup := func(terminationPolicy appsv1.TerminationPolicyType, backupRetainPolicy string) { By("mocking a retained backup") backupPolicyName := "test-backup-policy" backupName := "test-backup" @@ -965,13 +847,13 @@ var _ = Describe("Cluster Controller", func() { Eventually(testapps.CheckObjExists(&testCtx, backupKey, &dpv1alpha1.Backup{}, true)).Should(Succeed()) By("delete the cluster") - testapps.DeleteObject(&testCtx, clusterKey, &appsv1alpha1.Cluster{}) + testapps.DeleteObject(&testCtx, clusterKey, &appsv1.Cluster{}) By("wait for the cluster to terminate") - Eventually(testapps.CheckObjExists(&testCtx, clusterKey, &appsv1alpha1.Cluster{}, false)).Should(Succeed()) + Eventually(testapps.CheckObjExists(&testCtx, clusterKey, &appsv1.Cluster{}, false)).Should(Succeed()) By(fmt.Sprintf("checking the backup with TerminationPolicyType=%s", terminationPolicy)) - if terminationPolicy == appsv1alpha1.WipeOut && backupRetainPolicy == constant.BackupDelete { + if terminationPolicy == appsv1.WipeOut && backupRetainPolicy == constant.BackupDelete { Eventually(testapps.CheckObjExists(&testCtx, backupKey, &dpv1alpha1.Backup{}, false)).Should(Succeed()) } else { Consistently(testapps.CheckObjExists(&testCtx, backupKey, &dpv1alpha1.Backup{}, true)).Should(Succeed()) @@ -983,7 +865,7 @@ var _ = Describe("Cluster Controller", func() { Client: testCtx.Cli, } var namespacedKinds, clusteredKinds []client.ObjectList - if terminationPolicy == appsv1alpha1.WipeOut && backupRetainPolicy == constant.BackupDelete { + if terminationPolicy == appsv1.WipeOut && backupRetainPolicy == constant.BackupDelete { namespacedKinds, clusteredKinds = kindsForWipeOut() } else { namespacedKinds, clusteredKinds = kindsForDelete() @@ -994,14 +876,14 @@ var _ = Describe("Cluster Controller", func() { Expect(otherObjs).Should(HaveLen(0)) } - testDeleteClusterWithDelete := func(createObj func(appsv1alpha1.TerminationPolicyType)) { - createObj(appsv1alpha1.Delete) - deleteClusterWithBackup(appsv1alpha1.Delete, constant.BackupRetain) + testDeleteClusterWithDelete := func(createObj func(appsv1.TerminationPolicyType)) { + createObj(appsv1.Delete) + deleteClusterWithBackup(appsv1.Delete, constant.BackupRetain) } - testDeleteClusterWithWipeOut := func(createObj func(appsv1alpha1.TerminationPolicyType), backupRetainPolicy string) { - createObj(appsv1alpha1.WipeOut) - deleteClusterWithBackup(appsv1alpha1.WipeOut, backupRetainPolicy) + testDeleteClusterWithWipeOut := func(createObj func(appsv1.TerminationPolicyType), backupRetainPolicy string) { + createObj(appsv1.WipeOut) + deleteClusterWithBackup(appsv1.WipeOut, backupRetainPolicy) } Context("cluster provisioning", func() { @@ -1061,7 +943,7 @@ var _ = Describe("Cluster Controller", func() { Context("cluster termination policy", func() { var ( - createObj = func(policyType appsv1alpha1.TerminationPolicyType) { + createObj = func(policyType appsv1.TerminationPolicyType) { createClusterObj(defaultCompName, compDefObj.Name, func(f *testapps.MockClusterFactory) { f.SetTerminationPolicy(policyType) }) @@ -1120,9 +1002,9 @@ var _ = Describe("Cluster Controller", func() { createClusterObjNoWait(clusterDefObj.Name, componentProcessorWrapper(defaultCompName, mockCompDefName)) By("check conditions") - Eventually(testapps.CheckObj(&testCtx, clusterKey, func(g Gomega, cluster *appsv1alpha1.Cluster) { + Eventually(testapps.CheckObj(&testCtx, clusterKey, func(g Gomega, cluster *appsv1.Cluster) { g.Expect(cluster.Status.ObservedGeneration).Should(BeZero()) - condition := meta.FindStatusCondition(cluster.Status.Conditions, appsv1alpha1.ConditionTypeProvisioningStarted) + condition := meta.FindStatusCondition(cluster.Status.Conditions, appsv1.ConditionTypeProvisioningStarted) g.Expect(condition).ShouldNot(BeNil()) g.Expect(condition.Reason).Should(BeEquivalentTo(ReasonPreCheckFailed)) })).Should(Succeed()) @@ -1140,7 +1022,7 @@ var _ = Describe("Cluster Controller", func() { createAllDefinitionObjects() }) - createClusterWithBackup := func(backup *appsv1alpha1.ClusterBackup) { + createClusterWithBackup := func(backup *appsv1.ClusterBackup) { By("Creating a cluster") clusterObj := testapps.NewClusterFactory(testCtx.DefaultNamespace, clusterName, ""). WithRandomName(). @@ -1175,11 +1057,11 @@ var _ = Describe("Cluster Controller", func() { var testCases = []struct { desc string - backup *appsv1alpha1.ClusterBackup + backup *appsv1.ClusterBackup }{ { desc: "backup with snapshot method", - backup: &appsv1alpha1.ClusterBackup{ + backup: &appsv1.ClusterBackup{ Enabled: &boolTrue, RetentionPeriod: retention("1d"), Method: vsBackupMethodName, @@ -1191,7 +1073,7 @@ var _ = Describe("Cluster Controller", func() { }, { desc: "disable backup", - backup: &appsv1alpha1.ClusterBackup{ + backup: &appsv1.ClusterBackup{ Enabled: &boolFalse, RetentionPeriod: retention("1d"), Method: vsBackupMethodName, @@ -1203,7 +1085,7 @@ var _ = Describe("Cluster Controller", func() { }, { desc: "backup with backup tool", - backup: &appsv1alpha1.ClusterBackup{ + backup: &appsv1.ClusterBackup{ Enabled: &boolTrue, RetentionPeriod: retention("2d"), Method: backupMethodName, @@ -1297,24 +1179,6 @@ var _ = Describe("Cluster Controller", func() { }) }) - Context("cluster affinity and toleration", func() { - BeforeEach(func() { - createAllDefinitionObjects() - }) - - AfterEach(func() { - cleanEnv() - }) - - It("with cluster affinity and toleration set", func() { - testClusterAffinityNToleration(defaultCompName, compDefName, createClusterObj) - }) - - It("with both cluster and component affinity and toleration set", func() { - testClusterComponentAffinityNToleration(defaultCompName, compDefName, createClusterObj) - }) - }) - Context("cluster upgrade", func() { BeforeEach(func() { createAllDefinitionObjects() @@ -1331,7 +1195,7 @@ var _ = Describe("Cluster Controller", func() { testClusterComponentWithTopology(defaultTopology.Name, defaultCompName, setServiceVersion, compDefObj.Name, defaultServiceVersion) By("update cluster to upgrade service version") - Expect(testapps.GetAndChangeObj(&testCtx, clusterKey, func(cluster *appsv1alpha1.Cluster) { + Expect(testapps.GetAndChangeObj(&testCtx, clusterKey, func(cluster *appsv1.Cluster) { cluster.Spec.ComponentSpecs[0].ServiceVersion = latestServiceVersion })()).ShouldNot(HaveOccurred()) @@ -1340,7 +1204,7 @@ var _ = Describe("Cluster Controller", func() { Namespace: clusterObj.Namespace, Name: constant.GenerateClusterComponentName(clusterObj.Name, defaultCompName), } - Eventually(testapps.CheckObj(&testCtx, clusterKey, func(g Gomega, cluster *appsv1alpha1.Cluster) { + Eventually(testapps.CheckObj(&testCtx, clusterKey, func(g Gomega, cluster *appsv1.Cluster) { g.Expect(cluster.Spec.ComponentSpecs[0].ComponentDef).Should(Equal(compDefObj.Name)) g.Expect(cluster.Spec.ComponentSpecs[0].ServiceVersion).Should(Equal(latestServiceVersion)) })).Should(Succeed()) @@ -1372,7 +1236,7 @@ var _ = Describe("Cluster Controller", func() { Namespace: clusterObj.Namespace, Name: constant.GenerateClusterComponentName(clusterObj.Name, defaultCompName), } - Consistently(testapps.CheckObj(&testCtx, clusterKey, func(g Gomega, cluster *appsv1alpha1.Cluster) { + Consistently(testapps.CheckObj(&testCtx, clusterKey, func(g Gomega, cluster *appsv1.Cluster) { g.Expect(cluster.Spec.ComponentSpecs[0].ComponentDef).Should(Equal(compDefObj.Name)) g.Expect(cluster.Spec.ComponentSpecs[0].ServiceVersion).Should(Equal(defaultServiceVersion)) })).Should(Succeed()) @@ -1382,12 +1246,12 @@ var _ = Describe("Cluster Controller", func() { })).Should(Succeed()) By("update cluster to upgrade component definition") - Expect(testapps.GetAndChangeObj(&testCtx, clusterKey, func(cluster *appsv1alpha1.Cluster) { + Expect(testapps.GetAndChangeObj(&testCtx, clusterKey, func(cluster *appsv1.Cluster) { cluster.Spec.ComponentSpecs[0].ComponentDef = "" })()).ShouldNot(HaveOccurred()) By("check cluster and component objects been upgraded") - Eventually(testapps.CheckObj(&testCtx, clusterKey, func(g Gomega, cluster *appsv1alpha1.Cluster) { + Eventually(testapps.CheckObj(&testCtx, clusterKey, func(g Gomega, cluster *appsv1.Cluster) { g.Expect(cluster.Spec.ComponentSpecs[0].ComponentDef).Should(Equal(newCompDefObj.Name)) g.Expect(cluster.Spec.ComponentSpecs[0].ServiceVersion).Should(Equal(defaultServiceVersion)) })).Should(Succeed()) diff --git a/controllers/apps/cluster_plan_builder.go b/controllers/apps/cluster_plan_builder.go index 4c75e260c6a..efe2b130e2e 100644 --- a/controllers/apps/cluster_plan_builder.go +++ b/controllers/apps/cluster_plan_builder.go @@ -54,14 +54,14 @@ type clusterTransformContext struct { Client client.Reader record.EventRecorder logr.Logger - Cluster *appsv1alpha1.Cluster - OrigCluster *appsv1alpha1.Cluster + Cluster *appsv1.Cluster + OrigCluster *appsv1.Cluster ClusterDef *appsv1.ClusterDefinition ComponentDefs map[string]*appsv1.ComponentDefinition // ComponentSpecs includes all cluster component specs generated from ComponentSpecs and ShardingSpecs - ComponentSpecs []*appsv1alpha1.ClusterComponentSpec + ComponentSpecs []*appsv1.ClusterComponentSpec // ShardingComponentSpecs includes all sharding component specs generated from ShardingSpecs - ShardingComponentSpecs map[string][]*appsv1alpha1.ClusterComponentSpec + ShardingComponentSpecs map[string][]*appsv1.ClusterComponentSpec // Labels to be added to components, mapping with ComponentSpecs. Labels map[string]map[string]string // Annotations to be added to components, mapping with ComponentSpecs. @@ -119,7 +119,7 @@ func init() { // PlanBuilder implementation func (c *clusterPlanBuilder) Init() error { - cluster := &appsv1alpha1.Cluster{} + cluster := &appsv1.Cluster{} if err := c.cli.Get(c.transCtx.Context, c.req.NamespacedName, cluster); err != nil { return err } @@ -146,7 +146,7 @@ func (c *clusterPlanBuilder) Build() (graph.Plan, error) { if c.transCtx.Cluster.IsDeleting() { return } - preCheckCondition := meta.FindStatusCondition(c.transCtx.Cluster.Status.Conditions, appsv1alpha1.ConditionTypeProvisioningStarted) + preCheckCondition := meta.FindStatusCondition(c.transCtx.Cluster.Status.Conditions, appsv1.ConditionTypeProvisioningStarted) if preCheckCondition == nil { // this should not happen return @@ -238,7 +238,7 @@ func (c *clusterPlanBuilder) defaultWalkFunc(vertex graph.Vertex) error { } // cluster object has more business to do, handle them here - if _, ok = node.Obj.(*appsv1alpha1.Cluster); ok { + if _, ok = node.Obj.(*appsv1.Cluster); ok { if err := c.reconcileCluster(node); err != nil { return err } @@ -247,8 +247,8 @@ func (c *clusterPlanBuilder) defaultWalkFunc(vertex graph.Vertex) error { } func (c *clusterPlanBuilder) reconcileCluster(node *model.ObjectVertex) error { - cluster := node.Obj.(*appsv1alpha1.Cluster).DeepCopy() - origCluster := node.OriObj.(*appsv1alpha1.Cluster) + cluster := node.Obj.(*appsv1.Cluster).DeepCopy() + origCluster := node.OriObj.(*appsv1.Cluster) switch *node.Action { // cluster.meta and cluster.spec might change case model.STATUS: @@ -326,7 +326,7 @@ func (c *clusterPlanBuilder) reconcileDeleteObject(ctx context.Context, node *mo return nil } // delete secondary objects - if _, ok := node.Obj.(*appsv1alpha1.Cluster); !ok { + if _, ok := node.Obj.(*appsv1.Cluster); !ok { err := backgroundDeleteObject() if err != nil && !apierrors.IsNotFound(err) { return err @@ -341,8 +341,8 @@ func (c *clusterPlanBuilder) reconcileStatusObject(ctx context.Context, node *mo return err } // handle condition and phase changing triggered events - if newCluster, ok := node.Obj.(*appsv1alpha1.Cluster); ok { - oldCluster, _ := node.OriObj.(*appsv1alpha1.Cluster) + if newCluster, ok := node.Obj.(*appsv1.Cluster); ok { + oldCluster, _ := node.OriObj.(*appsv1.Cluster) c.emitConditionUpdatingEvent(oldCluster.Status.Conditions, newCluster.Status.Conditions) c.emitStatusUpdatingEvent(oldCluster.Status, newCluster.Status) } @@ -370,7 +370,7 @@ func (c *clusterPlanBuilder) emitConditionUpdatingEvent(oldConditions, newCondit } } -func (c *clusterPlanBuilder) emitStatusUpdatingEvent(oldStatus, newStatus appsv1alpha1.ClusterStatus) { +func (c *clusterPlanBuilder) emitStatusUpdatingEvent(oldStatus, newStatus appsv1.ClusterStatus) { cluster := c.transCtx.Cluster newPhase := newStatus.Phase if newPhase == oldStatus.Phase { @@ -379,11 +379,11 @@ func (c *clusterPlanBuilder) emitStatusUpdatingEvent(oldStatus, newStatus appsv1 eType := corev1.EventTypeNormal message := "" switch newPhase { - case appsv1alpha1.RunningClusterPhase: + case appsv1.RunningClusterPhase: message = fmt.Sprintf("Cluster: %s is ready, current phase is %s", cluster.Name, newPhase) - case appsv1alpha1.StoppedClusterPhase: + case appsv1.StoppedClusterPhase: message = fmt.Sprintf("Cluster: %s stopped successfully.", cluster.Name) - case appsv1alpha1.FailedClusterPhase, appsv1alpha1.AbnormalClusterPhase: + case appsv1.FailedClusterPhase, appsv1.AbnormalClusterPhase: message = fmt.Sprintf("Cluster: %s is %s, check according to the components message", cluster.Name, newPhase) eType = corev1.EventTypeWarning } diff --git a/controllers/apps/cluster_plan_builder_test.go b/controllers/apps/cluster_plan_builder_test.go index 6699ff5875e..5e214f8215d 100644 --- a/controllers/apps/cluster_plan_builder_test.go +++ b/controllers/apps/cluster_plan_builder_test.go @@ -27,7 +27,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/log" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" intctrlutil "github.com/apecloud/kubeblocks/pkg/controllerutil" "github.com/apecloud/kubeblocks/pkg/generics" testapps "github.com/apecloud/kubeblocks/pkg/testutil/apps" @@ -80,7 +80,7 @@ var _ = Describe("cluster plan builder test", func() { GetObject() Expect(testCtx.Cli.Create(testCtx.Ctx, clusterObj)).Should(Succeed()) clusterKey := client.ObjectKeyFromObject(clusterObj) - Eventually(testapps.CheckObjExists(&testCtx, clusterKey, &appsv1alpha1.Cluster{}, true)).Should(Succeed()) + Eventually(testapps.CheckObjExists(&testCtx, clusterKey, &appsv1.Cluster{}, true)).Should(Succeed()) req := ctrl.Request{ NamespacedName: clusterKey, } diff --git a/controllers/apps/cluster_status_conditions.go b/controllers/apps/cluster_status_conditions.go index e35ab95e96d..f1e2d01444d 100644 --- a/controllers/apps/cluster_status_conditions.go +++ b/controllers/apps/cluster_status_conditions.go @@ -27,7 +27,7 @@ import ( "k8s.io/apimachinery/pkg/api/meta" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" intctrlutil "github.com/apecloud/kubeblocks/pkg/controllerutil" ) @@ -55,7 +55,7 @@ func setProvisioningStartedCondition(conditions *[]metav1.Condition, clusterName // newProvisioningStartedCondition creates the provisioning started condition in cluster conditions. func newProvisioningStartedCondition(clusterName string, clusterGeneration int64) metav1.Condition { return metav1.Condition{ - Type: appsv1alpha1.ConditionTypeProvisioningStarted, + Type: appsv1.ConditionTypeProvisioningStarted, ObservedGeneration: clusterGeneration, Status: metav1.ConditionTrue, Message: fmt.Sprintf("The operator has started the provisioning of Cluster: %s", clusterName), @@ -77,7 +77,7 @@ func getConditionReasonWithError(defaultReason string, err error) string { // newApplyResourcesCondition creates a condition when applied resources succeed. func newFailedProvisioningStartedCondition(err error) metav1.Condition { return metav1.Condition{ - Type: appsv1alpha1.ConditionTypeProvisioningStarted, + Type: appsv1.ConditionTypeProvisioningStarted, Status: metav1.ConditionFalse, Message: err.Error(), Reason: getConditionReasonWithError(ReasonPreCheckFailed, err), @@ -96,7 +96,7 @@ func setApplyResourceCondition(conditions *[]metav1.Condition, clusterGeneration // newApplyResourcesCondition creates a condition when applied resources succeed. func newApplyResourcesCondition(clusterGeneration int64) metav1.Condition { return metav1.Condition{ - Type: appsv1alpha1.ConditionTypeApplyResources, + Type: appsv1.ConditionTypeApplyResources, ObservedGeneration: clusterGeneration, Status: metav1.ConditionTrue, Message: "Successfully applied for resources", @@ -107,7 +107,7 @@ func newApplyResourcesCondition(clusterGeneration int64) metav1.Condition { // newApplyResourcesCondition creates a condition when applied resources succeed. func newFailedApplyResourcesCondition(err error) metav1.Condition { return metav1.Condition{ - Type: appsv1alpha1.ConditionTypeApplyResources, + Type: appsv1.ConditionTypeApplyResources, Status: metav1.ConditionFalse, Message: err.Error(), Reason: getConditionReasonWithError(ReasonApplyResourcesFailed, err), @@ -117,7 +117,7 @@ func newFailedApplyResourcesCondition(err error) metav1.Condition { // newAllReplicasPodsReadyConditions creates a condition when all pods of components are ready func newAllReplicasPodsReadyConditions() metav1.Condition { return metav1.Condition{ - Type: appsv1alpha1.ConditionTypeReplicasReady, + Type: appsv1.ConditionTypeReplicasReady, Status: metav1.ConditionTrue, Message: "all pods of components are ready, waiting for the probe detection successful", Reason: ReasonAllReplicasReady, @@ -129,7 +129,7 @@ func newReplicasNotReadyCondition(notReadyComponentNames map[string]struct{}) me cNameSlice := maps.Keys(notReadyComponentNames) slices.Sort(cNameSlice) return metav1.Condition{ - Type: appsv1alpha1.ConditionTypeReplicasReady, + Type: appsv1.ConditionTypeReplicasReady, Status: metav1.ConditionFalse, Message: fmt.Sprintf("pods are not ready in Components: %v, refer to related component message in Cluster.status.components", cNameSlice), Reason: ReasonReplicasNotReady, @@ -139,7 +139,7 @@ func newReplicasNotReadyCondition(notReadyComponentNames map[string]struct{}) me // newClusterReadyCondition creates a condition when all components of cluster are running func newClusterReadyCondition(clusterName string) metav1.Condition { return metav1.Condition{ - Type: appsv1alpha1.ConditionTypeReady, + Type: appsv1.ConditionTypeReady, Status: metav1.ConditionTrue, Message: fmt.Sprintf("Cluster: %s is ready, current phase is Running", clusterName), Reason: ReasonClusterReady, @@ -151,7 +151,7 @@ func newComponentsNotReadyCondition(notReadyComponentNames map[string]struct{}) cNameSlice := maps.Keys(notReadyComponentNames) slices.Sort(cNameSlice) return metav1.Condition{ - Type: appsv1alpha1.ConditionTypeReady, + Type: appsv1.ConditionTypeReady, Status: metav1.ConditionFalse, Message: fmt.Sprintf("pods are unavailable in Components: %v, refer to related component message in Cluster.status.components", cNameSlice), Reason: ReasonComponentsNotReady, diff --git a/controllers/apps/clusterdefinition_controller.go b/controllers/apps/clusterdefinition_controller.go index 500589949c7..3ca0c6cab69 100644 --- a/controllers/apps/clusterdefinition_controller.go +++ b/controllers/apps/clusterdefinition_controller.go @@ -33,7 +33,6 @@ import ( "sigs.k8s.io/controller-runtime/pkg/log" appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" appsconfig "github.com/apecloud/kubeblocks/controllers/apps/configuration" "github.com/apecloud/kubeblocks/pkg/constant" intctrlutil "github.com/apecloud/kubeblocks/pkg/controllerutil" @@ -97,7 +96,7 @@ func (r *ClusterDefinitionReconciler) Reconcile(ctx context.Context, req ctrl.Re // SetupWithManager sets up the controller with the Manager. func (r *ClusterDefinitionReconciler) SetupWithManager(mgr ctrl.Manager) error { return intctrlutil.NewNamespacedControllerManagedBy(mgr). - For(&appsv1alpha1.ClusterDefinition{}). + For(&appsv1.ClusterDefinition{}). Complete(r) } @@ -108,7 +107,7 @@ func (r *ClusterDefinitionReconciler) deletionHandler(rctx intctrlutil.RequestCt "cannot be deleted because of existing referencing Cluster") } if res, err := intctrlutil.ValidateReferenceCR(rctx, r.Client, clusterDef, constant.ClusterDefLabelKey, - recordEvent, &appsv1alpha1.ClusterList{}); res != nil || err != nil { + recordEvent, &appsv1.ClusterList{}); res != nil || err != nil { return res, err } return nil, r.deleteExternalResources(rctx, clusterDef) diff --git a/controllers/apps/component_controller_test.go b/controllers/apps/component_controller_test.go index 359e7a8f3bd..0ad24cc5f69 100644 --- a/controllers/apps/component_controller_test.go +++ b/controllers/apps/component_controller_test.go @@ -49,7 +49,6 @@ import ( "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" kbappsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" dpv1alpha1 "github.com/apecloud/kubeblocks/apis/dataprotection/v1alpha1" workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" "github.com/apecloud/kubeblocks/pkg/constant" @@ -138,7 +137,7 @@ var _ = Describe("Component Controller", func() { var ( compDefObj *kbappsv1.ComponentDefinition compVerObj *kbappsv1.ComponentVersion - clusterObj *appsv1alpha1.Cluster + clusterObj *kbappsv1.Cluster clusterKey types.NamespacedName compObj *kbappsv1.Component compKey types.NamespacedName @@ -219,13 +218,13 @@ var _ = Describe("Component Controller", func() { waitForCreatingResourceCompletely := func(clusterKey client.ObjectKey, compNames ...string) { Eventually(testapps.GetClusterObservedGeneration(&testCtx, clusterKey)).Should(BeEquivalentTo(1)) - cluster := &appsv1alpha1.Cluster{} + cluster := &kbappsv1.Cluster{} Eventually(testapps.CheckObjExists(&testCtx, clusterKey, cluster, true)).Should(Succeed()) for _, compName := range compNames { - compPhase := appsv1alpha1.CreatingClusterCompPhase + compPhase := kbappsv1.CreatingClusterCompPhase for _, spec := range cluster.Spec.ComponentSpecs { if spec.Name == compName && spec.Replicas == 0 { - compPhase = appsv1alpha1.StoppedClusterCompPhase + compPhase = kbappsv1.StoppedClusterCompPhase } } Eventually(testapps.GetClusterComponentPhase(&testCtx, clusterKey, compName)).Should(Equal(compPhase)) @@ -233,7 +232,7 @@ var _ = Describe("Component Controller", func() { } createClusterObjX := func(clusterDefName, compName, compDefName string, - processor func(*testapps.MockClusterFactory), phase *appsv1alpha1.ClusterPhase) { + processor func(*testapps.MockClusterFactory), phase *kbappsv1.ClusterPhase) { factory := testapps.NewClusterFactory(testCtx.DefaultNamespace, clusterName, clusterDefName). WithRandomName(). AddComponent(compName, compDefName). @@ -247,7 +246,7 @@ var _ = Describe("Component Controller", func() { By("Waiting for the cluster enter expected phase") Eventually(testapps.GetClusterObservedGeneration(&testCtx, clusterKey)).Should(BeEquivalentTo(1)) if phase == nil { - Eventually(testapps.GetClusterPhase(&testCtx, clusterKey)).Should(Equal(appsv1alpha1.CreatingClusterPhase)) + Eventually(testapps.GetClusterPhase(&testCtx, clusterKey)).Should(Equal(kbappsv1.CreatingClusterPhase)) } else { Eventually(testapps.GetClusterPhase(&testCtx, clusterKey)).Should(Equal(*phase)) } @@ -270,7 +269,7 @@ var _ = Describe("Component Controller", func() { createClusterObjX("", compName, compDefName, processor, nil) } - createClusterObjWithPhase := func(compName, compDefName string, processor func(*testapps.MockClusterFactory), phase appsv1alpha1.ClusterPhase) { + createClusterObjWithPhase := func(compName, compDefName string, processor func(*testapps.MockClusterFactory), phase kbappsv1.ClusterPhase) { By("Creating a cluster with new component definition") createClusterObjX("", compName, compDefName, processor, &phase) } @@ -286,7 +285,7 @@ var _ = Describe("Component Controller", func() { Eventually(testapps.GetComponentPhase(&testCtx, types.NamespacedName{ Namespace: clusterObj.Namespace, Name: component.FullName(clusterObj.Name, compName), - })).Should(Equal(appsv1alpha1.RunningClusterCompPhase)) + })).Should(Equal(kbappsv1.RunningClusterCompPhase)) } // createCompObj := func(compName, compDefName, serviceVersion string, processor func(*testapps.MockComponentFactory)) { @@ -306,12 +305,12 @@ var _ = Describe("Component Controller", func() { // // Eventually(testapps.CheckObj(&testCtx, compKey, func(g Gomega, comp *kbappsv1.Component) { // g.Expect(comp.Status.ObservedGeneration).To(BeEquivalentTo(comp.Generation)) - // g.Expect(comp.Status.Phase).To(Equal(appsv1alpha1.CreatingClusterCompPhase)) + // g.Expect(comp.Status.Phase).To(Equal(kbappsv1.CreatingClusterCompPhase)) // })).Should(Succeed()) // } - changeCompReplicas := func(clusterName types.NamespacedName, replicas int32, comp *appsv1alpha1.ClusterComponentSpec) { - Expect(testapps.GetAndChangeObj(&testCtx, clusterName, func(cluster *appsv1alpha1.Cluster) { + changeCompReplicas := func(clusterName types.NamespacedName, replicas int32, comp *kbappsv1.ClusterComponentSpec) { + Expect(testapps.GetAndChangeObj(&testCtx, clusterName, func(cluster *kbappsv1.Cluster) { for i, clusterComp := range cluster.Spec.ComponentSpecs { if clusterComp.Name == comp.Name { cluster.Spec.ComponentSpecs[i].Replicas = replicas @@ -321,7 +320,7 @@ var _ = Describe("Component Controller", func() { } changeComponentReplicas := func(clusterName types.NamespacedName, replicas int32) { - Expect(testapps.GetAndChangeObj(&testCtx, clusterName, func(cluster *appsv1alpha1.Cluster) { + Expect(testapps.GetAndChangeObj(&testCtx, clusterName, func(cluster *kbappsv1.Cluster) { Expect(cluster.Spec.ComponentSpecs).Should(HaveLen(1)) cluster.Spec.ComponentSpecs[0].Replicas = replicas })()).ShouldNot(HaveOccurred()) @@ -337,9 +336,9 @@ var _ = Describe("Component Controller", func() { expectedOG++ By("Checking cluster status and the number of replicas changed") - Eventually(testapps.CheckObj(&testCtx, clusterKey, func(g Gomega, fetched *appsv1alpha1.Cluster) { + Eventually(testapps.CheckObj(&testCtx, clusterKey, func(g Gomega, fetched *kbappsv1.Cluster) { g.Expect(fetched.Status.ObservedGeneration).To(BeEquivalentTo(expectedOG)) - g.Eventually(testapps.GetClusterPhase(&testCtx, clusterKey)).Should(BeElementOf(appsv1alpha1.CreatingClusterPhase, appsv1alpha1.UpdatingClusterPhase)) + g.Eventually(testapps.GetClusterPhase(&testCtx, clusterKey)).Should(BeElementOf(kbappsv1.CreatingClusterPhase, kbappsv1.UpdatingClusterPhase)) })).Should(Succeed()) itsKey := compKey @@ -435,7 +434,7 @@ var _ = Describe("Component Controller", func() { CheckedCreate(&testCtx) } - mockComponentPVCsAndBound := func(comp *appsv1alpha1.ClusterComponentSpec, replicas int, create bool, storageClassName string) { + mockComponentPVCsAndBound := func(comp *kbappsv1.ClusterComponentSpec, replicas int, create bool, storageClassName string) { for i := 0; i < replicas; i++ { for _, vct := range comp.VolumeClaimTemplates { pvcKey := types.NamespacedName{ @@ -458,7 +457,7 @@ var _ = Describe("Component Controller", func() { } } - mockPodsForTest := func(cluster *appsv1alpha1.Cluster, number int) []corev1.Pod { + mockPodsForTest := func(cluster *kbappsv1.Cluster, number int) []corev1.Pod { componentName := cluster.Spec.ComponentSpecs[0].Name compDefName := cluster.Spec.ComponentSpecs[0].ComponentDef clusterName := cluster.Name @@ -494,7 +493,7 @@ var _ = Describe("Component Controller", func() { return pods } - horizontalScaleComp := func(updatedReplicas int, comp *appsv1alpha1.ClusterComponentSpec, storageClassName string, bpt *string) { + horizontalScaleComp := func(updatedReplicas int, comp *kbappsv1.ClusterComponentSpec, storageClassName string, bpt *string) { By("Mocking component PVCs to bound") mockComponentPVCsAndBound(comp, int(comp.Replicas), true, storageClassName) @@ -567,7 +566,7 @@ var _ = Describe("Component Controller", func() { }, }, } - scheme, _ := appsv1alpha1.SchemeBuilder.Build() + scheme, _ := kbappsv1.SchemeBuilder.Build() Expect(controllerruntime.SetControllerReference(clusterObj, volumeSnapshot, scheme)).Should(Succeed()) Expect(testCtx.CreateObj(testCtx.Ctx, volumeSnapshot)).Should(Succeed()) readyToUse := true @@ -699,7 +698,7 @@ var _ = Describe("Component Controller", func() { horizontalScale := func(updatedReplicas int, storageClassName string, policyType *string, compDefNames ...string) { defer kbagent.UnsetMockClient() - cluster := &appsv1alpha1.Cluster{} + cluster := &kbappsv1.Cluster{} Expect(k8sClient.Get(testCtx.Ctx, clusterKey, cluster)).Should(Succeed()) initialGeneration := int(cluster.Status.ObservedGeneration) @@ -710,7 +709,7 @@ var _ = Describe("Component Controller", func() { mockComponentPVCsAndBound(&comp, int(comp.Replicas), true, storageClassName) } - bpt := func(comp appsv1alpha1.ClusterComponentSpec) *string { + bpt := func(comp kbappsv1.ClusterComponentSpec) *string { compDef := &kbappsv1.ComponentDefinition{} Expect(k8sClient.Get(testCtx.Ctx, types.NamespacedName{Name: comp.ComponentDef}, compDef)).Should(Succeed()) if len(compDef.Annotations) > 0 { @@ -810,11 +809,11 @@ var _ = Describe("Component Controller", func() { })).ShouldNot(HaveOccurred()) Eventually(testapps.GetClusterObservedGeneration(&testCtx, clusterKey)).Should(BeEquivalentTo(1)) - Eventually(testapps.GetClusterComponentPhase(&testCtx, clusterKey, compName)).Should(Equal(appsv1alpha1.RunningClusterCompPhase)) - Eventually(testapps.GetClusterPhase(&testCtx, clusterKey)).Should(Equal(appsv1alpha1.RunningClusterPhase)) + Eventually(testapps.GetClusterComponentPhase(&testCtx, clusterKey, compName)).Should(Equal(kbappsv1.RunningClusterCompPhase)) + Eventually(testapps.GetClusterPhase(&testCtx, clusterKey)).Should(Equal(kbappsv1.RunningClusterPhase)) By("Updating data PVC storage size") - Expect(testapps.GetAndChangeObj(&testCtx, clusterKey, func(cluster *appsv1alpha1.Cluster) { + Expect(testapps.GetAndChangeObj(&testCtx, clusterKey, func(cluster *kbappsv1.Cluster) { comp := &cluster.Spec.ComponentSpecs[0] for i, vct := range comp.VolumeClaimTemplates { if vct.Name == testapps.DataVolumeName { @@ -825,8 +824,8 @@ var _ = Describe("Component Controller", func() { By("Checking the resize operation in progress for data volume") Eventually(testapps.GetClusterObservedGeneration(&testCtx, clusterKey)).Should(BeEquivalentTo(2)) - Eventually(testapps.GetClusterComponentPhase(&testCtx, clusterKey, compName)).Should(Equal(appsv1alpha1.UpdatingClusterCompPhase)) - Eventually(testapps.GetClusterPhase(&testCtx, clusterKey)).Should(Equal(appsv1alpha1.UpdatingClusterPhase)) + Eventually(testapps.GetClusterComponentPhase(&testCtx, clusterKey, compName)).Should(Equal(kbappsv1.UpdatingClusterCompPhase)) + Eventually(testapps.GetClusterPhase(&testCtx, clusterKey)).Should(Equal(kbappsv1.UpdatingClusterPhase)) for i := 0; i < replicas; i++ { pvc := &corev1.PersistentVolumeClaim{} pvcKey := types.NamespacedName{ @@ -856,8 +855,8 @@ var _ = Describe("Component Controller", func() { testk8s.MockInstanceSetReady(its, mockPods...) })()).ShouldNot(HaveOccurred()) Eventually(testapps.GetClusterObservedGeneration(&testCtx, clusterKey)).Should(BeEquivalentTo(2)) - Eventually(testapps.GetClusterComponentPhase(&testCtx, clusterKey, compName)).Should(Equal(appsv1alpha1.RunningClusterCompPhase)) - Eventually(testapps.GetClusterPhase(&testCtx, clusterKey)).Should(Equal(appsv1alpha1.RunningClusterPhase)) + Eventually(testapps.GetClusterComponentPhase(&testCtx, clusterKey, compName)).Should(Equal(kbappsv1.RunningClusterCompPhase)) + Eventually(testapps.GetClusterPhase(&testCtx, clusterKey)).Should(Equal(kbappsv1.RunningClusterPhase)) By("Checking data volumes are resized") for i := 0; i < replicas; i++ { @@ -951,7 +950,7 @@ var _ = Describe("Component Controller", func() { } changePVC := func(quantity resource.Quantity) { - Expect(testapps.GetAndChangeObj(&testCtx, clusterKey, func(cluster *appsv1alpha1.Cluster) { + Expect(testapps.GetAndChangeObj(&testCtx, clusterKey, func(cluster *kbappsv1.Cluster) { comp := &cluster.Spec.ComponentSpecs[0] comp.VolumeClaimTemplates[0].Spec.Resources.Requests[corev1.ResourceStorage] = quantity })()).ShouldNot(HaveOccurred()) @@ -1092,7 +1091,7 @@ var _ = Describe("Component Controller", func() { } testCompSystemAccountOverride := func(compName, compDefName string) { - passwordConfig := &appsv1alpha1.PasswordConfig{ + passwordConfig := &kbappsv1.PasswordConfig{ Length: 29, } secret := corev1.Secret{ @@ -1104,9 +1103,9 @@ var _ = Describe("Component Controller", func() { constant.AccountPasswdForSecret: "sysaccount-override", }, } - secretRef := func() *appsv1alpha1.ProvisionSecretRef { + secretRef := func() *kbappsv1.ProvisionSecretRef { Expect(testCtx.CreateObj(testCtx.Ctx, &secret)).Should(Succeed()) - return &appsv1alpha1.ProvisionSecretRef{ + return &kbappsv1.ProvisionSecretRef{ Name: secret.Name, Namespace: testCtx.DefaultNamespace, } @@ -1453,8 +1452,8 @@ var _ = Describe("Component Controller", func() { testCompTLSConfig := func(compName, compDefName string) { createClusterObj(compName, compDefName, func(f *testapps.MockClusterFactory) { - issuer := &appsv1alpha1.Issuer{ - Name: appsv1alpha1.IssuerKubeBlocks, + issuer := &kbappsv1.Issuer{ + Name: kbappsv1.IssuerKubeBlocks, } f.SetTLS(true).SetIssuer(issuer) }) @@ -1507,56 +1506,56 @@ var _ = Describe("Component Controller", func() { testCompConfiguration := func(compName, compDefName string) { } - testCompAffinityNToleration := func(compName, compDefName string) { - const ( - topologyKey = "testTopologyKey" - labelKey = "testNodeLabelKey" - labelValue = "testNodeLabelValue" - tolerationKey = "testTolerationKey" - tolerationValue = "testTolerationValue" - ) - - By("Creating a component with affinity and toleration") - affinity := appsv1alpha1.Affinity{ - PodAntiAffinity: appsv1alpha1.Required, - TopologyKeys: []string{topologyKey}, - NodeLabels: map[string]string{ - labelKey: labelValue, - }, - Tenancy: appsv1alpha1.SharedNode, - } - toleration := corev1.Toleration{ - Key: tolerationKey, - Value: tolerationValue, - Operator: corev1.TolerationOpEqual, - Effect: corev1.TaintEffectNoSchedule, - } - createClusterObj(compName, compDefName, func(f *testapps.MockClusterFactory) { - f.SetComponentAffinity(&affinity).AddComponentToleration(toleration) - }) - - By("Checking the Affinity, the TopologySpreadConstraints and Tolerations") - itsKey := types.NamespacedName{ - Namespace: compObj.Namespace, - Name: compObj.Name, - } - Eventually(testapps.CheckObj(&testCtx, itsKey, func(g Gomega, its *workloads.InstanceSet) { - podSpec := its.Spec.Template.Spec - // node affinity - g.Expect(podSpec.Affinity.NodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution.NodeSelectorTerms[0].MatchExpressions[0].Key).To(Equal(labelKey)) - // pod anti-affinity - g.Expect(podSpec.Affinity.PodAntiAffinity.RequiredDuringSchedulingIgnoredDuringExecution).Should(HaveLen(1)) - g.Expect(podSpec.Affinity.PodAntiAffinity.RequiredDuringSchedulingIgnoredDuringExecution[0].TopologyKey).To(Equal(topologyKey)) - // topology spread constraint - g.Expect(podSpec.TopologySpreadConstraints).Should(HaveLen(1)) - // Required -> DoNotSchedule, Preferred -> ScheduleAnyway - g.Expect(podSpec.TopologySpreadConstraints[0].WhenUnsatisfiable).To(Equal(corev1.DoNotSchedule)) - g.Expect(podSpec.TopologySpreadConstraints[0].TopologyKey).To(Equal(topologyKey)) - // toleration - g.Expect(podSpec.Tolerations).Should(HaveLen(2)) - g.Expect(podSpec.Tolerations[0]).Should(BeEquivalentTo(toleration)) - })).Should(Succeed()) - } + // testCompAffinityNToleration := func(compName, compDefName string) { + // const ( + // topologyKey = "testTopologyKey" + // labelKey = "testNodeLabelKey" + // labelValue = "testNodeLabelValue" + // tolerationKey = "testTolerationKey" + // tolerationValue = "testTolerationValue" + // ) + // + // By("Creating a component with affinity and toleration") + // affinity := appsv1alpha1.Affinity{ + // PodAntiAffinity: appsv1alpha1.Required, + // TopologyKeys: []string{topologyKey}, + // NodeLabels: map[string]string{ + // labelKey: labelValue, + // }, + // Tenancy: appsv1alpha1.SharedNode, + // } + // toleration := corev1.Toleration{ + // Key: tolerationKey, + // Value: tolerationValue, + // Operator: corev1.TolerationOpEqual, + // Effect: corev1.TaintEffectNoSchedule, + // } + // createClusterObj(compName, compDefName, func(f *testapps.MockClusterFactory) { + // f.SetComponentAffinity(&affinity).AddComponentToleration(toleration) + // }) + // + // By("Checking the Affinity, the TopologySpreadConstraints and Tolerations") + // itsKey := types.NamespacedName{ + // Namespace: compObj.Namespace, + // Name: compObj.Name, + // } + // Eventually(testapps.CheckObj(&testCtx, itsKey, func(g Gomega, its *workloads.InstanceSet) { + // podSpec := its.Spec.Template.Spec + // // node affinity + // g.Expect(podSpec.Affinity.NodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution.NodeSelectorTerms[0].MatchExpressions[0].Key).To(Equal(labelKey)) + // // pod anti-affinity + // g.Expect(podSpec.Affinity.PodAntiAffinity.RequiredDuringSchedulingIgnoredDuringExecution).Should(HaveLen(1)) + // g.Expect(podSpec.Affinity.PodAntiAffinity.RequiredDuringSchedulingIgnoredDuringExecution[0].TopologyKey).To(Equal(topologyKey)) + // // topology spread constraint + // g.Expect(podSpec.TopologySpreadConstraints).Should(HaveLen(1)) + // // Required -> DoNotSchedule, Preferred -> ScheduleAnyway + // g.Expect(podSpec.TopologySpreadConstraints[0].WhenUnsatisfiable).To(Equal(corev1.DoNotSchedule)) + // g.Expect(podSpec.TopologySpreadConstraints[0].TopologyKey).To(Equal(topologyKey)) + // // toleration + // g.Expect(podSpec.Tolerations).Should(HaveLen(2)) + // g.Expect(podSpec.Tolerations[0]).Should(BeEquivalentTo(toleration)) + // })).Should(Succeed()) + // } checkRBACResourcesExistence := func(saName string, expectExisted bool) { saKey := types.NamespacedName{ @@ -1614,8 +1613,8 @@ var _ = Describe("Component Controller", func() { testCompRBAC(compName, compDefName, saName) By("delete the cluster(component)") - testapps.DeleteObject(&testCtx, clusterKey, &appsv1alpha1.Cluster{}) - Eventually(testapps.CheckObjExists(&testCtx, clusterKey, &appsv1alpha1.Cluster{}, false)).Should(Succeed()) + testapps.DeleteObject(&testCtx, clusterKey, &kbappsv1.Cluster{}) + Eventually(testapps.CheckObjExists(&testCtx, clusterKey, &kbappsv1.Cluster{}, false)).Should(Succeed()) By("check the RBAC resources deleted") checkRBACResourcesExistence(saName, false) @@ -1646,8 +1645,8 @@ var _ = Describe("Component Controller", func() { })).Should(Succeed()) By("delete the cluster(component)") - testapps.DeleteObject(&testCtx, clusterKey, &appsv1alpha1.Cluster{}) - Eventually(testapps.CheckObjExists(&testCtx, clusterKey, &appsv1alpha1.Cluster{}, true)).Should(Succeed()) + testapps.DeleteObject(&testCtx, clusterKey, &kbappsv1.Cluster{}) + Eventually(testapps.CheckObjExists(&testCtx, clusterKey, &kbappsv1.Cluster{}, true)).Should(Succeed()) By("check the RBAC resources deleted") checkRBACResourcesExistence(saName, true) @@ -1748,7 +1747,7 @@ var _ = Describe("Component Controller", func() { By("Checking pods' role are updated in cluster status") Eventually(func(g Gomega) { - fetched := &appsv1alpha1.Cluster{} + fetched := &kbappsv1.Cluster{} g.Expect(k8sClient.Get(ctx, clusterKey, fetched)).To(Succeed()) compName := fetched.Spec.ComponentSpecs[0].Name g.Expect(fetched.Status.Components != nil).To(BeTrue()) @@ -1759,7 +1758,7 @@ var _ = Describe("Component Controller", func() { By("Waiting the component be running") Eventually(testapps.GetClusterComponentPhase(&testCtx, clusterKey, compName)). - Should(Equal(appsv1alpha1.RunningClusterCompPhase)) + Should(Equal(kbappsv1.RunningClusterCompPhase)) } testRestoreClusterFromBackup := func(compName string, compDef *kbappsv1.ComponentDefinition) { @@ -1821,7 +1820,7 @@ var _ = Describe("Component Controller", func() { Expect(testapps.ChangeObjStatus(&testCtx, its, func() { testk8s.MockInstanceSetReady(its, mockPods...) })).ShouldNot(HaveOccurred()) - Eventually(testapps.GetClusterComponentPhase(&testCtx, clusterKey, compName)).Should(Equal(appsv1alpha1.RunningClusterCompPhase)) + Eventually(testapps.GetClusterComponentPhase(&testCtx, clusterKey, compName)).Should(Equal(kbappsv1.RunningClusterCompPhase)) By("the restore container has been removed from init containers") Eventually(testapps.CheckObj(&testCtx, client.ObjectKeyFromObject(its), func(g Gomega, tmpIts *workloads.InstanceSet) { @@ -1829,8 +1828,8 @@ var _ = Describe("Component Controller", func() { })).Should(Succeed()) By("clean up annotations after cluster running") - Eventually(testapps.CheckObj(&testCtx, clusterKey, func(g Gomega, tmpCluster *appsv1alpha1.Cluster) { - g.Expect(tmpCluster.Status.Phase).Should(Equal(appsv1alpha1.RunningClusterPhase)) + Eventually(testapps.CheckObj(&testCtx, clusterKey, func(g Gomega, tmpCluster *kbappsv1.Cluster) { + g.Expect(tmpCluster.Status.Phase).Should(Equal(kbappsv1.RunningClusterPhase)) // mock postReady restore completed mockRestoreCompleted(ml) g.Expect(tmpCluster.Annotations[constant.RestoreFromBackupAnnotationKey]).Should(BeEmpty()) @@ -1957,7 +1956,7 @@ var _ = Describe("Component Controller", func() { It("with component zero replicas", func() { zeroReplicas := func(f *testapps.MockClusterFactory) { f.SetReplicas(0) } - phase := appsv1alpha1.ClusterPhase("") + phase := kbappsv1.ClusterPhase("") createClusterObjX("", defaultCompName, compDefName, zeroReplicas, &phase) By("checking the component status can't be reconciled well") @@ -2002,9 +2001,10 @@ var _ = Describe("Component Controller", func() { testCompConfiguration(defaultCompName, compDefName) }) - It("with component affinity and toleration set", func() { - testCompAffinityNToleration(defaultCompName, compDefName) - }) + // TODO(v1.0): scheduling + // It("with component affinity and toleration set", func() { + // testCompAffinityNToleration(defaultCompName, compDefName) + // }) It("with component RBAC set", func() { testCompRBAC(defaultCompName, compDefName, "") @@ -2172,18 +2172,18 @@ var _ = Describe("Component Controller", func() { }) startComp := func() { - Expect(testapps.GetAndChangeObj(&testCtx, clusterKey, func(cluster *appsv1alpha1.Cluster) { + Expect(testapps.GetAndChangeObj(&testCtx, clusterKey, func(cluster *kbappsv1.Cluster) { cluster.Spec.ComponentSpecs[0].Stop = nil })()).Should(Succeed()) } stopComp := func() { - Expect(testapps.GetAndChangeObj(&testCtx, clusterKey, func(cluster *appsv1alpha1.Cluster) { + Expect(testapps.GetAndChangeObj(&testCtx, clusterKey, func(cluster *kbappsv1.Cluster) { cluster.Spec.ComponentSpecs[0].Stop = func() *bool { b := true; return &b }() })()).Should(Succeed()) } - checkCompRunningAs := func(phase appsv1alpha1.ClusterComponentPhase) { + checkCompRunningAs := func(phase kbappsv1.ClusterComponentPhase) { Eventually(testapps.CheckObj(&testCtx, compKey, func(g Gomega, comp *kbappsv1.Component) { g.Expect(comp.Status.ObservedGeneration).To(BeEquivalentTo(comp.Generation)) if comp.Spec.Stop != nil { @@ -2199,11 +2199,11 @@ var _ = Describe("Component Controller", func() { } checkCompCreating := func() { - checkCompRunningAs(appsv1alpha1.CreatingClusterCompPhase) + checkCompRunningAs(kbappsv1.CreatingClusterCompPhase) } checkCompRunning := func() { - checkCompRunningAs(appsv1alpha1.UpdatingClusterCompPhase) + checkCompRunningAs(kbappsv1.UpdatingClusterCompPhase) } checkCompStopped := func() { @@ -2257,7 +2257,7 @@ var _ = Describe("Component Controller", func() { It("h-scale a stopped component", func() { createClusterObjWithPhase(defaultCompName, compDefName, func(f *testapps.MockClusterFactory) { f.SetStop(func() *bool { b := true; return &b }()) - }, appsv1alpha1.StoppedClusterPhase) + }, kbappsv1.StoppedClusterPhase) checkCompStopped() By("scale-out") diff --git a/controllers/apps/component_hscale_volume_populator.go b/controllers/apps/component_hscale_volume_populator.go index 7c33c3ffc34..39db28e8d85 100644 --- a/controllers/apps/component_hscale_volume_populator.go +++ b/controllers/apps/component_hscale_volume_populator.go @@ -29,7 +29,7 @@ import ( "k8s.io/apimachinery/pkg/util/sets" "sigs.k8s.io/controller-runtime/pkg/client" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" dpv1alpha1 "github.com/apecloud/kubeblocks/apis/dataprotection/v1alpha1" workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" "github.com/apecloud/kubeblocks/pkg/constant" @@ -67,7 +67,7 @@ const ( func newDataClone(reqCtx intctrlutil.RequestCtx, cli client.Client, - cluster *appsv1alpha1.Cluster, + cluster *appsv1.Cluster, component *component.SynthesizedComponent, itsObj, itsProto *workloads.InstanceSet, backupKey types.NamespacedName) (dataClone, error) { @@ -115,7 +115,7 @@ func newDataClone(reqCtx intctrlutil.RequestCtx, type baseDataClone struct { reqCtx intctrlutil.RequestCtx cli client.Client - cluster *appsv1alpha1.Cluster + cluster *appsv1.Cluster component *component.SynthesizedComponent itsObj *workloads.InstanceSet itsProto *workloads.InstanceSet @@ -439,7 +439,7 @@ func (d *backupDataClone) CheckRestoreStatus(templateName string, startingIndex // getBackupPolicyFromTemplate gets backup policy from template policy template. func getBackupPolicyFromTemplate(reqCtx intctrlutil.RequestCtx, cli client.Client, - cluster *appsv1alpha1.Cluster, + cluster *appsv1.Cluster, componentDef, backupPolicyTemplateName string) (*dpv1alpha1.BackupPolicy, error) { backupPolicyList := &dpv1alpha1.BackupPolicyList{} if err := cli.List(reqCtx.Ctx, backupPolicyList, diff --git a/controllers/apps/component_plan_builder.go b/controllers/apps/component_plan_builder.go index 1b6ac6224a5..60dfa1cfe38 100644 --- a/controllers/apps/component_plan_builder.go +++ b/controllers/apps/component_plan_builder.go @@ -31,7 +31,6 @@ import ( "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" "github.com/apecloud/kubeblocks/pkg/constant" "github.com/apecloud/kubeblocks/pkg/controller/component" "github.com/apecloud/kubeblocks/pkg/controller/graph" @@ -46,7 +45,7 @@ type componentTransformContext struct { Client client.Reader record.EventRecorder logr.Logger - Cluster *appsv1alpha1.Cluster + Cluster *appsv1.Cluster CompDef *appsv1.ComponentDefinition Component *appsv1.Component ComponentOrig *appsv1.Component @@ -91,7 +90,7 @@ var _ graph.PlanBuilder = &componentPlanBuilder{} var _ graph.Plan = &componentPlan{} func (c *componentPlanBuilder) Init() error { - comp := &appsv1alpha1.Component{} + comp := &appsv1.Component{} if err := c.cli.Get(c.transCtx.Context, c.req.NamespacedName, comp); err != nil { return err } diff --git a/controllers/apps/componentversion_controller.go b/controllers/apps/componentversion_controller.go index c21d6a86bb7..67eeaa12a6f 100644 --- a/controllers/apps/componentversion_controller.go +++ b/controllers/apps/componentversion_controller.go @@ -40,7 +40,6 @@ import ( "sigs.k8s.io/controller-runtime/pkg/reconcile" appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" "github.com/apecloud/kubeblocks/pkg/constant" "github.com/apecloud/kubeblocks/pkg/controller/component" intctrlutil "github.com/apecloud/kubeblocks/pkg/controllerutil" @@ -212,7 +211,7 @@ func (r *ComponentVersionReconciler) deletionHandler(rctx intctrlutil.RequestCtx "cannot be deleted because of existing referencing Cluster.") } if res, err := intctrlutil.ValidateReferenceCR(rctx, r.Client, compVersion, constant.ComponentVersionLabelKey, - recordEvent, &appsv1alpha1.ClusterList{}); res != nil || err != nil { + recordEvent, &appsv1.ClusterList{}); res != nil || err != nil { return res, err } return nil, nil diff --git a/controllers/apps/configuration/configconstraint_controller.go b/controllers/apps/configuration/configconstraint_controller.go index e3c6bc56831..5ebd5d16065 100644 --- a/controllers/apps/configuration/configconstraint_controller.go +++ b/controllers/apps/configuration/configconstraint_controller.go @@ -31,7 +31,6 @@ import ( "sigs.k8s.io/controller-runtime/pkg/log" appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" appsv1beta1 "github.com/apecloud/kubeblocks/apis/apps/v1beta1" cfgcore "github.com/apecloud/kubeblocks/pkg/configuration/core" "github.com/apecloud/kubeblocks/pkg/constant" @@ -86,7 +85,7 @@ func (r *ConfigConstraintReconciler) Reconcile(ctx context.Context, req ctrl.Req } if res, err := intctrlutil.ValidateReferenceCR(reqCtx, r.Client, configConstraint, cfgcore.GenerateConstraintsUniqLabelKeyWithConfig(configConstraint.GetName()), - recordEvent, &appsv1alpha1.ClusterDefinitionList{}, &appsv1.ComponentDefinitionList{}); res != nil || err != nil { + recordEvent, &appsv1.ClusterDefinitionList{}, &appsv1.ComponentDefinitionList{}); res != nil || err != nil { return res, err } return nil, nil diff --git a/controllers/apps/configuration/configuration_test.go b/controllers/apps/configuration/configuration_test.go index 17ffd8d218d..a8223a49720 100644 --- a/controllers/apps/configuration/configuration_test.go +++ b/controllers/apps/configuration/configuration_test.go @@ -87,8 +87,8 @@ func mockConfigResource() (*corev1.ConfigMap, *appsv1beta1.ConfigConstraint) { configuration := builder.NewConfigurationBuilder(testCtx.DefaultNamespace, core.GenerateComponentConfigurationName(clusterName, defaultCompName)). ClusterRef(clusterName). Component(defaultCompName). - AddConfigurationItem(appsv1alpha1.ComponentConfigSpec{ - ComponentTemplateSpec: appsv1alpha1.ComponentTemplateSpec{ + AddConfigurationItem(appsv1.ComponentConfigSpec{ + ComponentTemplateSpec: appsv1.ComponentTemplateSpec{ Name: configSpecName, TemplateRef: configmap.Name, Namespace: configmap.Namespace, @@ -102,7 +102,7 @@ func mockConfigResource() (*corev1.ConfigMap, *appsv1beta1.ConfigConstraint) { return configmap, constraint } -func mockReconcileResource() (*corev1.ConfigMap, *appsv1beta1.ConfigConstraint, *appsv1alpha1.Cluster, *appsv1.Component, *component.SynthesizedComponent) { +func mockReconcileResource() (*corev1.ConfigMap, *appsv1beta1.ConfigConstraint, *appsv1.Cluster, *appsv1.Component, *component.SynthesizedComponent) { configmap, constraint := mockConfigResource() By("Create a component definition obj and mock to available") @@ -159,7 +159,7 @@ func mockReconcileResource() (*corev1.ConfigMap, *appsv1beta1.ConfigConstraint, func initConfiguration(resourceCtx *configctrl.ResourceCtx, synthesizedComponent *component.SynthesizedComponent, - clusterObj *appsv1alpha1.Cluster, + clusterObj *appsv1.Cluster, componentObj *appsv1.Component) error { return configctrl.NewCreatePipeline(configctrl.ReconcileCtx{ ResourceCtx: resourceCtx, diff --git a/controllers/apps/configuration/policy_util_test.go b/controllers/apps/configuration/policy_util_test.go index 0efbfa09431..30ed8880c33 100644 --- a/controllers/apps/configuration/policy_util_test.go +++ b/controllers/apps/configuration/policy_util_test.go @@ -33,7 +33,6 @@ import ( "sigs.k8s.io/controller-runtime/pkg/log" appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" appsv1beta1 "github.com/apecloud/kubeblocks/apis/apps/v1beta1" workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" "github.com/apecloud/kubeblocks/pkg/configuration/core" @@ -96,7 +95,7 @@ func withMockInstanceSet(replicas int, labels map[string]string) ParamsOps { func withClusterComponent(replicas int) ParamsOps { return func(params *reconfigureParams) { - params.ClusterComponent = &appsv1alpha1.ClusterComponentSpec{ + params.ClusterComponent = &appsv1.ClusterComponentSpec{ Name: "test", Replicas: func() int32 { rep := int32(replicas); return rep }(), } @@ -178,7 +177,7 @@ func newMockReconfigureParams(testName string, cli client.Client, paramOps ...Pa }, }, }, - Cluster: &appsv1alpha1.Cluster{ + Cluster: &appsv1.Cluster{ ObjectMeta: metav1.ObjectMeta{ Name: "test", }}, diff --git a/controllers/apps/configuration/reconfigure_policy.go b/controllers/apps/configuration/reconfigure_policy.go index 849db0c55fc..abdfc0d6278 100644 --- a/controllers/apps/configuration/reconfigure_policy.go +++ b/controllers/apps/configuration/reconfigure_policy.go @@ -28,6 +28,7 @@ import ( "k8s.io/apimachinery/pkg/util/intstr" "sigs.k8s.io/controller-runtime/pkg/client" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" appsv1beta1 "github.com/apecloud/kubeblocks/apis/apps/v1beta1" workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" @@ -99,10 +100,10 @@ type reconfigureParams struct { Client client.Client Ctx intctrlutil.RequestCtx - Cluster *appsv1alpha1.Cluster + Cluster *appsv1.Cluster // Associated component for cluster. - ClusterComponent *appsv1alpha1.ClusterComponentSpec + ClusterComponent *appsv1.ClusterComponentSpec // Associated component for component and component definition. SynthesizedComponent *component.SynthesizedComponent diff --git a/controllers/apps/operations/backup.go b/controllers/apps/operations/backup.go index 86979f6311b..7d5834b9166 100644 --- a/controllers/apps/operations/backup.go +++ b/controllers/apps/operations/backup.go @@ -27,6 +27,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/client" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" dpv1alpha1 "github.com/apecloud/kubeblocks/apis/dataprotection/v1alpha1" "github.com/apecloud/kubeblocks/pkg/constant" @@ -44,8 +45,8 @@ var _ OpsHandler = BackupOpsHandler{} func init() { // ToClusterPhase is not defined, because 'backup' does not affect the cluster phase. backupBehaviour := OpsBehaviour{ - FromClusterPhases: []appsv1alpha1.ClusterPhase{appsv1alpha1.RunningClusterPhase, - appsv1alpha1.UpdatingClusterPhase, appsv1alpha1.AbnormalClusterPhase}, + FromClusterPhases: []appsv1.ClusterPhase{appsv1.RunningClusterPhase, + appsv1.UpdatingClusterPhase, appsv1.AbnormalClusterPhase}, OpsHandler: BackupOpsHandler{}, } @@ -104,7 +105,7 @@ func (b BackupOpsHandler) SaveLastConfiguration(reqCtx intctrlutil.RequestCtx, c return nil } -func buildBackup(reqCtx intctrlutil.RequestCtx, cli client.Client, opsRequest *appsv1alpha1.OpsRequest, cluster *appsv1alpha1.Cluster) (*dpv1alpha1.Backup, error) { +func buildBackup(reqCtx intctrlutil.RequestCtx, cli client.Client, opsRequest *appsv1alpha1.OpsRequest, cluster *appsv1.Cluster) (*dpv1alpha1.Backup, error) { var err error backupSpec := opsRequest.Spec.GetBackup() @@ -180,7 +181,7 @@ func buildBackup(reqCtx intctrlutil.RequestCtx, cli client.Client, opsRequest *a return backup, nil } -func getDefaultBackupPolicy(reqCtx intctrlutil.RequestCtx, cli client.Client, cluster *appsv1alpha1.Cluster, backupPolicy string) (string, error) { +func getDefaultBackupPolicy(reqCtx intctrlutil.RequestCtx, cli client.Client, cluster *appsv1.Cluster, backupPolicy string) (string, error) { // if backupPolicy is not empty, return it directly if backupPolicy != "" { return backupPolicy, nil diff --git a/controllers/apps/operations/backup_test.go b/controllers/apps/operations/backup_test.go index 614d7eefa41..f84d7306905 100644 --- a/controllers/apps/operations/backup_test.go +++ b/controllers/apps/operations/backup_test.go @@ -25,6 +25,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" intctrlutil "github.com/apecloud/kubeblocks/pkg/controllerutil" "github.com/apecloud/kubeblocks/pkg/generics" @@ -98,14 +99,14 @@ var _ = Describe("Backup OpsRequest", func() { It("should create a backup resource when cluster phase is Updating", func() { Expect(testapps.ChangeObjStatus(&testCtx, opsRes.Cluster, func() { - opsRes.Cluster.Status.Phase = appsv1alpha1.UpdatingClusterPhase + opsRes.Cluster.Status.Phase = appsv1.UpdatingClusterPhase })).Should(Succeed()) testBackupOps(opsRes) }) It("should failed when cluster phase is Failed", func() { Expect(testapps.ChangeObjStatus(&testCtx, opsRes.Cluster, func() { - opsRes.Cluster.Status.Phase = appsv1alpha1.FailedClusterPhase + opsRes.Cluster.Status.Phase = appsv1.FailedClusterPhase })).Should(Succeed()) By("create Backup OpsRequest") diff --git a/controllers/apps/operations/custom.go b/controllers/apps/operations/custom.go index 1b4dbcd12cc..02f871e70e7 100644 --- a/controllers/apps/operations/custom.go +++ b/controllers/apps/operations/custom.go @@ -126,7 +126,7 @@ func (c CustomOpsHandler) SaveLastConfiguration(reqCtx intctrlutil.RequestCtx, c func (c CustomOpsHandler) listComponents(reqCtx intctrlutil.RequestCtx, cli client.Client, - cluster *appsv1alpha1.Cluster, + cluster *appsv1.Cluster, componentName string) ([]appsv1.Component, error) { if cluster.Spec.GetComponentByName(componentName) != nil { comp, err := component.GetComponentByName(reqCtx.Ctx, cli, cluster.Namespace, diff --git a/controllers/apps/operations/custom/action_exec.go b/controllers/apps/operations/custom/action_exec.go index 4feb1f0b316..ab3c176d435 100644 --- a/controllers/apps/operations/custom/action_exec.go +++ b/controllers/apps/operations/custom/action_exec.go @@ -22,6 +22,7 @@ package custom import ( corev1 "k8s.io/api/core/v1" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" "github.com/apecloud/kubeblocks/pkg/constant" "github.com/apecloud/kubeblocks/pkg/controller/builder" @@ -31,18 +32,18 @@ import ( type ExecAction struct { OpsRequest *appsv1alpha1.OpsRequest - Cluster *appsv1alpha1.Cluster + Cluster *appsv1.Cluster OpsDef *appsv1alpha1.OpsDefinition CustomCompOps *appsv1alpha1.CustomOpsComponent - Comp *appsv1alpha1.ClusterComponentSpec + Comp *appsv1.ClusterComponentSpec progressDetail appsv1alpha1.ProgressStatusDetail } func NewExecAction(opsRequest *appsv1alpha1.OpsRequest, - cluster *appsv1alpha1.Cluster, + cluster *appsv1.Cluster, opsDef *appsv1alpha1.OpsDefinition, customCompOps *appsv1alpha1.CustomOpsComponent, - comp *appsv1alpha1.ClusterComponentSpec, + comp *appsv1.ClusterComponentSpec, progressDetail appsv1alpha1.ProgressStatusDetail) *ExecAction { return &ExecAction{ OpsRequest: opsRequest, @@ -168,10 +169,14 @@ func (e *ExecAction) buildExecPodSpec(actionCtx ActionContext, }, execAction.Command...), } intctrlutil.InjectZeroResourcesLimitsIfEmpty(container) + var tolerations []corev1.Toleration + if e.Comp.SchedulingPolicy != nil { + tolerations = e.Comp.SchedulingPolicy.Tolerations + } return &corev1.PodSpec{ Containers: []corev1.Container{*container}, // tolerate all taints - Tolerations: e.Comp.Tolerations, + Tolerations: tolerations, ImagePullSecrets: intctrlutil.BuildImagePullSecrets(), }, nil } diff --git a/controllers/apps/operations/custom/action_workload.go b/controllers/apps/operations/custom/action_workload.go index f8fa6ed32b5..322d46505a3 100644 --- a/controllers/apps/operations/custom/action_workload.go +++ b/controllers/apps/operations/custom/action_workload.go @@ -23,6 +23,7 @@ import ( corev1 "k8s.io/api/core/v1" "sigs.k8s.io/controller-runtime/pkg/client" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" "github.com/apecloud/kubeblocks/pkg/constant" intctrlutil "github.com/apecloud/kubeblocks/pkg/controllerutil" @@ -31,18 +32,18 @@ import ( type WorkloadAction struct { OpsRequest *appsv1alpha1.OpsRequest - Cluster *appsv1alpha1.Cluster + Cluster *appsv1.Cluster OpsDef *appsv1alpha1.OpsDefinition CustomCompOps *appsv1alpha1.CustomOpsComponent - Comp *appsv1alpha1.ClusterComponentSpec + Comp *appsv1.ClusterComponentSpec progressDetail appsv1alpha1.ProgressStatusDetail } func NewWorkloadAction(opsRequest *appsv1alpha1.OpsRequest, - cluster *appsv1alpha1.Cluster, + cluster *appsv1.Cluster, opsDef *appsv1alpha1.OpsDefinition, customCompOps *appsv1alpha1.CustomOpsComponent, - comp *appsv1alpha1.ClusterComponentSpec, + comp *appsv1.ClusterComponentSpec, progressDetail appsv1alpha1.ProgressStatusDetail) *WorkloadAction { return &WorkloadAction{ OpsRequest: opsRequest, @@ -181,8 +182,8 @@ func (w *WorkloadAction) buildPodSpec(actionCtx ActionContext, if podSpec.RestartPolicy == "" { podSpec.RestartPolicy = corev1.RestartPolicyNever } - if len(podSpec.Tolerations) == 0 { - podSpec.Tolerations = w.Comp.Tolerations + if len(podSpec.Tolerations) == 0 && w.Comp.SchedulingPolicy != nil { + podSpec.Tolerations = w.Comp.SchedulingPolicy.Tolerations } switch { case w.OpsRequest.Spec.CustomOps.ServiceAccountName != nil: diff --git a/controllers/apps/operations/custom/utils.go b/controllers/apps/operations/custom/utils.go index 5d03dfbf033..bc60525e77a 100644 --- a/controllers/apps/operations/custom/utils.go +++ b/controllers/apps/operations/custom/utils.go @@ -31,6 +31,7 @@ import ( "k8s.io/client-go/util/jsonpath" "sigs.k8s.io/controller-runtime/pkg/client" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" "github.com/apecloud/kubeblocks/pkg/common" "github.com/apecloud/kubeblocks/pkg/constant" @@ -53,10 +54,10 @@ const ( // buildComponentDefEnvs builds the env vars by the opsDefinition.spec.componentDefinitionRef func buildComponentEnvs(reqCtx intctrlutil.RequestCtx, cli client.Client, - cluster *appsv1alpha1.Cluster, + cluster *appsv1.Cluster, opsDef *appsv1alpha1.OpsDefinition, env *[]corev1.EnvVar, - comp *appsv1alpha1.ClusterComponentSpec) error { + comp *appsv1.ClusterComponentSpec) error { // inject built-in component env fullCompName := constant.GenerateClusterComponentName(cluster.Name, comp.Name) *env = append(*env, []corev1.EnvVar{ @@ -233,10 +234,10 @@ func buildVarWithEnv(targetPod *corev1.Pod, container *corev1.Container, envName func buildActionPodEnv(reqCtx intctrlutil.RequestCtx, cli client.Client, - cluster *appsv1alpha1.Cluster, + cluster *appsv1.Cluster, opsDef *appsv1alpha1.OpsDefinition, ops *appsv1alpha1.OpsRequest, - comp *appsv1alpha1.ClusterComponentSpec, + comp *appsv1.ClusterComponentSpec, compCustomItem *appsv1alpha1.CustomOpsComponent, podInfoExtractor *appsv1alpha1.PodInfoExtractor, targetPod *corev1.Pod) ([]corev1.EnvVar, error) { @@ -313,7 +314,7 @@ func getTargetTemplateAndPod(ctx context.Context, func getTargetPods( ctx context.Context, cli client.Client, - cluster *appsv1alpha1.Cluster, + cluster *appsv1.Cluster, podSelector appsv1alpha1.PodSelector, compName string) ([]*corev1.Pod, error) { var ( diff --git a/controllers/apps/operations/custom_test.go b/controllers/apps/operations/custom_test.go index 6ec6197fd39..80d6f934bf5 100644 --- a/controllers/apps/operations/custom_test.go +++ b/controllers/apps/operations/custom_test.go @@ -45,7 +45,7 @@ var _ = Describe("CustomOps", func() { compObj *appsv1.Component opsDef *appsv1alpha1.OpsDefinition reqCtx intctrlutil.RequestCtx - cluster *appsv1alpha1.Cluster + cluster *appsv1.Cluster ) cleanEnv := func() { diff --git a/controllers/apps/operations/custom_workflow.go b/controllers/apps/operations/custom_workflow.go index c60f04c7d75..172f9c4058d 100644 --- a/controllers/apps/operations/custom_workflow.go +++ b/controllers/apps/operations/custom_workflow.go @@ -21,6 +21,7 @@ package operations import ( "fmt" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" "sigs.k8s.io/controller-runtime/pkg/client" @@ -146,7 +147,7 @@ steps: func (w *WorkflowContext) getAction(action appsv1alpha1.OpsAction, compCustomItem *appsv1alpha1.CustomOpsComponent, - compSpec *appsv1alpha1.ClusterComponentSpec, + compSpec *appsv1.ClusterComponentSpec, progressDetail appsv1alpha1.ProgressStatusDetail) custom.OpsAction { switch { case action.Workload != nil: diff --git a/controllers/apps/operations/expose.go b/controllers/apps/operations/expose.go index fa001cd2dcf..afa3f18f0a1 100644 --- a/controllers/apps/operations/expose.go +++ b/controllers/apps/operations/expose.go @@ -30,6 +30,7 @@ import ( "k8s.io/apimachinery/pkg/util/sets" "sigs.k8s.io/controller-runtime/pkg/client" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" "github.com/apecloud/kubeblocks/pkg/constant" "github.com/apecloud/kubeblocks/pkg/controller/component" @@ -57,7 +58,7 @@ func (e ExposeOpsHandler) Action(reqCtx intctrlutil.RequestCtx, cli client.Clien exposeMap = opsRes.OpsRequest.Spec.ToExposeListToMap() ) reqCtx.Log.Info("cluster service before action", "clusterService", opsRes.Cluster.Spec.Services) - compMap := make(map[string]appsv1alpha1.ClusterComponentSpec) + compMap := make(map[string]appsv1.ClusterComponentSpec) for _, comp := range opsRes.Cluster.Spec.ComponentSpecs { compMap[comp.Name] = comp } @@ -104,7 +105,7 @@ func (e ExposeOpsHandler) ReconcileAction(reqCtx intctrlutil.RequestCtx, cli cli opsRequest.Status.Components = make(map[string]appsv1alpha1.OpsRequestComponentStatus) for _, v := range opsRequest.Spec.ExposeList { opsRequest.Status.Components[v.ComponentName] = appsv1alpha1.OpsRequestComponentStatus{ - Phase: appsv1alpha1.UpdatingClusterCompPhase, // appsv1alpha1.ExposingPhase, + Phase: appsv1.UpdatingClusterCompPhase, // appsv1.ExposingPhase, } } } @@ -124,7 +125,7 @@ func (e ExposeOpsHandler) ReconcileAction(reqCtx intctrlutil.RequestCtx, cli cli // update component status if completed if actualCount == expectCount { p := opsRequest.Status.Components[v.ComponentName] - p.Phase = appsv1alpha1.RunningClusterCompPhase + p.Phase = appsv1.RunningClusterCompPhase } } opsRequest.Status.Progress = fmt.Sprintf("%d/%d", actualProgressCount, expectProgressCount) @@ -243,7 +244,7 @@ func (e ExposeOpsHandler) SaveLastConfiguration(reqCtx intctrlutil.RequestCtx, c return nil } -func (e ExposeOpsHandler) removeClusterServices(cluster *appsv1alpha1.Cluster, +func (e ExposeOpsHandler) removeClusterServices(cluster *appsv1.Cluster, clusterCompSpecName string, exposeServices []appsv1alpha1.OpsService) error { if cluster == nil || len(exposeServices) == 0 { @@ -264,7 +265,7 @@ func (e ExposeOpsHandler) removeClusterServices(cluster *appsv1alpha1.Cluster, func (e ExposeOpsHandler) buildClusterServices(reqCtx intctrlutil.RequestCtx, cli client.Client, - cluster *appsv1alpha1.Cluster, + cluster *appsv1.Cluster, clusterCompSpecName string, compDefName string, exposeServices []appsv1alpha1.OpsService) error { @@ -290,7 +291,7 @@ func (e ExposeOpsHandler) buildClusterServices(reqCtx intctrlutil.RequestCtx, return false } - convertDefaultCompDefServicePorts := func(compServices []appsv1alpha1.ComponentService) ([]corev1.ServicePort, error) { + convertDefaultCompDefServicePorts := func(compServices []appsv1.ComponentService) ([]corev1.ServicePort, error) { if len(compServices) == 0 { return nil, fmt.Errorf("component service is not defined, expose operation is not supported, cluster: %s, component: %s", cluster.Name, clusterCompSpecName) } @@ -353,8 +354,8 @@ func (e ExposeOpsHandler) buildClusterServices(reqCtx intctrlutil.RequestCtx, genServiceName := generateServiceName(clusterCompSpecName, exposeService.Name) - clusterService := appsv1alpha1.ClusterService{ - Service: appsv1alpha1.Service{ + clusterService := appsv1.ClusterService{ + Service: appsv1.Service{ Name: genServiceName, ServiceName: genServiceName, Annotations: exposeService.Annotations, diff --git a/controllers/apps/operations/horizontal_scaling.go b/controllers/apps/operations/horizontal_scaling.go index 1686d7d90be..8f3b122f34c 100644 --- a/controllers/apps/operations/horizontal_scaling.go +++ b/controllers/apps/operations/horizontal_scaling.go @@ -30,6 +30,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" dpv1alpha1 "github.com/apecloud/kubeblocks/apis/dataprotection/v1alpha1" "github.com/apecloud/kubeblocks/pkg/constant" @@ -45,8 +46,8 @@ func init() { hsHandler := horizontalScalingOpsHandler{} horizontalScalingBehaviour := OpsBehaviour{ // if cluster is Abnormal or Failed, new opsRequest may repair it. - FromClusterPhases: appsv1alpha1.GetClusterUpRunningPhases(), - ToClusterPhase: appsv1alpha1.UpdatingClusterPhase, + FromClusterPhases: appsv1.GetClusterUpRunningPhases(), + ToClusterPhase: appsv1.UpdatingClusterPhase, QueueByCluster: true, OpsHandler: hsHandler, CancelFunc: hsHandler.Cancel, @@ -62,8 +63,8 @@ func (hs horizontalScalingOpsHandler) ActionStartedCondition(reqCtx intctrlutil. // Action modifies Cluster.spec.components[*].replicas from the opsRequest func (hs horizontalScalingOpsHandler) Action(reqCtx intctrlutil.RequestCtx, cli client.Client, opsRes *OpsResource) error { - if slices.Contains([]appsv1alpha1.ClusterPhase{appsv1alpha1.StoppedClusterPhase, - appsv1alpha1.StoppingClusterPhase}, opsRes.Cluster.Status.Phase) { + if slices.Contains([]appsv1.ClusterPhase{appsv1.StoppedClusterPhase, + appsv1.StoppingClusterPhase}, opsRes.Cluster.Status.Phase) { return intctrlutil.NewFatalError("please start the cluster before scaling the cluster horizontally") } compOpsSet := newComponentOpsHelper(opsRes.OpsRequest.Spec.HorizontalScalingList) @@ -97,7 +98,7 @@ func (hs horizontalScalingOpsHandler) Action(reqCtx intctrlutil.RequestCtx, cli return err } - if err := compOpsSet.updateClusterComponentsAndShardings(opsRes.Cluster, func(compSpec *appsv1alpha1.ClusterComponentSpec, obj ComponentOpsInterface) error { + if err := compOpsSet.updateClusterComponentsAndShardings(opsRes.Cluster, func(compSpec *appsv1.ClusterComponentSpec, obj ComponentOpsInterface) error { horizontalScaling := obj.(appsv1alpha1.HorizontalScaling) lastCompConfiguration := opsRes.OpsRequest.Status.LastConfiguration.Components[obj.GetComponentName()] if horizontalScaling.ScaleIn != nil && len(horizontalScaling.ScaleIn.OnlineInstancesToOffline) > 0 { @@ -163,7 +164,7 @@ func (hs horizontalScalingOpsHandler) ReconcileAction(reqCtx intctrlutil.Request // SaveLastConfiguration records last configuration to the OpsRequest.status.lastConfiguration func (hs horizontalScalingOpsHandler) SaveLastConfiguration(reqCtx intctrlutil.RequestCtx, cli client.Client, opsRes *OpsResource) error { compOpsHelper := newComponentOpsHelper(opsRes.OpsRequest.Spec.HorizontalScalingList) - getLastComponentInfo := func(compSpec appsv1alpha1.ClusterComponentSpec, comOps ComponentOpsInterface) appsv1alpha1.LastComponentConfiguration { + getLastComponentInfo := func(compSpec appsv1.ClusterComponentSpec, comOps ComponentOpsInterface) appsv1alpha1.LastComponentConfiguration { lastCompConfiguration := appsv1alpha1.LastComponentConfiguration{ Replicas: pointer.Int32(compSpec.Replicas), Instances: compSpec.Instances, @@ -178,7 +179,7 @@ func (hs horizontalScalingOpsHandler) SaveLastConfiguration(reqCtx intctrlutil.R // getCreateAndDeletePodSet gets the pod set that are created and deleted in this opsRequest. func (hs horizontalScalingOpsHandler) getCreateAndDeletePodSet(opsRes *OpsResource, lastCompConfiguration appsv1alpha1.LastComponentConfiguration, - currCompSpec appsv1alpha1.ClusterComponentSpec, + currCompSpec appsv1.ClusterComponentSpec, horizontalScaling appsv1alpha1.HorizontalScaling, fullCompName string) (map[string]string, map[string]string, error) { clusterName := opsRes.Cluster.Name @@ -218,7 +219,7 @@ func (hs horizontalScalingOpsHandler) getCreateAndDeletePodSet(opsRes *OpsResour // Cancel this function defines the cancel horizontalScaling action. func (hs horizontalScalingOpsHandler) Cancel(reqCtx intctrlutil.RequestCtx, cli client.Client, opsRes *OpsResource) error { compOpsHelper := newComponentOpsHelper(opsRes.OpsRequest.Spec.HorizontalScalingList) - if err := compOpsHelper.cancelComponentOps(reqCtx.Ctx, cli, opsRes, func(lastConfig *appsv1alpha1.LastComponentConfiguration, comp *appsv1alpha1.ClusterComponentSpec) { + if err := compOpsHelper.cancelComponentOps(reqCtx.Ctx, cli, opsRes, func(lastConfig *appsv1alpha1.LastComponentConfiguration, comp *appsv1.ClusterComponentSpec) { comp.Replicas = *lastConfig.Replicas comp.Instances = lastConfig.Instances comp.OfflineInstances = lastConfig.OfflineInstances @@ -291,9 +292,9 @@ func (hs horizontalScalingOpsHandler) checkIntersectionWithEarlierOps(opsRes *Op // getExpectedCompValues gets the expected replicas, instances, offlineInstances. func (hs horizontalScalingOpsHandler) getExpectedCompValues( opsRes *OpsResource, - compSpec *appsv1alpha1.ClusterComponentSpec, + compSpec *appsv1.ClusterComponentSpec, lastCompConfiguration appsv1alpha1.LastComponentConfiguration, - horizontalScaling appsv1alpha1.HorizontalScaling) (int32, []appsv1alpha1.InstanceTemplate, []string, error) { + horizontalScaling appsv1alpha1.HorizontalScaling) (int32, []appsv1.InstanceTemplate, []string, error) { compReplicas := compSpec.Replicas compInstanceTpls := compSpec.Instances compOfflineInstances := compSpec.OfflineInstances @@ -317,12 +318,12 @@ func (hs horizontalScalingOpsHandler) autoSyncReplicaChanges( opsRes *OpsResource, horizontalScaling appsv1alpha1.HorizontalScaling, compReplicas int32, - compInstanceTpls []appsv1alpha1.InstanceTemplate, + compInstanceTpls []appsv1.InstanceTemplate, compExpectOfflineInstances []string) error { // sync the replicaChanges for component and instance template. getSyncedInstancesAndReplicaChanges := func(offlineOrOnlineInsCountMap map[string]int32, replicaChanger appsv1alpha1.ReplicaChanger, - newInstances []appsv1alpha1.InstanceTemplate) ([]appsv1alpha1.InstanceReplicasTemplate, *int32) { + newInstances []appsv1.InstanceTemplate) ([]appsv1alpha1.InstanceReplicasTemplate, *int32) { allReplicaChanges := int32(0) insTplMap := map[string]sets.Empty{} for _, v := range replicaChanger.Instances { @@ -392,9 +393,9 @@ func (hs horizontalScalingOpsHandler) getCompExpectReplicas(horizontalScaling ap // getCompExpectedOfflineInstances gets the expected instance templates of the component. func (hs horizontalScalingOpsHandler) getCompExpectedInstances( - compInstanceTpls []appsv1alpha1.InstanceTemplate, + compInstanceTpls []appsv1.InstanceTemplate, horizontalScaling appsv1alpha1.HorizontalScaling, -) []appsv1alpha1.InstanceTemplate { +) []appsv1.InstanceTemplate { if horizontalScaling.Replicas != nil { return compInstanceTpls } diff --git a/controllers/apps/operations/horizontal_scaling_test.go b/controllers/apps/operations/horizontal_scaling_test.go index 1bafe43d1fe..28b9dfb8eaa 100644 --- a/controllers/apps/operations/horizontal_scaling_test.go +++ b/controllers/apps/operations/horizontal_scaling_test.go @@ -32,6 +32,7 @@ import ( "k8s.io/utils/pointer" "sigs.k8s.io/controller-runtime/pkg/client" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" opsutil "github.com/apecloud/kubeblocks/controllers/apps/operations/util" "github.com/apecloud/kubeblocks/pkg/constant" @@ -77,19 +78,19 @@ var _ = Describe("HorizontalScaling OpsRequest", func() { initClusterAnnotationAndPhaseForOps := func(opsRes *OpsResource) { Expect(opsutil.UpdateClusterOpsAnnotations(ctx, k8sClient, opsRes.Cluster, nil)).Should(Succeed()) Expect(testapps.ChangeObjStatus(&testCtx, opsRes.Cluster, func() { - opsRes.Cluster.Status.Phase = appsv1alpha1.RunningClusterPhase + opsRes.Cluster.Status.Phase = appsv1.RunningClusterPhase })).ShouldNot(HaveOccurred()) } Context("Test OpsRequest", func() { commonHScaleConsensusCompTest := func(reqCtx intctrlutil.RequestCtx, - changeClusterSpec func(cluster *appsv1alpha1.Cluster), + changeClusterSpec func(cluster *appsv1.Cluster), horizontalScaling appsv1alpha1.HorizontalScaling) (*OpsResource, []*corev1.Pod) { By("init operations resources with CLusterDefinition/Hybrid components Cluster/consensus Pods") opsRes, _, _ := initOperationsResources(compDefName, clusterName) its := testapps.MockInstanceSetComponent(&testCtx, clusterName, defaultCompName) if changeClusterSpec != nil { - Expect(testapps.ChangeObj(&testCtx, opsRes.Cluster, func(cluster *appsv1alpha1.Cluster) { + Expect(testapps.ChangeObj(&testCtx, opsRes.Cluster, func(cluster *appsv1.Cluster) { changeClusterSpec(cluster) })).Should(Succeed()) } @@ -100,7 +101,7 @@ var _ = Describe("HorizontalScaling OpsRequest", func() { opsRes.OpsRequest = createHorizontalScaling(clusterName, horizontalScaling) // set ops phase to Pending opsRes.OpsRequest.Status.Phase = appsv1alpha1.OpsPendingPhase - mockComponentIsOperating(opsRes.Cluster, appsv1alpha1.UpdatingClusterCompPhase, defaultCompName) + mockComponentIsOperating(opsRes.Cluster, appsv1.UpdatingClusterCompPhase, defaultCompName) By("expect for opsRequest phase is Creating after doing action") _, err := GetOpsManager().Do(reqCtx, k8sClient, opsRes) @@ -110,7 +111,7 @@ var _ = Describe("HorizontalScaling OpsRequest", func() { By("check for the replicas of consensus component after doing action again when opsRequest phase is Creating") _, err = GetOpsManager().Do(reqCtx, k8sClient, opsRes) Expect(err).ShouldNot(HaveOccurred()) - Eventually(testapps.CheckObj(&testCtx, client.ObjectKeyFromObject(opsRes.Cluster), func(g Gomega, tmpCluster *appsv1alpha1.Cluster) { + Eventually(testapps.CheckObj(&testCtx, client.ObjectKeyFromObject(opsRes.Cluster), func(g Gomega, tmpCluster *appsv1.Cluster) { if horizontalScaling.Replicas == nil { return } @@ -174,7 +175,7 @@ var _ = Describe("HorizontalScaling OpsRequest", func() { } testHScaleReplicas := func( - changeClusterSpec func(cluster *appsv1alpha1.Cluster), + changeClusterSpec func(cluster *appsv1.Cluster), horizontalScaling appsv1alpha1.HorizontalScaling, mockHScale func(podList []*corev1.Pod)) { reqCtx := intctrlutil.RequestCtx{Ctx: testCtx.Ctx} @@ -276,7 +277,7 @@ var _ = Describe("HorizontalScaling OpsRequest", func() { testCancelHScale(appsv1alpha1.HorizontalScaling{ScaleIn: &appsv1alpha1.ScaleIn{ReplicaChanger: appsv1alpha1.ReplicaChanger{ReplicaChanges: pointer.Int32(2)}}}, true) }) - setClusterCompSpec := func(cluster *appsv1alpha1.Cluster, instances []appsv1alpha1.InstanceTemplate, offlineInstances []string) { + setClusterCompSpec := func(cluster *appsv1.Cluster, instances []appsv1.InstanceTemplate, offlineInstances []string) { for i, v := range cluster.Spec.ComponentSpecs { if v.Name == defaultCompName { cluster.Spec.ComponentSpecs[i].OfflineInstances = offlineInstances @@ -286,7 +287,7 @@ var _ = Describe("HorizontalScaling OpsRequest", func() { } } - testHScaleWithSpecifiedPod := func(changeClusterSpec func(cluster *appsv1alpha1.Cluster), + testHScaleWithSpecifiedPod := func(changeClusterSpec func(cluster *appsv1.Cluster), horizontalScaling appsv1alpha1.HorizontalScaling, expectOfflineInstances []string, mockHScale func(podList []*corev1.Pod)) *OpsResource { @@ -311,8 +312,8 @@ var _ = Describe("HorizontalScaling OpsRequest", func() { It("test offline the specified pod of the component", func() { toDeletePodName := fmt.Sprintf("%s-%s-1", clusterName, defaultCompName) offlineInstances := []string{toDeletePodName} - opsRes := testHScaleWithSpecifiedPod(func(cluster *appsv1alpha1.Cluster) { - setClusterCompSpec(cluster, []appsv1alpha1.InstanceTemplate{ + opsRes := testHScaleWithSpecifiedPod(func(cluster *appsv1.Cluster) { + setClusterCompSpec(cluster, []appsv1.InstanceTemplate{ {Name: insTplName, Replicas: pointer.Int32(1)}, }, nil) }, appsv1alpha1.HorizontalScaling{ @@ -330,8 +331,8 @@ var _ = Describe("HorizontalScaling OpsRequest", func() { It("test offline the specified pod and scale out another replicas", func() { toDeletePodName := fmt.Sprintf("%s-%s-1", clusterName, defaultCompName) offlineInstances := []string{toDeletePodName} - opsRes := testHScaleWithSpecifiedPod(func(cluster *appsv1alpha1.Cluster) { - setClusterCompSpec(cluster, []appsv1alpha1.InstanceTemplate{ + opsRes := testHScaleWithSpecifiedPod(func(cluster *appsv1.Cluster) { + setClusterCompSpec(cluster, []appsv1.InstanceTemplate{ {Name: insTplName, Replicas: pointer.Int32(1)}, }, nil) }, appsv1alpha1.HorizontalScaling{ @@ -354,8 +355,8 @@ var _ = Describe("HorizontalScaling OpsRequest", func() { It("test offline the specified pod and auto-sync replicaChanges", func() { offlineInstanceName := fmt.Sprintf("%s-%s-%s-0", clusterName, defaultCompName, insTplName) offlineInstances := []string{offlineInstanceName} - opsRes := testHScaleWithSpecifiedPod(func(cluster *appsv1alpha1.Cluster) { - setClusterCompSpec(cluster, []appsv1alpha1.InstanceTemplate{ + opsRes := testHScaleWithSpecifiedPod(func(cluster *appsv1.Cluster) { + setClusterCompSpec(cluster, []appsv1.InstanceTemplate{ {Name: insTplName, Replicas: pointer.Int32(1)}, }, nil) }, appsv1alpha1.HorizontalScaling{ @@ -376,8 +377,8 @@ var _ = Describe("HorizontalScaling OpsRequest", func() { It("test online the specified pod of the instance template and auto-sync replicaChanges", func() { offlineInstanceName := fmt.Sprintf("%s-%s-%s-0", clusterName, defaultCompName, insTplName) offlineInstances := []string{offlineInstanceName} - opsRes := testHScaleWithSpecifiedPod(func(cluster *appsv1alpha1.Cluster) { - setClusterCompSpec(cluster, []appsv1alpha1.InstanceTemplate{ + opsRes := testHScaleWithSpecifiedPod(func(cluster *appsv1.Cluster) { + setClusterCompSpec(cluster, []appsv1.InstanceTemplate{ {Name: insTplName, Replicas: pointer.Int32(1)}, }, offlineInstances) }, appsv1alpha1.HorizontalScaling{ @@ -398,8 +399,8 @@ var _ = Describe("HorizontalScaling OpsRequest", func() { It("test offline and online the specified pod and auto-sync replicaChanges", func() { onlinePodName := fmt.Sprintf("%s-%s-1", clusterName, defaultCompName) offlinePodName := fmt.Sprintf("%s-%s-%s-0", clusterName, defaultCompName, insTplName) - opsRes := testHScaleWithSpecifiedPod(func(cluster *appsv1alpha1.Cluster) { - setClusterCompSpec(cluster, []appsv1alpha1.InstanceTemplate{ + opsRes := testHScaleWithSpecifiedPod(func(cluster *appsv1.Cluster) { + setClusterCompSpec(cluster, []appsv1.InstanceTemplate{ {Name: insTplName, Replicas: pointer.Int32(1)}, }, []string{onlinePodName}) }, appsv1alpha1.HorizontalScaling{ @@ -441,7 +442,7 @@ var _ = Describe("HorizontalScaling OpsRequest", func() { }, }) By("verify cluster spec is correct") - var targetSpec *appsv1alpha1.ClusterComponentSpec + var targetSpec *appsv1.ClusterComponentSpec for i := range opsRes.Cluster.Spec.ComponentSpecs { spec := &opsRes.Cluster.Spec.ComponentSpecs[i] if spec.Name == defaultCompName { @@ -467,7 +468,7 @@ var _ = Describe("HorizontalScaling OpsRequest", func() { opsRes.OpsRequest.Spec.Force = true // set ops phase to Pending opsRes.OpsRequest.Status.Phase = appsv1alpha1.OpsPendingPhase - mockComponentIsOperating(opsRes.Cluster, appsv1alpha1.UpdatingClusterCompPhase, defaultCompName) + mockComponentIsOperating(opsRes.Cluster, appsv1.UpdatingClusterCompPhase, defaultCompName) By("expect for opsRequest phase is Creating after doing action") _, err := GetOpsManager().Do(reqCtx, k8sClient, opsRes) @@ -582,6 +583,6 @@ func cancelOpsRequest(reqCtx intctrlutil.RequestCtx, opsRes *OpsResource, cancel func mockConsensusCompToRunning(opsRes *OpsResource) { // mock consensus component is Running compStatus := opsRes.Cluster.Status.Components[defaultCompName] - compStatus.Phase = appsv1alpha1.RunningClusterCompPhase + compStatus.Phase = appsv1.RunningClusterCompPhase opsRes.Cluster.Status.Components[defaultCompName] = compStatus } diff --git a/controllers/apps/operations/ops_comp_helper.go b/controllers/apps/operations/ops_comp_helper.go index 77a69f429c6..657f95371d1 100644 --- a/controllers/apps/operations/ops_comp_helper.go +++ b/controllers/apps/operations/ops_comp_helper.go @@ -54,9 +54,9 @@ func newComponentOpsHelper[T ComponentOpsInterface](compOpsList []T) componentOp return compOpsHelper } -func (c componentOpsHelper) updateClusterComponentsAndShardings(cluster *appsv1alpha1.Cluster, - updateFunc func(compSpec *appsv1alpha1.ClusterComponentSpec, compOpsItem ComponentOpsInterface) error) error { - updateComponentSpecs := func(compSpec *appsv1alpha1.ClusterComponentSpec, componentName string) error { +func (c componentOpsHelper) updateClusterComponentsAndShardings(cluster *appsv1.Cluster, + updateFunc func(compSpec *appsv1.ClusterComponentSpec, compOpsItem ComponentOpsInterface) error) error { + updateComponentSpecs := func(compSpec *appsv1.ClusterComponentSpec, componentName string) error { if obj, ok := c.componentOpsSet[componentName]; ok { if err := updateFunc(compSpec, obj); err != nil { return err @@ -82,8 +82,8 @@ func (c componentOpsHelper) updateClusterComponentsAndShardings(cluster *appsv1a } func (c componentOpsHelper) saveLastConfigurations(opsRes *OpsResource, - buildLastCompConfiguration func(compSpec appsv1alpha1.ClusterComponentSpec, obj ComponentOpsInterface) appsv1alpha1.LastComponentConfiguration) { - setLastCompConfiguration := func(compSpec appsv1alpha1.ClusterComponentSpec, + buildLastCompConfiguration func(compSpec appsv1.ClusterComponentSpec, obj ComponentOpsInterface) appsv1alpha1.LastComponentConfiguration) { + setLastCompConfiguration := func(compSpec appsv1.ClusterComponentSpec, lastConfiguration *appsv1alpha1.LastConfiguration, componentName string) { obj, ok := c.componentOpsSet[componentName] @@ -109,8 +109,8 @@ func (c componentOpsHelper) saveLastConfigurations(opsRes *OpsResource, func (c componentOpsHelper) cancelComponentOps(ctx context.Context, cli client.Client, opsRes *OpsResource, - updateCompSpec func(lastConfig *appsv1alpha1.LastComponentConfiguration, comp *appsv1alpha1.ClusterComponentSpec)) error { - rollBackCompSpec := func(compSpec *appsv1alpha1.ClusterComponentSpec, + updateCompSpec func(lastConfig *appsv1alpha1.LastComponentConfiguration, comp *appsv1.ClusterComponentSpec)) error { + rollBackCompSpec := func(compSpec *appsv1.ClusterComponentSpec, lastCompInfos map[string]appsv1alpha1.LastComponentConfiguration, componentName string) { lastConfig, ok := lastCompInfos[componentName] @@ -176,7 +176,7 @@ func (c componentOpsHelper) reconcileActionWithComponentOps(reqCtx intctrlutil.R opsRequest.Status.Components = map[string]appsv1alpha1.OpsRequestComponentStatus{} } var progressResources []progressResource - setProgressResource := func(compSpec *appsv1alpha1.ClusterComponentSpec, compOps ComponentOpsInterface, + setProgressResource := func(compSpec *appsv1.ClusterComponentSpec, compOps ComponentOpsInterface, fullComponentName string, isShardingComponent bool) error { var componentDefinition *appsv1.ComponentDefinition if compSpec.ComponentDef != "" { @@ -259,7 +259,7 @@ func (c componentOpsHelper) reconcileActionWithComponentOps(reqCtx intctrlutil.R if err != nil { return opsRequestPhase, 0, err } - componentPhase = appsv1alpha1.ClusterComponentPhase(compObj.Status.Phase) + componentPhase = appsv1.ClusterComponentPhase(compObj.Status.Phase) } // conditions whether ops is running: // 1. completedProgressCount is not equal to expectProgressCount when the ops do not need to wait component phase to a terminal phase. @@ -269,7 +269,7 @@ func (c componentOpsHelper) reconcileActionWithComponentOps(reqCtx intctrlutil.R opsIsCompleted = false } } else { - if !slices.Contains(appsv1alpha1.GetComponentTerminalPhases(), componentPhase) || completedCount == 0 { + if !slices.Contains(appsv1.GetComponentTerminalPhases(), componentPhase) || completedCount == 0 { opsIsCompleted = false } } diff --git a/controllers/apps/operations/ops_progress_util.go b/controllers/apps/operations/ops_progress_util.go index 0cdf3773a9d..1f3020d8765 100644 --- a/controllers/apps/operations/ops_progress_util.go +++ b/controllers/apps/operations/ops_progress_util.go @@ -33,6 +33,7 @@ import ( "k8s.io/kubectl/pkg/util/podutils" "sigs.k8s.io/controller-runtime/pkg/client" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" "github.com/apecloud/kubeblocks/pkg/constant" @@ -366,7 +367,7 @@ func getProgressFailedMessage(opsMessageKey, objectKey, componentName, podMessag } // getFailedPodMessage gets the failed pod message from cluster component status -func getFailedPodMessage(cluster *appsv1alpha1.Cluster, componentName string, pod *corev1.Pod) string { +func getFailedPodMessage(cluster *appsv1.Cluster, componentName string, pod *corev1.Pod) string { clusterCompStatus := cluster.Status.Components[componentName] return clusterCompStatus.GetObjectMessage(constant.PodKind, pod.Name) } diff --git a/controllers/apps/operations/ops_progress_util_test.go b/controllers/apps/operations/ops_progress_util_test.go index eba194e993a..f2ed1848f27 100644 --- a/controllers/apps/operations/ops_progress_util_test.go +++ b/controllers/apps/operations/ops_progress_util_test.go @@ -31,6 +31,7 @@ import ( "k8s.io/utils/pointer" "sigs.k8s.io/controller-runtime/pkg/client" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" opsutil "github.com/apecloud/kubeblocks/controllers/apps/operations/util" "github.com/apecloud/kubeblocks/pkg/constant" @@ -102,7 +103,7 @@ var _ = Describe("Ops ProgressDetails", func() { By("create restart ops and pods of component") opsRes.OpsRequest = createRestartOpsObj(clusterName, "restart-"+randomStr) - mockComponentIsOperating(opsRes.Cluster, appsv1alpha1.UpdatingClusterCompPhase, defaultCompName) + mockComponentIsOperating(opsRes.Cluster, appsv1.UpdatingClusterCompPhase, defaultCompName) podList := initInstanceSetPods(ctx, k8sClient, opsRes) By("mock restart OpsRequest is Running") @@ -126,7 +127,7 @@ var _ = Describe("Ops ProgressDetails", func() { ComponentOps: appsv1alpha1.ComponentOps{ComponentName: defaultCompName}, Replicas: pointer.Int32(1), }) - mockComponentIsOperating(opsRes.Cluster, appsv1alpha1.UpdatingClusterCompPhase, defaultCompName) // appsv1alpha1.HorizontalScalingPhase + mockComponentIsOperating(opsRes.Cluster, appsv1.UpdatingClusterCompPhase, defaultCompName) // appsv1.HorizontalScalingPhase initClusterForOps(opsRes) By("mock HorizontalScaling OpsRequest phase is running") diff --git a/controllers/apps/operations/ops_util.go b/controllers/apps/operations/ops_util.go index 82221a5e1d6..cf216a59894 100644 --- a/controllers/apps/operations/ops_util.go +++ b/controllers/apps/operations/ops_util.go @@ -22,7 +22,6 @@ package operations import ( "context" "fmt" - appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" "time" "golang.org/x/exp/slices" @@ -31,6 +30,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/client" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" opsutil "github.com/apecloud/kubeblocks/controllers/apps/operations/util" "github.com/apecloud/kubeblocks/pkg/configuration/core" @@ -42,8 +42,8 @@ var _ error = &WaitForClusterPhaseErr{} type WaitForClusterPhaseErr struct { clusterName string - currentPhase appsv1alpha1.ClusterPhase - expectedPhase []appsv1alpha1.ClusterPhase + currentPhase appsv1.ClusterPhase + expectedPhase []appsv1.ClusterPhase } func (e *WaitForClusterPhaseErr) Error() string { @@ -198,7 +198,7 @@ func updateReconfigureStatusByCM(reconfiguringStatus *appsv1alpha1.Reconfiguring // validateOpsWaitingPhase validates whether the current cluster phase is expected, and whether the waiting time exceeds the limit. // only requests with `Pending` phase will be validated. -func validateOpsWaitingPhase(cluster *appsv1alpha1.Cluster, ops *appsv1alpha1.OpsRequest, opsBehaviour OpsBehaviour) error { +func validateOpsWaitingPhase(cluster *appsv1.Cluster, ops *appsv1alpha1.OpsRequest, opsBehaviour OpsBehaviour) error { if ops.Force() { return nil } @@ -309,7 +309,7 @@ func updateHAConfigIfNecessary(reqCtx intctrlutil.RequestCtx, cli client.Client, return cli.Update(reqCtx.Ctx, haConfig) } -func getComponentSpecOrShardingTemplate(cluster *appsv1alpha1.Cluster, componentName string) *appsv1alpha1.ClusterComponentSpec { +func getComponentSpecOrShardingTemplate(cluster *appsv1.Cluster, componentName string) *appsv1.ClusterComponentSpec { for _, v := range cluster.Spec.ComponentSpecs { if v.Name == componentName { return &v diff --git a/controllers/apps/operations/ops_util_test.go b/controllers/apps/operations/ops_util_test.go index 156b7add5ce..ad113012236 100644 --- a/controllers/apps/operations/ops_util_test.go +++ b/controllers/apps/operations/ops_util_test.go @@ -30,6 +30,7 @@ import ( "k8s.io/utils/pointer" "sigs.k8s.io/controller-runtime/pkg/client" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" opsutil "github.com/apecloud/kubeblocks/controllers/apps/operations/util" "github.com/apecloud/kubeblocks/pkg/constant" @@ -104,7 +105,7 @@ var _ = Describe("OpsUtil functions", func() { By("mock component failed") clusterComp := opsRes.Cluster.Status.Components[defaultCompName] - clusterComp.Phase = appsv1alpha1.FailedClusterCompPhase + clusterComp.Phase = appsv1.FailedClusterCompPhase opsRes.Cluster.Status.SetComponentStatus(defaultCompName, clusterComp) By("expect for opsRequest is running") @@ -214,7 +215,7 @@ var _ = Describe("OpsUtil functions", func() { ops2 := runHscaleOps(appsv1alpha1.OpsPendingPhase) By("check opsRequest annotation in cluster") - cluster := &appsv1alpha1.Cluster{} + cluster := &appsv1.Cluster{} Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(opsRes.Cluster), cluster)).Should(Succeed()) opsSlice, _ := opsutil.GetOpsRequestSliceFromCluster(cluster) Expect(len(opsSlice)).Should(Equal(2)) @@ -238,7 +239,7 @@ var _ = Describe("OpsUtil functions", func() { g.Expect(ops.Status.Phase).Should(Equal(appsv1alpha1.OpsCancelledPhase)) }) - testapps.CheckObj(&testCtx, client.ObjectKeyFromObject(cluster), func(g Gomega, cluster *appsv1alpha1.Cluster) { + testapps.CheckObj(&testCtx, client.ObjectKeyFromObject(cluster), func(g Gomega, cluster *appsv1.Cluster) { opsSlice, _ = opsutil.GetOpsRequestSliceFromCluster(cluster) // expect cluster's opsRequest queue is empty g.Expect(opsSlice).Should(BeEmpty()) @@ -308,7 +309,7 @@ var _ = Describe("OpsUtil functions", func() { By("mock cluster phase to Updating") Expect(testapps.ChangeObjStatus(&testCtx, opsRes.Cluster, func() { - opsRes.Cluster.Status.Phase = appsv1alpha1.UpdatingClusterPhase + opsRes.Cluster.Status.Phase = appsv1.UpdatingClusterPhase })).Should(Succeed()) By("expect the ops phase is failed") diff --git a/controllers/apps/operations/rebuild_instance.go b/controllers/apps/operations/rebuild_instance.go index bad109e8cce..8f462bfdbe4 100644 --- a/controllers/apps/operations/rebuild_instance.go +++ b/controllers/apps/operations/rebuild_instance.go @@ -31,6 +31,7 @@ import ( "k8s.io/utils/pointer" "sigs.k8s.io/controller-runtime/pkg/client" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" dpv1alpha1 "github.com/apecloud/kubeblocks/apis/dataprotection/v1alpha1" "github.com/apecloud/kubeblocks/pkg/constant" @@ -58,8 +59,8 @@ var _ OpsHandler = rebuildInstanceOpsHandler{} func init() { rebuildInstanceBehaviour := OpsBehaviour{ - FromClusterPhases: []appsv1alpha1.ClusterPhase{appsv1alpha1.AbnormalClusterPhase, appsv1alpha1.FailedClusterPhase, appsv1alpha1.UpdatingClusterPhase}, - ToClusterPhase: appsv1alpha1.UpdatingClusterPhase, + FromClusterPhases: []appsv1.ClusterPhase{appsv1.AbnormalClusterPhase, appsv1.FailedClusterPhase, appsv1.UpdatingClusterPhase}, + ToClusterPhase: appsv1.UpdatingClusterPhase, QueueByCluster: true, OpsHandler: rebuildInstanceOpsHandler{}, } @@ -79,8 +80,8 @@ func (r rebuildInstanceOpsHandler) Action(reqCtx intctrlutil.RequestCtx, cli cli continue } // check if the component has matched the `Phase` condition - if !opsRes.OpsRequest.Spec.Force && !slices.Contains([]appsv1alpha1.ClusterComponentPhase{appsv1alpha1.FailedClusterCompPhase, - appsv1alpha1.AbnormalClusterCompPhase, appsv1alpha1.UpdatingClusterCompPhase}, compStatus.Phase) { + if !opsRes.OpsRequest.Spec.Force && !slices.Contains([]appsv1.ClusterComponentPhase{appsv1.FailedClusterCompPhase, + appsv1.AbnormalClusterCompPhase, appsv1.UpdatingClusterCompPhase}, compStatus.Phase) { return intctrlutil.NewFatalError(fmt.Sprintf(`the phase of component "%s" can not be %s`, v.ComponentName, compStatus.Phase)) } var ( @@ -141,7 +142,7 @@ func (r rebuildInstanceOpsHandler) validateRebuildInstanceWithHScale(reqCtx intc func (r rebuildInstanceOpsHandler) SaveLastConfiguration(reqCtx intctrlutil.RequestCtx, cli client.Client, opsRes *OpsResource) error { compOpsHelper := newComponentOpsHelper(opsRes.OpsRequest.Spec.RebuildFrom) - getLastComponentInfo := func(compSpec appsv1alpha1.ClusterComponentSpec, comOps ComponentOpsInterface) appsv1alpha1.LastComponentConfiguration { + getLastComponentInfo := func(compSpec appsv1.ClusterComponentSpec, comOps ComponentOpsInterface) appsv1alpha1.LastComponentConfiguration { lastCompConfiguration := appsv1alpha1.LastComponentConfiguration{ Replicas: pointer.Int32(compSpec.Replicas), Instances: compSpec.Instances, @@ -365,7 +366,7 @@ func (r rebuildInstanceOpsHandler) getRebuildInstanceWrapper(opsRes *OpsResource } func (r rebuildInstanceOpsHandler) scaleOutCompReplicasAndSyncProgress(opsRes *OpsResource, - compSpec *appsv1alpha1.ClusterComponentSpec, + compSpec *appsv1.ClusterComponentSpec, rebuildInstance appsv1alpha1.RebuildInstance, compStatus *appsv1alpha1.OpsRequestComponentStatus, rebuildInsWrapper map[string]*rebuildInstanceWrapper) { @@ -409,7 +410,7 @@ func (r rebuildInstanceOpsHandler) checkProgressForScalingOutPods(reqCtx intctrl cli client.Client, opsRes *OpsResource, rebuildInstance appsv1alpha1.RebuildInstance, - compSpec *appsv1alpha1.ClusterComponentSpec, + compSpec *appsv1.ClusterComponentSpec, compStatus *appsv1alpha1.OpsRequestComponentStatus) (int, int, []string, error) { var ( instancesNeedToOffline []string @@ -480,10 +481,10 @@ func (r rebuildInstanceOpsHandler) checkProgressForScalingOutPods(reqCtx intctrl } // offlineSpecifiedInstances to take the specific instances offline. -func (r rebuildInstanceOpsHandler) offlineSpecifiedInstances(compSpec *appsv1alpha1.ClusterComponentSpec, clusterName string, instancesNeedToOffline []string) { +func (r rebuildInstanceOpsHandler) offlineSpecifiedInstances(compSpec *appsv1.ClusterComponentSpec, clusterName string, instancesNeedToOffline []string) { for _, insName := range instancesNeedToOffline { compSpec.OfflineInstances = append(compSpec.OfflineInstances, insName) - templateName := appsv1alpha1.GetInstanceTemplateName(clusterName, compSpec.Name, insName) + templateName := appsv1.GetInstanceTemplateName(clusterName, compSpec.Name, insName) if templateName == constant.EmptyInsTemplateName { continue } @@ -511,7 +512,7 @@ func (r rebuildInstanceOpsHandler) getScalingOutPodNameFromMessage(progressMsg s func (r rebuildInstanceOpsHandler) buildSynthesizedComponent(reqCtx intctrlutil.RequestCtx, cli client.Client, - cluster *appsv1alpha1.Cluster, + cluster *appsv1.Cluster, componentName string) (*component.SynthesizedComponent, error) { compSpec := getComponentSpecOrShardingTemplate(cluster, componentName) if compSpec.ComponentDef == "" { diff --git a/controllers/apps/operations/rebuild_instance_test.go b/controllers/apps/operations/rebuild_instance_test.go index e9829ceee77..4c22affb534 100644 --- a/controllers/apps/operations/rebuild_instance_test.go +++ b/controllers/apps/operations/rebuild_instance_test.go @@ -21,6 +21,7 @@ package operations import ( "fmt" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" @@ -171,7 +172,7 @@ var _ = Describe("OpsUtil functions", func() { By("fake cluster phase to Abnormal and component phase to Running") Expect(testapps.ChangeObjStatus(&testCtx, opsRes.Cluster, func() { - opsRes.Cluster.Status.Phase = appsv1alpha1.AbnormalClusterPhase + opsRes.Cluster.Status.Phase = appsv1.AbnormalClusterPhase })).Should(Succeed()) opsRes.OpsRequest.Status.Phase = appsv1alpha1.OpsCreatingPhase @@ -184,7 +185,7 @@ var _ = Describe("OpsUtil functions", func() { opsRes.OpsRequest.Status.Phase = appsv1alpha1.OpsCreatingPhase Expect(testapps.ChangeObjStatus(&testCtx, opsRes.Cluster, func() { compStatus := opsRes.Cluster.Status.Components[defaultCompName] - compStatus.Phase = appsv1alpha1.AbnormalClusterCompPhase + compStatus.Phase = appsv1.AbnormalClusterCompPhase opsRes.Cluster.Status.Components[defaultCompName] = compStatus })).Should(Succeed()) @@ -398,8 +399,8 @@ var _ = Describe("OpsUtil functions", func() { opsRes.OpsRequest.Status.Phase = appsv1alpha1.OpsCreatingPhase Expect(testapps.ChangeObjStatus(&testCtx, opsRes.Cluster, func() { compStatus := opsRes.Cluster.Status.Components[defaultCompName] - compStatus.Phase = appsv1alpha1.AbnormalClusterCompPhase - opsRes.Cluster.Status.Phase = appsv1alpha1.AbnormalClusterPhase + compStatus.Phase = appsv1.AbnormalClusterCompPhase + opsRes.Cluster.Status.Phase = appsv1.AbnormalClusterPhase opsRes.Cluster.Status.Components[defaultCompName] = compStatus })).Should(Succeed()) diff --git a/controllers/apps/operations/reconfigure_test.go b/controllers/apps/operations/reconfigure_test.go index 12b2fd403e2..ccf5ff1db43 100644 --- a/controllers/apps/operations/reconfigure_test.go +++ b/controllers/apps/operations/reconfigure_test.go @@ -76,7 +76,7 @@ var _ = Describe("Reconfigure OpsRequest", func() { initClusterForOps := func(opsRes *OpsResource) { Expect(opsutil.UpdateClusterOpsAnnotations(ctx, k8sClient, opsRes.Cluster, nil)).Should(Succeed()) - opsRes.Cluster.Status.Phase = appsv1alpha1.RunningClusterPhase + opsRes.Cluster.Status.Phase = appsv1.RunningClusterPhase } assureCfgTplObj := func(tplName, cmName, ns string) (*corev1.ConfigMap, *appsv1beta1.ConfigConstraint) { @@ -150,7 +150,7 @@ var _ = Describe("Reconfigure OpsRequest", func() { // mock cluster is Running to support reconfiguring ops By("mock cluster status") patch := client.MergeFrom(clusterObject.DeepCopy()) - clusterObject.Status.Phase = appsv1alpha1.RunningClusterPhase + clusterObject.Status.Phase = appsv1.RunningClusterPhase Expect(k8sClient.Status().Patch(ctx, clusterObject, patch)).Should(Succeed()) } @@ -319,7 +319,7 @@ var _ = Describe("Reconfigure OpsRequest", func() { By("Reconfigure configure") _, _ = opsManager.Reconcile(reqCtx, k8sClient, opsRes) // mock cluster.status.component.phase to Updating - mockClusterCompPhase := func(clusterObj *appsv1alpha1.Cluster, phase appsv1alpha1.ClusterComponentPhase) { + mockClusterCompPhase := func(clusterObj *appsv1.Cluster, phase appsv1.ClusterComponentPhase) { clusterObject := clusterObj.DeepCopy() patch := client.MergeFrom(clusterObject.DeepCopy()) compStatus := clusterObject.Status.Components[defaultCompName] @@ -327,20 +327,20 @@ var _ = Describe("Reconfigure OpsRequest", func() { clusterObject.Status.Components[defaultCompName] = compStatus Expect(k8sClient.Status().Patch(ctx, clusterObject, patch)).Should(Succeed()) } - mockClusterCompPhase(opsRes.Cluster, appsv1alpha1.UpdatingClusterCompPhase) + mockClusterCompPhase(opsRes.Cluster, appsv1.UpdatingClusterCompPhase) Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(opsRes.Cluster), opsRes.Cluster)).Should(Succeed()) By("check cluster.status.components[*].phase == Reconfiguring") Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(opsRes.OpsRequest), opsRes.OpsRequest)).Should(Succeed()) - Expect(opsRes.Cluster.Status.Components[defaultCompName].Phase).Should(Equal(appsv1alpha1.UpdatingClusterCompPhase)) // appsv1alpha1.ReconfiguringPhase + Expect(opsRes.Cluster.Status.Components[defaultCompName].Phase).Should(Equal(appsv1.UpdatingClusterCompPhase)) // appsv1.ReconfiguringPhase // TODO: add status condition expect _, _ = opsManager.Reconcile(reqCtx, k8sClient, opsRes) // mock cluster.status.component.phase to Running - mockClusterCompPhase(opsRes.Cluster, appsv1alpha1.RunningClusterCompPhase) + mockClusterCompPhase(opsRes.Cluster, appsv1.RunningClusterCompPhase) By("check cluster.status.components[*].phase == Running") Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(opsRes.Cluster), opsRes.Cluster)).Should(Succeed()) - Expect(opsRes.Cluster.Status.Components[defaultCompName].Phase).Should(Equal(appsv1alpha1.RunningClusterCompPhase)) + Expect(opsRes.Cluster.Status.Components[defaultCompName].Phase).Should(Equal(appsv1.RunningClusterCompPhase)) }) }) }) diff --git a/controllers/apps/operations/restart_test.go b/controllers/apps/operations/restart_test.go index 87ed873a07b..cbbc5e2ea46 100644 --- a/controllers/apps/operations/restart_test.go +++ b/controllers/apps/operations/restart_test.go @@ -22,9 +22,11 @@ package operations import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" + "k8s.io/apimachinery/pkg/api/meta" "sigs.k8s.io/controller-runtime/pkg/client" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" intctrlutil "github.com/apecloud/kubeblocks/pkg/controllerutil" "github.com/apecloud/kubeblocks/pkg/generics" @@ -63,7 +65,7 @@ var _ = Describe("Restart OpsRequest", func() { Context("Test OpsRequest", func() { var ( opsRes *OpsResource - cluster *appsv1alpha1.Cluster + cluster *appsv1.Cluster reqCtx intctrlutil.RequestCtx ) @@ -76,7 +78,7 @@ var _ = Describe("Restart OpsRequest", func() { It("Test restart OpsRequest", func() { By("create Restart opsRequest") opsRes.OpsRequest = createRestartOpsObj(clusterName, "restart-ops-"+randomStr) - mockComponentIsOperating(opsRes.Cluster, appsv1alpha1.UpdatingClusterCompPhase, defaultCompName) + mockComponentIsOperating(opsRes.Cluster, appsv1.UpdatingClusterCompPhase, defaultCompName) By("mock restart OpsRequest is Running") _, err := GetOpsManager().Do(reqCtx, k8sClient, opsRes) @@ -94,7 +96,7 @@ var _ = Describe("Restart OpsRequest", func() { It("expect failed when cluster is stopped", func() { By("mock cluster is stopped") Expect(testapps.ChangeObjStatus(&testCtx, cluster, func() { - cluster.Status.Phase = appsv1alpha1.StoppedClusterPhase + cluster.Status.Phase = appsv1.StoppedClusterPhase })).Should(Succeed()) By("create Restart opsRequest") opsRes.OpsRequest = createRestartOpsObj(clusterName, "restart-ops-"+randomStr) diff --git a/controllers/apps/operations/restore.go b/controllers/apps/operations/restore.go index 6824a3d3ff2..a514cb1c45b 100644 --- a/controllers/apps/operations/restore.go +++ b/controllers/apps/operations/restore.go @@ -30,6 +30,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" dpv1alpha1 "github.com/apecloud/kubeblocks/apis/dataprotection/v1alpha1" "github.com/apecloud/kubeblocks/controllers/apps/operations/util" @@ -62,7 +63,7 @@ func (r RestoreOpsHandler) ActionStartedCondition(reqCtx intctrlutil.RequestCtx, // Action implements the restore action. func (r RestoreOpsHandler) Action(reqCtx intctrlutil.RequestCtx, cli client.Client, opsRes *OpsResource) error { - var cluster *appsv1alpha1.Cluster + var cluster *appsv1.Cluster var err error opsRequest := opsRes.OpsRequest @@ -106,7 +107,7 @@ func (r RestoreOpsHandler) ReconcileAction(reqCtx intctrlutil.RequestCtx, cli cl clusterDef := opsRequest.Spec.GetClusterName() // get cluster - cluster := &appsv1alpha1.Cluster{} + cluster := &appsv1.Cluster{} if err := cli.Get(reqCtx.Ctx, client.ObjectKey{ Namespace: opsRequest.GetNamespace(), Name: clusterDef, @@ -118,9 +119,9 @@ func (r RestoreOpsHandler) ReconcileAction(reqCtx intctrlutil.RequestCtx, cli cl } // check if the cluster is running - if cluster.Status.Phase == appsv1alpha1.RunningClusterPhase { + if cluster.Status.Phase == appsv1.RunningClusterPhase { return appsv1alpha1.OpsSucceedPhase, 0, nil - } else if cluster.Status.Phase == appsv1alpha1.FailedClusterPhase { + } else if cluster.Status.Phase == appsv1.FailedClusterPhase { return appsv1alpha1.OpsFailedPhase, 0, fmt.Errorf("restore failed") } return appsv1alpha1.OpsRunningPhase, 0, nil @@ -131,7 +132,7 @@ func (r RestoreOpsHandler) SaveLastConfiguration(reqCtx intctrlutil.RequestCtx, return nil } -func (r RestoreOpsHandler) restoreClusterFromBackup(reqCtx intctrlutil.RequestCtx, cli client.Client, opsRequest *appsv1alpha1.OpsRequest) (*appsv1alpha1.Cluster, error) { +func (r RestoreOpsHandler) restoreClusterFromBackup(reqCtx intctrlutil.RequestCtx, cli client.Client, opsRequest *appsv1alpha1.OpsRequest) (*appsv1.Cluster, error) { restoreSpec := opsRequest.Spec.GetRestore() if restoreSpec == nil { return nil, intctrlutil.NewFatalError("spec.restore can not be empty") @@ -176,8 +177,8 @@ func (r RestoreOpsHandler) restoreClusterFromBackup(reqCtx intctrlutil.RequestCt return clusterObj, nil } -func (r RestoreOpsHandler) getClusterObjFromBackup(backup *dpv1alpha1.Backup, opsRequest *appsv1alpha1.OpsRequest) (*appsv1alpha1.Cluster, error) { - cluster := &appsv1alpha1.Cluster{} +func (r RestoreOpsHandler) getClusterObjFromBackup(backup *dpv1alpha1.Backup, opsRequest *appsv1alpha1.OpsRequest) (*appsv1.Cluster, error) { + cluster := &appsv1.Cluster{} // use the cluster snapshot to restore firstly clusterString, ok := backup.Annotations[constant.ClusterSnapshotAnnotationKey] if !ok { @@ -198,7 +199,7 @@ func (r RestoreOpsHandler) getClusterObjFromBackup(backup *dpv1alpha1.Backup, op cluster.Annotations[constant.RestoreFromBackupAnnotationKey] = restoreAnnotation cluster.Name = opsRequest.Spec.GetClusterName() // Reset cluster services - var services []appsv1alpha1.ClusterService + var services []appsv1.ClusterService for i := range cluster.Spec.Services { svc := cluster.Spec.Services[i] if svc.Service.Spec.Type == corev1.ServiceTypeLoadBalancer { diff --git a/controllers/apps/operations/restore_test.go b/controllers/apps/operations/restore_test.go index b49c37db93e..bcaa5c688c9 100644 --- a/controllers/apps/operations/restore_test.go +++ b/controllers/apps/operations/restore_test.go @@ -29,6 +29,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/client" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" dpv1alpha1 "github.com/apecloud/kubeblocks/apis/dataprotection/v1alpha1" "github.com/apecloud/kubeblocks/pkg/constant" @@ -110,7 +111,7 @@ var _ = Describe("Restore OpsRequest", func() { _ = restoreHandler.Action(reqCtx, k8sClient, opsRes) By("test restore reconcile function") - opsRes.Cluster.Status.Phase = appsv1alpha1.RunningClusterPhase + opsRes.Cluster.Status.Phase = appsv1.RunningClusterPhase _, err = GetOpsManager().Reconcile(reqCtx, k8sClient, opsRes) Expect(err).ShouldNot(HaveOccurred()) Expect(opsRes.OpsRequest.Status.Phase).Should(Equal(appsv1alpha1.OpsSucceedPhase)) @@ -118,10 +119,10 @@ var _ = Describe("Restore OpsRequest", func() { It("test if source cluster exists services", func() { By("mock backup annotations and labels") - opsRes.Cluster.Spec.Services = []appsv1alpha1.ClusterService{ + opsRes.Cluster.Spec.Services = []appsv1.ClusterService{ { ComponentSelector: defaultCompName, - Service: appsv1alpha1.Service{ + Service: appsv1.Service{ Name: "svc", Spec: corev1.ServiceSpec{ Ports: []corev1.ServicePort{ @@ -132,7 +133,7 @@ var _ = Describe("Restore OpsRequest", func() { }, { ComponentSelector: defaultCompName, - Service: appsv1alpha1.Service{ + Service: appsv1.Service{ Name: "svc-2", ServiceName: "svc-2", Spec: corev1.ServiceSpec{ @@ -170,7 +171,7 @@ var _ = Describe("Restore OpsRequest", func() { _ = restoreHandler.Action(reqCtx, k8sClient, opsRes) By("the loadBalancer should be reset") - Eventually(testapps.CheckObj(&testCtx, client.ObjectKey{Name: restoreClusterName, Namespace: opsRes.OpsRequest.Namespace}, func(g Gomega, restoreCluster *appsv1alpha1.Cluster) { + Eventually(testapps.CheckObj(&testCtx, client.ObjectKey{Name: restoreClusterName, Namespace: opsRes.OpsRequest.Namespace}, func(g Gomega, restoreCluster *appsv1.Cluster) { Expect(restoreCluster.Spec.Services).Should(HaveLen(1)) })).Should(Succeed()) }) diff --git a/controllers/apps/operations/start.go b/controllers/apps/operations/start.go index a8134109c34..ed229c50b3a 100644 --- a/controllers/apps/operations/start.go +++ b/controllers/apps/operations/start.go @@ -25,6 +25,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/client" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" intctrlcomp "github.com/apecloud/kubeblocks/pkg/controller/component" intctrlutil "github.com/apecloud/kubeblocks/pkg/controllerutil" @@ -36,8 +37,8 @@ var _ OpsHandler = StartOpsHandler{} func init() { stopBehaviour := OpsBehaviour{ - FromClusterPhases: []appsv1alpha1.ClusterPhase{appsv1alpha1.StoppedClusterPhase}, - ToClusterPhase: appsv1alpha1.UpdatingClusterPhase, + FromClusterPhases: []appsv1.ClusterPhase{appsv1.StoppedClusterPhase}, + ToClusterPhase: appsv1.UpdatingClusterPhase, QueueByCluster: true, OpsHandler: StartOpsHandler{}, } @@ -55,7 +56,7 @@ func (start StartOpsHandler) ActionStartedCondition(reqCtx intctrlutil.RequestCt func (start StartOpsHandler) Action(reqCtx intctrlutil.RequestCtx, cli client.Client, opsRes *OpsResource) error { var ( cluster = opsRes.Cluster - startComp = func(compSpec *appsv1alpha1.ClusterComponentSpec) { + startComp = func(compSpec *appsv1.ClusterComponentSpec) { compSpec.Stop = nil } ) diff --git a/controllers/apps/operations/start_test.go b/controllers/apps/operations/start_test.go index 6fcae5df6ee..3b4a5901f9a 100644 --- a/controllers/apps/operations/start_test.go +++ b/controllers/apps/operations/start_test.go @@ -25,6 +25,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" opsutil "github.com/apecloud/kubeblocks/controllers/apps/operations/util" intctrlutil "github.com/apecloud/kubeblocks/pkg/controllerutil" @@ -76,7 +77,7 @@ var _ = Describe("Start OpsRequest", func() { Expect(opsutil.UpdateClusterOpsAnnotations(ctx, k8sClient, opsRes.Cluster, nil)).Should(Succeed()) // mock cluster phase to stopped Expect(testapps.ChangeObjStatus(&testCtx, opsRes.Cluster, func() { - opsRes.Cluster.Status.Phase = appsv1alpha1.StoppedClusterPhase + opsRes.Cluster.Status.Phase = appsv1.StoppedClusterPhase })).ShouldNot(HaveOccurred()) // set ops phase to Pending diff --git a/controllers/apps/operations/stop.go b/controllers/apps/operations/stop.go index 2ea2b68adf6..d1e0532f44c 100644 --- a/controllers/apps/operations/stop.go +++ b/controllers/apps/operations/stop.go @@ -26,6 +26,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/client" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" intctrlcomp "github.com/apecloud/kubeblocks/pkg/controller/component" intctrlutil "github.com/apecloud/kubeblocks/pkg/controllerutil" @@ -37,8 +38,8 @@ var _ OpsHandler = StopOpsHandler{} func init() { stopBehaviour := OpsBehaviour{ - FromClusterPhases: append(appsv1alpha1.GetClusterUpRunningPhases(), appsv1alpha1.UpdatingClusterPhase), - ToClusterPhase: appsv1alpha1.StoppingClusterPhase, + FromClusterPhases: append(appsv1.GetClusterUpRunningPhases(), appsv1.UpdatingClusterPhase), + ToClusterPhase: appsv1.StoppingClusterPhase, QueueByCluster: true, OpsHandler: StopOpsHandler{}, } @@ -59,8 +60,8 @@ func (stop StopOpsHandler) Action(reqCtx intctrlutil.RequestCtx, cli client.Clie ) // if the cluster is already stopping or stopped, return - if slices.Contains([]appsv1alpha1.ClusterPhase{appsv1alpha1.StoppedClusterPhase, - appsv1alpha1.StoppingClusterPhase}, opsRes.Cluster.Status.Phase) { + if slices.Contains([]appsv1.ClusterPhase{appsv1.StoppedClusterPhase, + appsv1.StoppingClusterPhase}, opsRes.Cluster.Status.Phase) { return nil } @@ -73,7 +74,7 @@ func (stop StopOpsHandler) Action(reqCtx intctrlutil.RequestCtx, cli client.Clie return err } - stopComp := func(compSpec *appsv1alpha1.ClusterComponentSpec) { + stopComp := func(compSpec *appsv1.ClusterComponentSpec) { compSpec.Stop = func() *bool { b := true; return &b }() } diff --git a/controllers/apps/operations/suite_test.go b/controllers/apps/operations/suite_test.go index 71cbc7c88c3..0c9f2ca3abd 100644 --- a/controllers/apps/operations/suite_test.go +++ b/controllers/apps/operations/suite_test.go @@ -147,7 +147,7 @@ var _ = AfterSuite(func() { Expect(err).NotTo(HaveOccurred()) }) -func initOperationsResources(compDefName, clusterName string) (*OpsResource, *appsv1.ComponentDefinition, *appsv1alpha1.Cluster) { +func initOperationsResources(compDefName, clusterName string) (*OpsResource, *appsv1.ComponentDefinition, *appsv1.Cluster) { compDef := testapps.NewComponentDefinitionFactory(compDefName). SetDefaultSpec(). Create(&testCtx). @@ -168,10 +168,10 @@ func initOperationsResources(compDefName, clusterName string) (*OpsResource, *ap By("mock cluster is Running and the status operations") Expect(testapps.ChangeObjStatus(&testCtx, clusterObject, func() { - clusterObject.Status.Phase = appsv1alpha1.RunningClusterPhase - clusterObject.Status.Components = map[string]appsv1alpha1.ClusterComponentStatus{ + clusterObject.Status.Phase = appsv1.RunningClusterPhase + clusterObject.Status.Components = map[string]appsv1.ClusterComponentStatus{ defaultCompName: { - Phase: appsv1alpha1.RunningClusterCompPhase, + Phase: appsv1.RunningClusterCompPhase, }, } })).Should(Succeed()) @@ -190,7 +190,7 @@ func initInstanceSetPods(ctx context.Context, cli client.Client, opsRes *OpsReso return pods } -func mockComponentIsOperating(cluster *appsv1alpha1.Cluster, expectPhase appsv1alpha1.ClusterComponentPhase, compNames ...string) { +func mockComponentIsOperating(cluster *appsv1.Cluster, expectPhase appsv1.ClusterComponentPhase, compNames ...string) { Expect(testapps.ChangeObjStatus(&testCtx, cluster, func() { for _, v := range compNames { compStatus := cluster.Status.Components[v] diff --git a/controllers/apps/operations/switchover.go b/controllers/apps/operations/switchover.go index 8c628d4a0e5..59641c030ff 100644 --- a/controllers/apps/operations/switchover.go +++ b/controllers/apps/operations/switchover.go @@ -31,6 +31,7 @@ import ( "k8s.io/client-go/tools/record" "sigs.k8s.io/controller-runtime/pkg/client" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" "github.com/apecloud/kubeblocks/pkg/constant" "github.com/apecloud/kubeblocks/pkg/controller/component" @@ -51,8 +52,8 @@ type SwitchoverMessage struct { func init() { switchoverBehaviour := OpsBehaviour{ - FromClusterPhases: appsv1alpha1.GetClusterUpRunningPhases(), - ToClusterPhase: appsv1alpha1.UpdatingClusterPhase, + FromClusterPhases: appsv1.GetClusterUpRunningPhases(), + ToClusterPhase: appsv1.UpdatingClusterPhase, QueueByCluster: true, OpsHandler: switchoverOpsHandler{}, } @@ -142,7 +143,7 @@ func doSwitchoverComponents(reqCtx intctrlutil.RequestCtx, cli client.Client, op } if !needSwitchover { opsRequest.Status.Components[switchover.ComponentName] = appsv1alpha1.OpsRequestComponentStatus{ - Phase: appsv1alpha1.RunningClusterCompPhase, + Phase: appsv1.RunningClusterCompPhase, Reason: OpsReasonForSkipSwitchover, Message: fmt.Sprintf("This component %s is already in the expected state, skip the switchover operation", switchover.ComponentName), ProgressDetails: []appsv1alpha1.ProgressStatusDetail{}, @@ -150,7 +151,7 @@ func doSwitchoverComponents(reqCtx intctrlutil.RequestCtx, cli client.Client, op continue } else { opsRequest.Status.Components[switchover.ComponentName] = appsv1alpha1.OpsRequestComponentStatus{ - Phase: appsv1alpha1.UpdatingClusterCompPhase, + Phase: appsv1.UpdatingClusterCompPhase, ProgressDetails: []appsv1alpha1.ProgressStatusDetail{}, } } @@ -211,12 +212,12 @@ func handleSwitchoverProgress(reqCtx intctrlutil.RequestCtx, cli client.Client, err = nil } checkJobProcessDetail.Message = fmt.Sprintf("switchover job %s is not succeed", jobName) - setComponentSwitchoverProgressDetails(reqCtx.Recorder, opsRequest, appsv1alpha1.UpdatingClusterCompPhase, checkJobProcessDetail, switchover.ComponentName) + setComponentSwitchoverProgressDetails(reqCtx.Recorder, opsRequest, appsv1.UpdatingClusterCompPhase, checkJobProcessDetail, switchover.ComponentName) continue } else { checkJobProcessDetail.Message = fmt.Sprintf("switchover job %s is succeed", jobName) checkJobProcessDetail.Status = appsv1alpha1.SucceedProgressStatus - setComponentSwitchoverProgressDetails(reqCtx.Recorder, opsRequest, appsv1alpha1.UpdatingClusterCompPhase, checkJobProcessDetail, switchover.ComponentName) + setComponentSwitchoverProgressDetails(reqCtx.Recorder, opsRequest, appsv1.UpdatingClusterCompPhase, checkJobProcessDetail, switchover.ComponentName) } // check the current component pod role label whether correct @@ -230,24 +231,24 @@ func handleSwitchoverProgress(reqCtx intctrlutil.RequestCtx, cli client.Client, if errBuild != nil { checkRoleLabelProcessDetail.Message = fmt.Sprintf("handleSwitchoverProgress build synthesizedComponent %s failed", switchover.ComponentName) checkRoleLabelProcessDetail.Status = appsv1alpha1.FailedProgressStatus - setComponentSwitchoverProgressDetails(reqCtx.Recorder, opsRequest, appsv1alpha1.UpdatingClusterCompPhase, checkRoleLabelProcessDetail, switchover.ComponentName) + setComponentSwitchoverProgressDetails(reqCtx.Recorder, opsRequest, appsv1.UpdatingClusterCompPhase, checkRoleLabelProcessDetail, switchover.ComponentName) continue } consistency, err = checkPodRoleLabelConsistency(reqCtx.Ctx, cli, *synthesizedComp, &switchover, switchoverCondition) if err != nil { checkRoleLabelProcessDetail.Message = fmt.Sprintf("waiting for component %s pod role label consistency after switchover", switchover.ComponentName) - setComponentSwitchoverProgressDetails(reqCtx.Recorder, opsRequest, appsv1alpha1.UpdatingClusterCompPhase, checkRoleLabelProcessDetail, switchover.ComponentName) + setComponentSwitchoverProgressDetails(reqCtx.Recorder, opsRequest, appsv1.UpdatingClusterCompPhase, checkRoleLabelProcessDetail, switchover.ComponentName) continue } if !consistency { err = intctrlutil.NewErrorf(intctrlutil.ErrorWaitCacheRefresh, "requeue to waiting for pod role label consistency.") - setComponentSwitchoverProgressDetails(reqCtx.Recorder, opsRequest, appsv1alpha1.UpdatingClusterCompPhase, checkRoleLabelProcessDetail, switchover.ComponentName) + setComponentSwitchoverProgressDetails(reqCtx.Recorder, opsRequest, appsv1.UpdatingClusterCompPhase, checkRoleLabelProcessDetail, switchover.ComponentName) continue } else { checkRoleLabelProcessDetail.Message = fmt.Sprintf("check component %s pod role label consistency after switchover is succeed", switchover.ComponentName) checkRoleLabelProcessDetail.Status = appsv1alpha1.SucceedProgressStatus - setComponentSwitchoverProgressDetails(reqCtx.Recorder, opsRequest, appsv1alpha1.UpdatingClusterCompPhase, checkRoleLabelProcessDetail, switchover.ComponentName) + setComponentSwitchoverProgressDetails(reqCtx.Recorder, opsRequest, appsv1.UpdatingClusterCompPhase, checkRoleLabelProcessDetail, switchover.ComponentName) } // component switchover is successful @@ -258,7 +259,7 @@ func handleSwitchoverProgress(reqCtx intctrlutil.RequestCtx, cli client.Client, Message: fmt.Sprintf("switchover job %s is succeed", jobName), Status: appsv1alpha1.SucceedProgressStatus, } - setComponentSwitchoverProgressDetails(reqCtx.Recorder, opsRequest, appsv1alpha1.RunningClusterCompPhase, componentProcessDetail, switchover.ComponentName) + setComponentSwitchoverProgressDetails(reqCtx.Recorder, opsRequest, appsv1.RunningClusterCompPhase, componentProcessDetail, switchover.ComponentName) } opsRequest.Status.Progress = fmt.Sprintf("%d/%d", completedCount, expectCount) @@ -288,7 +289,7 @@ func handleSwitchoverProgress(reqCtx intctrlutil.RequestCtx, cli client.Client, // setComponentSwitchoverProgressDetails sets component switchover progress details. func setComponentSwitchoverProgressDetails(recorder record.EventRecorder, opsRequest *appsv1alpha1.OpsRequest, - phase appsv1alpha1.ClusterComponentPhase, + phase appsv1.ClusterComponentPhase, processDetail appsv1alpha1.ProgressStatusDetail, componentName string) { componentProcessDetails := opsRequest.Status.Components[componentName].ProgressDetails @@ -300,7 +301,7 @@ func setComponentSwitchoverProgressDetails(recorder record.EventRecorder, } // buildSynthesizedComp builds synthesized component for native component or generated component. -func buildSynthesizedComp(reqCtx intctrlutil.RequestCtx, cli client.Client, opsRes *OpsResource, clusterCompSpec *appsv1alpha1.ClusterComponentSpec) (*component.SynthesizedComponent, error) { +func buildSynthesizedComp(reqCtx intctrlutil.RequestCtx, cli client.Client, opsRes *OpsResource, clusterCompSpec *appsv1.ClusterComponentSpec) (*component.SynthesizedComponent, error) { if len(clusterCompSpec.ComponentDef) > 0 { compObj, compDefObj, err := component.GetCompNCompDefByName(reqCtx.Ctx, cli, opsRes.Cluster.Namespace, constant.GenerateClusterComponentName(opsRes.Cluster.Name, clusterCompSpec.Name)) diff --git a/controllers/apps/operations/switchover_test.go b/controllers/apps/operations/switchover_test.go index a17d7dd9a23..5d46033e271 100644 --- a/controllers/apps/operations/switchover_test.go +++ b/controllers/apps/operations/switchover_test.go @@ -44,7 +44,7 @@ var _ = Describe("", func() { compDefName = "test-compdef-" + randomStr clusterName = "test-cluster-" + randomStr compDefObj *appsv1.ComponentDefinition - clusterObj *appsv1alpha1.Cluster + clusterObj *appsv1.Cluster ) defaultRole := func(index int32) string { @@ -153,10 +153,10 @@ var _ = Describe("", func() { } By("mock cluster is Running and the status operations") Expect(testapps.ChangeObjStatus(&testCtx, clusterObj, func() { - clusterObj.Status.Phase = appsv1alpha1.RunningClusterPhase - clusterObj.Status.Components = map[string]appsv1alpha1.ClusterComponentStatus{ + clusterObj.Status.Phase = appsv1.RunningClusterPhase + clusterObj.Status.Components = map[string]appsv1.ClusterComponentStatus{ defaultCompName: { - Phase: appsv1alpha1.RunningClusterCompPhase, + Phase: appsv1.RunningClusterCompPhase, }, } })).Should(Succeed()) diff --git a/controllers/apps/operations/switchover_util.go b/controllers/apps/operations/switchover_util.go index 4eee3c32958..c24cef03e69 100644 --- a/controllers/apps/operations/switchover_util.go +++ b/controllers/apps/operations/switchover_util.go @@ -99,7 +99,7 @@ func needDoSwitchover(ctx context.Context, // createSwitchoverJob creates a switchover job to do switchover. func createSwitchoverJob(reqCtx intctrlutil.RequestCtx, cli client.Client, - cluster *appsv1alpha1.Cluster, + cluster *appsv1.Cluster, synthesizedComp *component.SynthesizedComponent, switchover *appsv1alpha1.Switchover) error { switchoverJob, err := renderSwitchoverCmdJob(reqCtx.Ctx, cli, cluster, synthesizedComp, switchover) @@ -174,7 +174,7 @@ func checkPodRoleLabelConsistency(ctx context.Context, // renderSwitchoverCmdJob renders and creates the switchover command jobs. func renderSwitchoverCmdJob(ctx context.Context, cli client.Client, - cluster *appsv1alpha1.Cluster, + cluster *appsv1.Cluster, synthesizedComp *component.SynthesizedComponent, switchover *appsv1alpha1.Switchover) (*batchv1.Job, error) { if synthesizedComp.LifecycleActions == nil || synthesizedComp.LifecycleActions.Switchover == nil || switchover == nil { @@ -260,7 +260,7 @@ func getSwitchoverCmdJobLabel(clusterName, componentName string) map[string]stri // buildSwitchoverCandidateEnv builds the candidate instance name environment variable for the switchover job. func buildSwitchoverCandidateEnv( - cluster *appsv1alpha1.Cluster, + cluster *appsv1.Cluster, componentName string, switchover *appsv1alpha1.Switchover) []corev1.EnvVar { svcName := strings.Join([]string{cluster.Name, componentName, "headless"}, "-") @@ -285,7 +285,7 @@ func buildSwitchoverCandidateEnv( // buildSwitchoverEnvs builds the environment variables for the switchover job. func buildSwitchoverEnvs(ctx context.Context, cli client.Client, - cluster *appsv1alpha1.Cluster, + cluster *appsv1.Cluster, synthesizeComp *component.SynthesizedComponent, switchover *appsv1alpha1.Switchover) ([]corev1.EnvVar, error) { if synthesizeComp == nil || synthesizeComp.LifecycleActions == nil || diff --git a/controllers/apps/operations/type.go b/controllers/apps/operations/type.go index edc1157f5f7..5692958e214 100644 --- a/controllers/apps/operations/type.go +++ b/controllers/apps/operations/type.go @@ -20,13 +20,13 @@ along with this program. If not, see . package operations import ( - appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" "time" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/tools/record" "sigs.k8s.io/controller-runtime/pkg/client" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" intctrlutil "github.com/apecloud/kubeblocks/pkg/controllerutil" ) @@ -50,11 +50,11 @@ type OpsHandler interface { } type OpsBehaviour struct { - FromClusterPhases []appsv1alpha1.ClusterPhase + FromClusterPhases []appsv1.ClusterPhase // ToClusterPhase indicates that the cluster will enter this phase during the operation. // All opsRequest with ToClusterPhase are mutually exclusive. - ToClusterPhase appsv1alpha1.ClusterPhase + ToClusterPhase appsv1.ClusterPhase // CancelFunc this function defines the cancel action and does not patch/update the opsRequest by client-go in here. // only update the opsRequest object, then opsRequest controller will update uniformly. @@ -87,9 +87,9 @@ type reconfigureParams struct { type OpsResource struct { OpsDef *appsv1alpha1.OpsDefinition OpsRequest *appsv1alpha1.OpsRequest - Cluster *appsv1alpha1.Cluster + Cluster *appsv1.Cluster Recorder record.EventRecorder - ToClusterPhase appsv1alpha1.ClusterPhase + ToClusterPhase appsv1.ClusterPhase } type OpsManager struct { @@ -105,7 +105,7 @@ type progressResource struct { fullComponentName string // checks if the component is a sharding component isShardingComponent bool - clusterComponent *appsv1alpha1.ClusterComponentSpec + clusterComponent *appsv1.ClusterComponentSpec clusterDef *appsv1.ClusterDefinition componentDef *appsv1.ComponentDefinition // record which pods need to updated during this operation. diff --git a/controllers/apps/operations/upgrade.go b/controllers/apps/operations/upgrade.go index 98c0b97fb85..7f0ecb21b0b 100644 --- a/controllers/apps/operations/upgrade.go +++ b/controllers/apps/operations/upgrade.go @@ -40,8 +40,8 @@ var _ OpsHandler = upgradeOpsHandler{} func init() { upgradeBehaviour := OpsBehaviour{ // if cluster is Abnormal or Failed, new opsRequest may can repair it. - FromClusterPhases: appsv1alpha1.GetClusterUpRunningPhases(), - ToClusterPhase: appsv1alpha1.UpdatingClusterPhase, + FromClusterPhases: appsv1.GetClusterUpRunningPhases(), + ToClusterPhase: appsv1.UpdatingClusterPhase, QueueByCluster: true, OpsHandler: upgradeOpsHandler{}, } @@ -62,7 +62,7 @@ func (u upgradeOpsHandler) Action(reqCtx intctrlutil.RequestCtx, cli client.Clie return fmt.Errorf("not implemented") } else { compOpsHelper = newComponentOpsHelper(upgradeSpec.Components) - if err := compOpsHelper.updateClusterComponentsAndShardings(opsRes.Cluster, func(compSpec *appsv1alpha1.ClusterComponentSpec, obj ComponentOpsInterface) error { + if err := compOpsHelper.updateClusterComponentsAndShardings(opsRes.Cluster, func(compSpec *appsv1.ClusterComponentSpec, obj ComponentOpsInterface) error { upgradeComp := obj.(appsv1alpha1.UpgradeComponent) if u.needUpdateCompDef(upgradeComp, opsRes.Cluster) { compSpec.ComponentDef = *upgradeComp.ComponentDefinitionName @@ -111,7 +111,7 @@ func (u upgradeOpsHandler) ReconcileAction(reqCtx intctrlutil.RequestCtx, cli cl return opsRes.OpsRequest.Status.Phase, 0, err } } - componentUpgraded := func(cluster *appsv1alpha1.Cluster, + componentUpgraded := func(cluster *appsv1.Cluster, lastCompConfiguration appsv1alpha1.LastComponentConfiguration, upgradeComp appsv1alpha1.UpgradeComponent) bool { if u.needUpdateCompDef(upgradeComp, opsRes.Cluster) && @@ -156,7 +156,7 @@ func (u upgradeOpsHandler) ReconcileAction(reqCtx intctrlutil.RequestCtx, cli cl // SaveLastConfiguration records last configuration to the OpsRequest.status.lastConfiguration func (u upgradeOpsHandler) SaveLastConfiguration(reqCtx intctrlutil.RequestCtx, cli client.Client, opsRes *OpsResource) error { compOpsHelper := newComponentOpsHelper(opsRes.OpsRequest.Spec.Upgrade.Components) - compOpsHelper.saveLastConfigurations(opsRes, func(compSpec appsv1alpha1.ClusterComponentSpec, comOps ComponentOpsInterface) appsv1alpha1.LastComponentConfiguration { + compOpsHelper.saveLastConfigurations(opsRes, func(compSpec appsv1.ClusterComponentSpec, comOps ComponentOpsInterface) appsv1alpha1.LastComponentConfiguration { return appsv1alpha1.LastComponentConfiguration{ ComponentDefinitionName: compSpec.ComponentDef, ServiceVersion: compSpec.ServiceVersion, @@ -213,7 +213,7 @@ func (u upgradeOpsHandler) existClusterVersion(ops *appsv1alpha1.OpsRequest) boo return ops.Spec.Upgrade.ClusterVersionRef != nil && *ops.Spec.Upgrade.ClusterVersionRef != "" } -func (u upgradeOpsHandler) needUpdateCompDef(upgradeComp appsv1alpha1.UpgradeComponent, cluster *appsv1alpha1.Cluster) bool { +func (u upgradeOpsHandler) needUpdateCompDef(upgradeComp appsv1alpha1.UpgradeComponent, cluster *appsv1.Cluster) bool { if upgradeComp.ComponentDefinitionName == nil { return false } diff --git a/controllers/apps/operations/upgrade_test.go b/controllers/apps/operations/upgrade_test.go index bd5c576d7e9..27b17baf958 100644 --- a/controllers/apps/operations/upgrade_test.go +++ b/controllers/apps/operations/upgrade_test.go @@ -77,15 +77,15 @@ var _ = Describe("Upgrade OpsRequest", func() { // do upgrade _, err = GetOpsManager().Do(reqCtx, k8sClient, opsRes) Expect(err).ShouldNot(HaveOccurred()) - mockComponentIsOperating(opsRes.Cluster, appsv1alpha1.UpdatingClusterCompPhase, defaultCompName) + mockComponentIsOperating(opsRes.Cluster, appsv1.UpdatingClusterCompPhase, defaultCompName) } - mockClusterRunning := func(clusterObject *appsv1alpha1.Cluster) { + mockClusterRunning := func(clusterObject *appsv1.Cluster) { Expect(testapps.ChangeObjStatus(&testCtx, clusterObject, func() { - clusterObject.Status.Phase = appsv1alpha1.RunningClusterPhase - clusterObject.Status.Components = map[string]appsv1alpha1.ClusterComponentStatus{ + clusterObject.Status.Phase = appsv1.RunningClusterPhase + clusterObject.Status.Components = map[string]appsv1.ClusterComponentStatus{ defaultCompName: { - Phase: appsv1alpha1.RunningClusterCompPhase, + Phase: appsv1.RunningClusterCompPhase, }, } })).Should(Succeed()) @@ -191,7 +191,7 @@ var _ = Describe("Upgrade OpsRequest", func() { return compDef1, compDef2, opsRes } - createUpgradeOpsRequest := func(clusterObject *appsv1alpha1.Cluster, upgradeSpec appsv1alpha1.Upgrade) *appsv1alpha1.OpsRequest { + createUpgradeOpsRequest := func(clusterObject *appsv1.Cluster, upgradeSpec appsv1alpha1.Upgrade) *appsv1alpha1.OpsRequest { ops := testapps.NewOpsRequestObj("upgrade-ops-"+randomStr, testCtx.DefaultNamespace, clusterObject.Name, appsv1alpha1.UpgradeType) ops.Spec.Upgrade = &upgradeSpec @@ -203,13 +203,13 @@ var _ = Describe("Upgrade OpsRequest", func() { expectOpsSucceed := func(reqCtx intctrlutil.RequestCtx, opsRes *OpsResource, compNames ...string) { // mock component to running - mockComponentIsOperating(opsRes.Cluster, appsv1alpha1.RunningClusterCompPhase, compNames...) + mockComponentIsOperating(opsRes.Cluster, appsv1.RunningClusterCompPhase, compNames...) _, err := GetOpsManager().Reconcile(reqCtx, k8sClient, opsRes) Expect(err).ShouldNot(HaveOccurred()) Eventually(testapps.GetOpsRequestPhase(&testCtx, client.ObjectKeyFromObject(opsRes.OpsRequest))).Should(Equal(appsv1alpha1.OpsSucceedPhase)) } - mockPodsAppliedImage := func(cluster *appsv1alpha1.Cluster, releaseVersion string) { + mockPodsAppliedImage := func(cluster *appsv1.Cluster, releaseVersion string) { pods := testapps.MockInstanceSetPods(&testCtx, nil, cluster, defaultCompName) image := testapps.AppImage(testapps.AppName, releaseVersion) for i := range pods { @@ -274,7 +274,7 @@ var _ = Describe("Upgrade OpsRequest", func() { By("expect for this opsRequest is Running") reqCtx := intctrlutil.RequestCtx{Ctx: ctx} makeUpgradeOpsIsRunning(reqCtx, opsRes) - Eventually(testapps.CheckObj(&testCtx, client.ObjectKeyFromObject(opsRes.Cluster), func(g Gomega, cluster *appsv1alpha1.Cluster) { + Eventually(testapps.CheckObj(&testCtx, client.ObjectKeyFromObject(opsRes.Cluster), func(g Gomega, cluster *appsv1.Cluster) { g.Expect(cluster.Spec.ComponentSpecs[0].ComponentDef).Should(Equal(compDef2.Name)) g.Expect(cluster.Spec.ComponentSpecs[0].ServiceVersion).Should(Equal(serviceVer2)) })).Should(Succeed()) @@ -302,7 +302,7 @@ var _ = Describe("Upgrade OpsRequest", func() { By("expect for this opsRequest is Running and reuse the original ComponentDefinition") reqCtx := intctrlutil.RequestCtx{Ctx: ctx} makeUpgradeOpsIsRunning(reqCtx, opsRes) - Eventually(testapps.CheckObj(&testCtx, client.ObjectKeyFromObject(opsRes.Cluster), func(g Gomega, cluster *appsv1alpha1.Cluster) { + Eventually(testapps.CheckObj(&testCtx, client.ObjectKeyFromObject(opsRes.Cluster), func(g Gomega, cluster *appsv1.Cluster) { g.Expect(cluster.Spec.ComponentSpecs[0].ComponentDef).Should(Equal(compDef1.Name)) g.Expect(cluster.Spec.ComponentSpecs[0].ServiceVersion).Should(Equal(serviceVer1)) })).Should(Succeed()) @@ -330,7 +330,7 @@ var _ = Describe("Upgrade OpsRequest", func() { By(" expect for this opsRequest is Running") reqCtx := intctrlutil.RequestCtx{Ctx: ctx} makeUpgradeOpsIsRunning(reqCtx, opsRes) - Eventually(testapps.CheckObj(&testCtx, client.ObjectKeyFromObject(opsRes.Cluster), func(g Gomega, cluster *appsv1alpha1.Cluster) { + Eventually(testapps.CheckObj(&testCtx, client.ObjectKeyFromObject(opsRes.Cluster), func(g Gomega, cluster *appsv1.Cluster) { g.Expect(cluster.Spec.ComponentSpecs[0].ComponentDef).Should(Equal(compDef1.Name)) g.Expect(cluster.Spec.ComponentSpecs[0].ServiceVersion).Should(BeEmpty()) })).Should(Succeed()) @@ -357,7 +357,7 @@ var _ = Describe("Upgrade OpsRequest", func() { By("expecting no changes to serviceVersion") reqCtx := intctrlutil.RequestCtx{Ctx: ctx} makeUpgradeOpsIsRunning(reqCtx, opsRes) - Eventually(testapps.CheckObj(&testCtx, client.ObjectKeyFromObject(opsRes.Cluster), func(g Gomega, cluster *appsv1alpha1.Cluster) { + Eventually(testapps.CheckObj(&testCtx, client.ObjectKeyFromObject(opsRes.Cluster), func(g Gomega, cluster *appsv1.Cluster) { g.Expect(cluster.Spec.ComponentSpecs[0].ComponentDef).Should(Equal(compDef2.Name)) g.Expect(cluster.Spec.ComponentSpecs[0].ServiceVersion).Should(Equal(serviceVer0)) })).Should(Succeed()) @@ -380,7 +380,7 @@ var _ = Describe("Upgrade OpsRequest", func() { By("expecting no changes to cluster.spec.componentSpec[0].componentDef") reqCtx := intctrlutil.RequestCtx{Ctx: ctx} makeUpgradeOpsIsRunning(reqCtx, opsRes) - Eventually(testapps.CheckObj(&testCtx, client.ObjectKeyFromObject(opsRes.Cluster), func(g Gomega, cluster *appsv1alpha1.Cluster) { + Eventually(testapps.CheckObj(&testCtx, client.ObjectKeyFromObject(opsRes.Cluster), func(g Gomega, cluster *appsv1.Cluster) { g.Expect(cluster.Spec.ComponentSpecs[0].ComponentDef).Should(Equal(compDef1.Name)) g.Expect(cluster.Spec.ComponentSpecs[0].ServiceVersion).Should(Equal("")) })).Should(Succeed()) diff --git a/controllers/apps/operations/util/common_util.go b/controllers/apps/operations/util/common_util.go index 6556e1d34e3..3de73f114b3 100644 --- a/controllers/apps/operations/util/common_util.go +++ b/controllers/apps/operations/util/common_util.go @@ -26,12 +26,13 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" dpv1alpha1 "github.com/apecloud/kubeblocks/apis/dataprotection/v1alpha1" intctrlutil "github.com/apecloud/kubeblocks/pkg/constant" ) -func SetOpsRequestToCluster(cluster *appsv1alpha1.Cluster, opsRequestSlice []appsv1alpha1.OpsRecorder) { +func SetOpsRequestToCluster(cluster *appsv1.Cluster, opsRequestSlice []appsv1alpha1.OpsRecorder) { if cluster.Annotations == nil { cluster.Annotations = map[string]string{} } @@ -46,7 +47,7 @@ func SetOpsRequestToCluster(cluster *appsv1alpha1.Cluster, opsRequestSlice []app // UpdateClusterOpsAnnotations updates OpsRequest annotation in Cluster.annotations func UpdateClusterOpsAnnotations(ctx context.Context, cli client.Client, - cluster *appsv1alpha1.Cluster, + cluster *appsv1.Cluster, opsRequestSlice []appsv1alpha1.OpsRecorder) error { SetOpsRequestToCluster(cluster, opsRequestSlice) return cli.Update(ctx, cluster) @@ -70,7 +71,7 @@ func PatchOpsRequestReconcileAnnotation(ctx context.Context, cli client.Client, // GetOpsRequestSliceFromCluster gets OpsRequest slice from cluster annotations. // this records what OpsRequests are running in cluster -func GetOpsRequestSliceFromCluster(cluster *appsv1alpha1.Cluster) ([]appsv1alpha1.OpsRecorder, error) { +func GetOpsRequestSliceFromCluster(cluster *appsv1.Cluster) ([]appsv1alpha1.OpsRecorder, error) { var ( opsRequestValue string opsRequestSlice []appsv1alpha1.OpsRecorder diff --git a/controllers/apps/operations/util/common_util_test.go b/controllers/apps/operations/util/common_util_test.go index 08c3668fbe3..86de8d2c89b 100644 --- a/controllers/apps/operations/util/common_util_test.go +++ b/controllers/apps/operations/util/common_util_test.go @@ -25,6 +25,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" dpv1alpha1 "github.com/apecloud/kubeblocks/apis/dataprotection/v1alpha1" intctrlutil "github.com/apecloud/kubeblocks/pkg/constant" @@ -41,7 +42,7 @@ var _ = Describe("OpsRequest Controller", func() { ) cleanupObjects := func() { - err := k8sClient.DeleteAllOf(ctx, &appsv1alpha1.Cluster{}, client.InNamespace(testCtx.DefaultNamespace), client.HasLabels{testCtx.TestObjLabelKey}) + err := k8sClient.DeleteAllOf(ctx, &appsv1.Cluster{}, client.InNamespace(testCtx.DefaultNamespace), client.HasLabels{testCtx.TestObjLabelKey}) Expect(err).NotTo(HaveOccurred()) err = k8sClient.DeleteAllOf(ctx, &appsv1alpha1.OpsRequest{}, client.InNamespace(testCtx.DefaultNamespace), client.HasLabels{testCtx.TestObjLabelKey}) Expect(err).NotTo(HaveOccurred()) diff --git a/controllers/apps/operations/vertical_scaling.go b/controllers/apps/operations/vertical_scaling.go index 124a237da53..9d5877d60ed 100644 --- a/controllers/apps/operations/vertical_scaling.go +++ b/controllers/apps/operations/vertical_scaling.go @@ -26,6 +26,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/client" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" "github.com/apecloud/kubeblocks/pkg/constant" "github.com/apecloud/kubeblocks/pkg/controller/instanceset" @@ -40,8 +41,8 @@ func init() { vsHandler := verticalScalingHandler{} verticalScalingBehaviour := OpsBehaviour{ // if cluster is Abnormal or Failed, new opsRequest may can repair it. - FromClusterPhases: appsv1alpha1.GetClusterUpRunningPhases(), - ToClusterPhase: appsv1alpha1.UpdatingClusterPhase, + FromClusterPhases: appsv1.GetClusterUpRunningPhases(), + ToClusterPhase: appsv1.UpdatingClusterPhase, OpsHandler: vsHandler, QueueByCluster: true, CancelFunc: vsHandler.Cancel, @@ -59,7 +60,7 @@ func (vs verticalScalingHandler) ActionStartedCondition(reqCtx intctrlutil.Reque // Action modifies cluster component resources according to // the definition of opsRequest with spec.componentNames and spec.componentOps.verticalScaling func (vs verticalScalingHandler) Action(reqCtx intctrlutil.RequestCtx, cli client.Client, opsRes *OpsResource) error { - applyVerticalScaling := func(compSpec *appsv1alpha1.ClusterComponentSpec, obj ComponentOpsInterface) error { + applyVerticalScaling := func(compSpec *appsv1.ClusterComponentSpec, obj ComponentOpsInterface) error { verticalScaling := obj.(appsv1alpha1.VerticalScaling) if vs.verticalScalingComp(verticalScaling) { compSpec.Resources = verticalScaling.ResourceRequirements @@ -197,15 +198,15 @@ func (vs verticalScalingHandler) podApplyCompOps( // SaveLastConfiguration records last configuration to the OpsRequest.status.lastConfiguration func (vs verticalScalingHandler) SaveLastConfiguration(reqCtx intctrlutil.RequestCtx, cli client.Client, opsRes *OpsResource) error { compOpsHelper := newComponentOpsHelper(opsRes.OpsRequest.Spec.VerticalScalingList) - compOpsHelper.saveLastConfigurations(opsRes, func(compSpec appsv1alpha1.ClusterComponentSpec, comOps ComponentOpsInterface) appsv1alpha1.LastComponentConfiguration { + compOpsHelper.saveLastConfigurations(opsRes, func(compSpec appsv1.ClusterComponentSpec, comOps ComponentOpsInterface) appsv1alpha1.LastComponentConfiguration { verticalScaling := comOps.(appsv1alpha1.VerticalScaling) - var instanceTemplates []appsv1alpha1.InstanceTemplate + var instanceTemplates []appsv1.InstanceTemplate for _, vIns := range verticalScaling.Instances { for _, compIns := range compSpec.Instances { if vIns.Name != compIns.Name { continue } - instanceTemplates = append(instanceTemplates, appsv1alpha1.InstanceTemplate{ + instanceTemplates = append(instanceTemplates, appsv1.InstanceTemplate{ Name: compIns.Name, Resources: compIns.Resources, }) @@ -223,7 +224,7 @@ func (vs verticalScalingHandler) SaveLastConfiguration(reqCtx intctrlutil.Reques // Cancel this function defines the cancel verticalScaling action. func (vs verticalScalingHandler) Cancel(reqCxt intctrlutil.RequestCtx, cli client.Client, opsRes *OpsResource) error { compOpsHelper := newComponentOpsHelper(opsRes.OpsRequest.Spec.VerticalScalingList) - return compOpsHelper.cancelComponentOps(reqCxt.Ctx, cli, opsRes, func(lastConfig *appsv1alpha1.LastComponentConfiguration, comp *appsv1alpha1.ClusterComponentSpec) { + return compOpsHelper.cancelComponentOps(reqCxt.Ctx, cli, opsRes, func(lastConfig *appsv1alpha1.LastComponentConfiguration, comp *appsv1.ClusterComponentSpec) { comp.Resources = lastConfig.ResourceRequirements for _, lastIns := range lastConfig.Instances { for i := range comp.Instances { diff --git a/controllers/apps/operations/vertical_scaling_test.go b/controllers/apps/operations/vertical_scaling_test.go index e75e5cc8ae6..87f64f13686 100644 --- a/controllers/apps/operations/vertical_scaling_test.go +++ b/controllers/apps/operations/vertical_scaling_test.go @@ -24,12 +24,13 @@ import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/client" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" opsutil "github.com/apecloud/kubeblocks/controllers/apps/operations/util" "github.com/apecloud/kubeblocks/pkg/constant" @@ -139,7 +140,7 @@ var _ = Describe("VerticalScaling OpsRequest", func() { opsRes.OpsRequest = testapps.CreateOpsRequest(ctx, testCtx, ops) By("mock opsRequest is Running") - mockComponentIsOperating(opsRes.Cluster, appsv1alpha1.UpdatingClusterCompPhase, defaultCompName) + mockComponentIsOperating(opsRes.Cluster, appsv1.UpdatingClusterCompPhase, defaultCompName) Expect(testapps.ChangeObjStatus(&testCtx, opsRes.OpsRequest, func() { opsRes.OpsRequest.Status.Phase = appsv1alpha1.OpsRunningPhase opsRes.OpsRequest.Status.StartTimestamp = metav1.Time{Time: time.Now()} diff --git a/controllers/apps/operations/volume_expansion.go b/controllers/apps/operations/volume_expansion.go index f33ae8fb067..0cc0cb5cfc2 100644 --- a/controllers/apps/operations/volume_expansion.go +++ b/controllers/apps/operations/volume_expansion.go @@ -1,4 +1,5 @@ /* +/* Copyright (C) 2022-2024 ApeCloud Co., Ltd This file is part of KubeBlocks project @@ -32,6 +33,7 @@ import ( "k8s.io/apimachinery/pkg/util/sets" "sigs.k8s.io/controller-runtime/pkg/client" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" "github.com/apecloud/kubeblocks/pkg/constant" "github.com/apecloud/kubeblocks/pkg/controller/instanceset" @@ -74,9 +76,9 @@ func (ve volumeExpansionOpsHandler) ActionStartedCondition(reqCtx intctrlutil.Re // Action modifies Cluster.spec.components[*].VolumeClaimTemplates[*].spec.resources func (ve volumeExpansionOpsHandler) Action(reqCtx intctrlutil.RequestCtx, cli client.Client, opsRes *OpsResource) error { - applyVolumeExpansion := func(compSpec *appsv1alpha1.ClusterComponentSpec, obj ComponentOpsInterface) error { + applyVolumeExpansion := func(compSpec *appsv1.ClusterComponentSpec, obj ComponentOpsInterface) error { setVolumeStorage := func(volumeExpansionVCTs []appsv1alpha1.OpsRequestVolumeClaimTemplate, - targetVCTs []appsv1alpha1.ClusterComponentVolumeClaimTemplate) { + targetVCTs []appsv1.ClusterComponentVolumeClaimTemplate) { for _, v := range volumeExpansionVCTs { for i, vct := range targetVCTs { if vct.Name != v.Name { @@ -119,7 +121,7 @@ func (ve volumeExpansionOpsHandler) ReconcileAction(reqCtx intctrlutil.RequestCt succeedProgressCount int completedProgressCount int ) - getTemplateReplicas := func(templates []appsv1alpha1.InstanceTemplate) int32 { + getTemplateReplicas := func(templates []appsv1.InstanceTemplate) int32 { var replicaCount int32 for _, v := range templates { replicaCount += v.GetReplicas() @@ -133,7 +135,7 @@ func (ve volumeExpansionOpsHandler) ReconcileAction(reqCtx intctrlutil.RequestCt compOpsHelper := newComponentOpsHelper(opsRes.OpsRequest.Spec.VolumeExpansionList) storageMap := ve.getRequestStorageMap(opsRequest) var veHelpers []volumeExpansionHelper - setVeHelpers := func(compSpec appsv1alpha1.ClusterComponentSpec, compOps ComponentOpsInterface, fullComponentName string) { + setVeHelpers := func(compSpec appsv1.ClusterComponentSpec, compOps ComponentOpsInterface, fullComponentName string) { volumeExpansion := compOps.(appsv1alpha1.VolumeExpansion) if len(volumeExpansion.VolumeClaimTemplates) > 0 { expectReplicas := compSpec.Replicas - getTemplateReplicas(compSpec.Instances) @@ -234,9 +236,9 @@ func (ve volumeExpansionOpsHandler) SaveLastConfiguration(reqCtx intctrlutil.Req opsRequest := opsRes.OpsRequest compOpsHelper := newComponentOpsHelper(opsRequest.Spec.VolumeExpansionList) storageMap := ve.getRequestStorageMap(opsRequest) - compOpsHelper.saveLastConfigurations(opsRes, func(compSpec appsv1alpha1.ClusterComponentSpec, comOps ComponentOpsInterface) appsv1alpha1.LastComponentConfiguration { - getLastVCTs := func(vcts []appsv1alpha1.ClusterComponentVolumeClaimTemplate, templateName string) []appsv1alpha1.ClusterComponentVolumeClaimTemplate { - lastVCTs := make([]appsv1alpha1.ClusterComponentVolumeClaimTemplate, 0) + compOpsHelper.saveLastConfigurations(opsRes, func(compSpec appsv1.ClusterComponentSpec, comOps ComponentOpsInterface) appsv1alpha1.LastComponentConfiguration { + getLastVCTs := func(vcts []appsv1.ClusterComponentVolumeClaimTemplate, templateName string) []appsv1.ClusterComponentVolumeClaimTemplate { + lastVCTs := make([]appsv1.ClusterComponentVolumeClaimTemplate, 0) for _, vct := range vcts { key := getComponentVCTKey(comOps.GetComponentName(), comOps.GetComponentName(), templateName) if _, ok := storageMap[key]; !ok { @@ -248,13 +250,13 @@ func (ve volumeExpansionOpsHandler) SaveLastConfiguration(reqCtx intctrlutil.Req } volumeExpansion := comOps.(appsv1alpha1.VolumeExpansion) // save the last vcts of the instances - var instanceTemplates []appsv1alpha1.InstanceTemplate + var instanceTemplates []appsv1.InstanceTemplate for _, v := range volumeExpansion.Instances { for _, ins := range compSpec.Instances { if ins.Name != v.Name { continue } - instanceTemplates = append(instanceTemplates, appsv1alpha1.InstanceTemplate{ + instanceTemplates = append(instanceTemplates, appsv1.InstanceTemplate{ VolumeClaimTemplates: getLastVCTs(ins.VolumeClaimTemplates, ins.Name), }) } diff --git a/controllers/apps/operations/volume_expansion_test.go b/controllers/apps/operations/volume_expansion_test.go index f10cad99bb3..61503e1e11a 100644 --- a/controllers/apps/operations/volume_expansion_test.go +++ b/controllers/apps/operations/volume_expansion_test.go @@ -24,6 +24,7 @@ import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" + corev1 "k8s.io/api/core/v1" storagev1 "k8s.io/api/storage/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" @@ -32,6 +33,7 @@ import ( "k8s.io/kubectl/pkg/util/storage" "sigs.k8s.io/controller-runtime/pkg/client" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" "github.com/apecloud/kubeblocks/pkg/constant" intctrlutil "github.com/apecloud/kubeblocks/pkg/controllerutil" @@ -84,7 +86,7 @@ var _ = Describe("OpsRequest Controller Volume Expansion Handler", func() { constant.KBAppComponentLabelKey, consensusCompName).SetStorage("2Gi").SetStorageClass(storageClassName).CheckedCreate(&testCtx) } - initResourcesForVolumeExpansion := func(clusterObject *appsv1alpha1.Cluster, opsRes *OpsResource, storage string, replicas int) (*appsv1alpha1.OpsRequest, []string) { + initResourcesForVolumeExpansion := func(clusterObject *appsv1.Cluster, opsRes *OpsResource, storage string, replicas int) (*appsv1alpha1.OpsRequest, []string) { pvcNames := opsRes.Cluster.GetVolumeClaimNames(consensusCompName) for _, pvcName := range pvcNames { createPVC(clusterObject.Name, storageClassName, vctName, pvcName) @@ -144,13 +146,13 @@ var _ = Describe("OpsRequest Controller Volume Expansion Handler", func() { } testVolumeExpansion := func(reqCtx intctrlutil.RequestCtx, - clusterObject *appsv1alpha1.Cluster, + clusterObject *appsv1.Cluster, opsRes *OpsResource, requestStorage, actualStorage string) { // mock cluster is Running to support volume expansion ops Expect(testapps.ChangeObjStatus(&testCtx, clusterObject, func() { - clusterObject.Status.Phase = appsv1alpha1.RunningClusterPhase + clusterObject.Status.Phase = appsv1.RunningClusterPhase })).ShouldNot(HaveOccurred()) // init resources for volume expansion @@ -199,7 +201,7 @@ var _ = Describe("OpsRequest Controller Volume Expansion Handler", func() { Expect(opsRes.OpsRequest.Status.Phase).Should(Equal(appsv1alpha1.OpsSucceedPhase)) } - testDeleteRunningVolumeExpansion := func(clusterObject *appsv1alpha1.Cluster, opsRes *OpsResource) { + testDeleteRunningVolumeExpansion := func(clusterObject *appsv1.Cluster, opsRes *OpsResource) { // init resources for volume expansion newOps, pvcNames := initResourcesForVolumeExpansion(clusterObject, opsRes, "5Gi", 1) Expect(k8sClient.Delete(ctx, newOps)).Should(Succeed()) @@ -231,10 +233,10 @@ var _ = Describe("OpsRequest Controller Volume Expansion Handler", func() { By("Test OpsManager.MainEnter function with ClusterOps") Expect(testapps.ChangeObjStatus(&testCtx, clusterObject, func() { - clusterObject.Status.Phase = appsv1alpha1.RunningClusterPhase - clusterObject.Status.Components = map[string]appsv1alpha1.ClusterComponentStatus{ + clusterObject.Status.Phase = appsv1.RunningClusterPhase + clusterObject.Status.Components = map[string]appsv1.ClusterComponentStatus{ consensusCompName: { - Phase: appsv1alpha1.RunningClusterCompPhase, + Phase: appsv1.RunningClusterCompPhase, }, } })).ShouldNot(HaveOccurred()) diff --git a/controllers/apps/opsrequest_controller.go b/controllers/apps/opsrequest_controller.go index 1f95a8d6adc..b7c35d10b1a 100644 --- a/controllers/apps/opsrequest_controller.go +++ b/controllers/apps/opsrequest_controller.go @@ -42,6 +42,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/log" "sigs.k8s.io/controller-runtime/pkg/reconcile" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" dpv1alpha1 "github.com/apecloud/kubeblocks/apis/dataprotection/v1alpha1" workloadsv1alpha1 "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" @@ -93,7 +94,7 @@ func (r *OpsRequestReconciler) SetupWithManager(mgr ctrl.Manager) error { WithOptions(controller.Options{ MaxConcurrentReconciles: int(math.Ceil(viper.GetFloat64(constant.CfgKBReconcileWorkers) / 2)), }). - Watches(&appsv1alpha1.Cluster{}, handler.EnqueueRequestsFromMapFunc(r.parseRunningOpsRequests)). + Watches(&appsv1.Cluster{}, handler.EnqueueRequestsFromMapFunc(r.parseRunningOpsRequests)). Watches(&workloadsv1alpha1.InstanceSet{}, handler.EnqueueRequestsFromMapFunc(r.parseRunningOpsRequestsForInstanceSet)). Watches(&dpv1alpha1.Backup{}, handler.EnqueueRequestsFromMapFunc(r.parseBackupOpsRequest)). Watches(&corev1.PersistentVolumeClaim{}, handler.EnqueueRequestsFromMapFunc(r.parseVolumeExpansionOpsRequest)). @@ -135,7 +136,7 @@ func (r *OpsRequestReconciler) handleDeletion(reqCtx intctrlutil.RequestCtx, ops // fetchCluster fetches the Cluster from the OpsRequest. func (r *OpsRequestReconciler) fetchCluster(reqCtx intctrlutil.RequestCtx, opsRes *operations.OpsResource) (*ctrl.Result, error) { - cluster := &appsv1alpha1.Cluster{} + cluster := &appsv1.Cluster{} opsBehaviour, ok := operations.GetOpsManager().OpsMap[opsRes.OpsRequest.Spec.Type] if !ok || opsBehaviour.OpsHandler == nil { return nil, operations.PatchOpsHandlerNotSupported(reqCtx.Ctx, r.Client, opsRes) @@ -300,7 +301,7 @@ func (r *OpsRequestReconciler) addClusterLabelAndSetOwnerReference(reqCtx intctr } opsRequest.Labels[constant.AppInstanceLabelKey] = opsRequest.Spec.GetClusterName() opsRequest.Labels[constant.OpsRequestTypeLabelKey] = string(opsRequest.Spec.Type) - scheme, _ := appsv1alpha1.SchemeBuilder.Build() + scheme, _ := appsv1.SchemeBuilder.Build() if err := controllerutil.SetOwnerReference(opsRes.Cluster, opsRequest, scheme); err != nil { return intctrlutil.ResultToP(intctrlutil.CheckedRequeueWithError(err, reqCtx.Log, "")) } @@ -346,7 +347,7 @@ func (r *OpsRequestReconciler) doOpsRequestAction(reqCtx intctrlutil.RequestCtx, // handleOpsReqDeletedDuringRunning handles the cluster annotation if the OpsRequest is deleted during running. func (r *OpsRequestReconciler) handleOpsReqDeletedDuringRunning(reqCtx intctrlutil.RequestCtx) error { - clusterList := &appsv1alpha1.ClusterList{} + clusterList := &appsv1.ClusterList{} if err := r.Client.List(reqCtx.Ctx, clusterList, client.InNamespace(reqCtx.Req.Namespace)); err != nil { return err } @@ -358,7 +359,7 @@ func (r *OpsRequestReconciler) handleOpsReqDeletedDuringRunning(reqCtx intctrlut return nil } -func (r *OpsRequestReconciler) cleanupOpsAnnotationForCluster(reqCtx intctrlutil.RequestCtx, cluster *appsv1alpha1.Cluster) error { +func (r *OpsRequestReconciler) cleanupOpsAnnotationForCluster(reqCtx intctrlutil.RequestCtx, cluster *appsv1.Cluster) error { opsRequestSlice, _ := opsutil.GetOpsRequestSliceFromCluster(cluster) index, _ := operations.GetOpsRecorderFromSlice(opsRequestSlice, reqCtx.Req.Name) if index == -1 { @@ -369,7 +370,7 @@ func (r *OpsRequestReconciler) cleanupOpsAnnotationForCluster(reqCtx intctrlutil return opsutil.UpdateClusterOpsAnnotations(reqCtx.Ctx, r.Client, cluster, opsRequestSlice) } -func (r *OpsRequestReconciler) getRunningOpsRequestsFromCluster(cluster *appsv1alpha1.Cluster) []reconcile.Request { +func (r *OpsRequestReconciler) getRunningOpsRequestsFromCluster(cluster *appsv1.Cluster) []reconcile.Request { var ( opsRequestSlice []appsv1alpha1.OpsRecorder err error @@ -416,7 +417,7 @@ func (r *OpsRequestReconciler) getRunningOpsRequestsFromCluster(cluster *appsv1a } func (r *OpsRequestReconciler) parseRunningOpsRequests(ctx context.Context, object client.Object) []reconcile.Request { - cluster := object.(*appsv1alpha1.Cluster) + cluster := object.(*appsv1.Cluster) return r.getRunningOpsRequestsFromCluster(cluster) } @@ -426,7 +427,7 @@ func (r *OpsRequestReconciler) parseRunningOpsRequestsForInstanceSet(ctx context if clusterName == "" { return nil } - cluster := &appsv1alpha1.Cluster{} + cluster := &appsv1.Cluster{} if err := r.Client.Get(ctx, client.ObjectKey{Name: clusterName, Namespace: its.Namespace}, cluster); err != nil { return nil } diff --git a/controllers/apps/opsrequest_controller_test.go b/controllers/apps/opsrequest_controller_test.go index c57a7c62adb..2c18c3db23e 100644 --- a/controllers/apps/opsrequest_controller_test.go +++ b/controllers/apps/opsrequest_controller_test.go @@ -102,27 +102,27 @@ var _ = Describe("OpsRequest Controller", func() { var ( compDefObj *appsv1.ComponentDefinition - clusterObj *appsv1alpha1.Cluster + clusterObj *appsv1.Cluster clusterKey types.NamespacedName ) mockSetClusterStatusPhaseToRunning := func(namespacedName types.NamespacedName) { Expect(testapps.GetAndChangeObjStatus(&testCtx, namespacedName, - func(fetched *appsv1alpha1.Cluster) { + func(fetched *appsv1.Cluster) { // TODO: would be better to have hint for cluster.status.phase is mocked, // i.e., add annotation info for the mocked context - fetched.Status.Phase = appsv1alpha1.RunningClusterPhase + fetched.Status.Phase = appsv1.RunningClusterPhase if len(fetched.Status.Components) == 0 { - fetched.Status.Components = map[string]appsv1alpha1.ClusterComponentStatus{} + fetched.Status.Components = map[string]appsv1.ClusterComponentStatus{} for _, v := range fetched.Spec.ComponentSpecs { - fetched.Status.SetComponentStatus(v.Name, appsv1alpha1.ClusterComponentStatus{ - Phase: appsv1alpha1.RunningClusterCompPhase, + fetched.Status.SetComponentStatus(v.Name, appsv1.ClusterComponentStatus{ + Phase: appsv1.RunningClusterCompPhase, }) } return } for componentKey, componentStatus := range fetched.Status.Components { - componentStatus.Phase = appsv1alpha1.RunningClusterCompPhase + componentStatus.Phase = appsv1.RunningClusterCompPhase fetched.Status.SetComponentStatus(componentKey, componentStatus) } })()).ShouldNot(HaveOccurred()) @@ -295,7 +295,7 @@ var _ = Describe("OpsRequest Controller", func() { testk8s.RemovePodFinalizer(ctx, testCtx, &podList.Items[i]) } } - cluster := &appsv1alpha1.Cluster{} + cluster := &appsv1.Cluster{} Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(clusterObj), cluster)).Should(Succeed()) mockPods := testapps.MockInstanceSetPods(&testCtx, its, cluster, mysqlCompName) @@ -351,14 +351,14 @@ var _ = Describe("OpsRequest Controller", func() { } // mock and wait for the cluster running - Eventually(testapps.CheckObj(&testCtx, clusterKey, func(g Gomega, cluster *appsv1alpha1.Cluster) { + Eventually(testapps.CheckObj(&testCtx, clusterKey, func(g Gomega, cluster *appsv1.Cluster) { g.Expect(cluster.Status.ObservedGeneration).Should(Equal(cluster.Generation)) })).Should(Succeed()) mockSetClusterStatusPhaseToRunning(clusterKey) - Eventually(testapps.CheckObj(&testCtx, clusterKey, func(g Gomega, cluster *appsv1alpha1.Cluster) { + Eventually(testapps.CheckObj(&testCtx, clusterKey, func(g Gomega, cluster *appsv1.Cluster) { g.Expect(cluster.Status.ObservedGeneration).Should(Equal(cluster.Generation)) - g.Expect(cluster.Status.Phase).Should(Equal(appsv1alpha1.RunningClusterPhase)) - g.Expect(cluster.Status.Components[mysqlCompName].Phase).Should(Equal(appsv1alpha1.RunningClusterCompPhase)) + g.Expect(cluster.Status.Phase).Should(Equal(appsv1.RunningClusterPhase)) + g.Expect(cluster.Status.Components[mysqlCompName].Phase).Should(Equal(appsv1.RunningClusterCompPhase)) })).Should(Succeed()) } @@ -392,7 +392,7 @@ var _ = Describe("OpsRequest Controller", func() { testk8s.MockDisableVolumeSnapshot(&testCtx, testk8s.DefaultStorageClassName) createMysqlCluster(3) - cluster := &appsv1alpha1.Cluster{} + cluster := &appsv1.Cluster{} Expect(testCtx.Cli.Get(testCtx.Ctx, clusterKey, cluster)).Should(Succeed()) initGeneration := cluster.Status.ObservedGeneration Eventually(testapps.GetClusterObservedGeneration(&testCtx, clusterKey)).Should(Equal(initGeneration)) @@ -402,16 +402,16 @@ var _ = Describe("OpsRequest Controller", func() { By("expect component is Running if don't support volume snapshot during doing h-scale ops") Eventually(testapps.GetOpsRequestPhase(&testCtx, opsKey)).Should(Equal(appsv1alpha1.OpsRunningPhase)) - Eventually(testapps.CheckObj(&testCtx, clusterKey, func(g Gomega, fetched *appsv1alpha1.Cluster) { + Eventually(testapps.CheckObj(&testCtx, clusterKey, func(g Gomega, fetched *appsv1.Cluster) { // the cluster spec has been updated by ops-controller to scale out. g.Expect(fetched.Generation == initGeneration+1).Should(BeTrue()) // expect cluster phase is Updating during Hscale. g.Expect(fetched.Generation > fetched.Status.ObservedGeneration).Should(BeTrue()) - g.Expect(fetched.Status.Phase).Should(Equal(appsv1alpha1.UpdatingClusterPhase)) + g.Expect(fetched.Status.Phase).Should(Equal(appsv1.UpdatingClusterPhase)) // when snapshot is not supported, the expected component phase is running. - g.Expect(fetched.Status.Components[mysqlCompName].Phase).Should(Equal(appsv1alpha1.RunningClusterCompPhase)) + g.Expect(fetched.Status.Components[mysqlCompName].Phase).Should(Equal(appsv1.RunningClusterCompPhase)) // expect preCheckFailed condition to occur. - condition := meta.FindStatusCondition(fetched.Status.Conditions, appsv1alpha1.ConditionTypeProvisioningStarted) + condition := meta.FindStatusCondition(fetched.Status.Conditions, appsv1.ConditionTypeProvisioningStarted) g.Expect(condition).ShouldNot(BeNil()) g.Expect(condition.Status).Should(BeFalse()) g.Expect(condition.Reason).Should(Equal(ReasonPreCheckFailed)) @@ -419,13 +419,13 @@ var _ = Describe("OpsRequest Controller", func() { })) By("reset replicas to 3 and cluster phase should be reconciled to Running") - Expect(testapps.GetAndChangeObj(&testCtx, clusterKey, func(cluster *appsv1alpha1.Cluster) { + Expect(testapps.GetAndChangeObj(&testCtx, clusterKey, func(cluster *appsv1.Cluster) { cluster.Spec.ComponentSpecs[0].Replicas = int32(3) })()).ShouldNot(HaveOccurred()) - Eventually(testapps.CheckObj(&testCtx, clusterKey, func(g Gomega, lcluster *appsv1alpha1.Cluster) { + Eventually(testapps.CheckObj(&testCtx, clusterKey, func(g Gomega, lcluster *appsv1.Cluster) { g.Expect(lcluster.Generation == initGeneration+2).Should(BeTrue()) g.Expect(lcluster.Generation == lcluster.Status.ObservedGeneration).Should(BeTrue()) - g.Expect(cluster.Status.Phase).Should(Equal(appsv1alpha1.RunningClusterPhase)) + g.Expect(cluster.Status.Phase).Should(Equal(appsv1.RunningClusterPhase)) })).Should(Succeed()) }) @@ -441,12 +441,12 @@ var _ = Describe("OpsRequest Controller", func() { By("expect cluster and component is reconciling the new spec") Eventually(testapps.GetOpsRequestPhase(&testCtx, opsKey)).Should(Equal(appsv1alpha1.OpsRunningPhase)) - Eventually(testapps.CheckObj(&testCtx, clusterKey, func(g Gomega, cluster *appsv1alpha1.Cluster) { + Eventually(testapps.CheckObj(&testCtx, clusterKey, func(g Gomega, cluster *appsv1.Cluster) { g.Expect(cluster.Generation == 2).Should(BeTrue()) g.Expect(cluster.Status.ObservedGeneration == 2).Should(BeTrue()) - g.Expect(cluster.Status.Components[mysqlCompName].Phase).Should(Equal(appsv1alpha1.UpdatingClusterCompPhase)) + g.Expect(cluster.Status.Components[mysqlCompName].Phase).Should(Equal(appsv1.UpdatingClusterCompPhase)) // the expected cluster phase is Updating during Hscale. - g.Expect(cluster.Status.Phase).Should(Equal(appsv1alpha1.UpdatingClusterPhase)) + g.Expect(cluster.Status.Phase).Should(Equal(appsv1.UpdatingClusterPhase)) })).Should(Succeed()) By("mock backup status is ready, component phase should change to Updating when component is horizontally scaling.") @@ -457,9 +457,9 @@ var _ = Describe("OpsRequest Controller", func() { backup.Status.Phase = dpv1alpha1.BackupPhaseCompleted testdp.MockBackupStatusMethod(backup, testdp.BackupMethodName, testapps.DataVolumeName, testdp.ActionSetName) Expect(k8sClient.Status().Update(testCtx.Ctx, backup)).Should(Succeed()) - Consistently(testapps.CheckObj(&testCtx, clusterKey, func(g Gomega, cluster *appsv1alpha1.Cluster) { - g.Expect(cluster.Status.Components[mysqlCompName].Phase).Should(Equal(appsv1alpha1.UpdatingClusterCompPhase)) - g.Expect(cluster.Status.Phase).Should(Equal(appsv1alpha1.UpdatingClusterPhase)) + Consistently(testapps.CheckObj(&testCtx, clusterKey, func(g Gomega, cluster *appsv1.Cluster) { + g.Expect(cluster.Status.Components[mysqlCompName].Phase).Should(Equal(appsv1.UpdatingClusterCompPhase)) + g.Expect(cluster.Status.Phase).Should(Equal(appsv1.UpdatingClusterPhase)) })).Should(Succeed()) By("mock create volumesnapshot, which should done by backup controller") @@ -478,7 +478,7 @@ var _ = Describe("OpsRequest Controller", func() { Expect(k8sClient.Create(testCtx.Ctx, vs)).Should(Succeed()) Eventually(testapps.CheckObjExists(&testCtx, backupKey, vs, true)).Should(Succeed()) - mockComponentPVCsAndBound := func(comp *appsv1alpha1.ClusterComponentSpec) { + mockComponentPVCsAndBound := func(comp *appsv1.ClusterComponentSpec) { for i := 0; i < int(replicas); i++ { for _, vct := range comp.VolumeClaimTemplates { pvcKey := types.NamespacedName{ @@ -503,7 +503,7 @@ var _ = Describe("OpsRequest Controller", func() { } // mock pvcs have restored - mockComponentPVCsAndBound(clusterObj.Spec.GetComponentByName(mysqlCompName)) + mockComponentPVCsAndBound(clusterObj.GetComponentByName(mysqlCompName)) // check restore CR and mock it to Completed checkRestoreAndSetCompleted(clusterKey, mysqlCompName, int(replicas-oldReplicas)) @@ -544,9 +544,9 @@ var _ = Describe("OpsRequest Controller", func() { By("mock component workload is running and expect cluster and component are running") mockCompRunning(replicas, false) - Eventually(testapps.CheckObj(&testCtx, clusterKey, func(g Gomega, cluster *appsv1alpha1.Cluster) { - g.Expect(cluster.Status.Components[mysqlCompName].Phase).Should(Equal(appsv1alpha1.RunningClusterCompPhase)) - g.Expect(cluster.Status.Phase).Should(Equal(appsv1alpha1.RunningClusterPhase)) + Eventually(testapps.CheckObj(&testCtx, clusterKey, func(g Gomega, cluster *appsv1.Cluster) { + g.Expect(cluster.Status.Components[mysqlCompName].Phase).Should(Equal(appsv1.RunningClusterCompPhase)) + g.Expect(cluster.Status.Phase).Should(Equal(appsv1.RunningClusterPhase)) })).Should(Succeed()) Eventually(testapps.GetOpsRequestPhase(&testCtx, opsKey)).Should(Equal(appsv1alpha1.OpsSucceedPhase)) }) @@ -559,7 +559,7 @@ var _ = Describe("OpsRequest Controller", func() { createMysqlCluster(3) By("mock component replicas to 4 and actual pods is 3") - Expect(testapps.ChangeObj(&testCtx, clusterObj, func(clusterObj *appsv1alpha1.Cluster) { + Expect(testapps.ChangeObj(&testCtx, clusterObj, func(clusterObj *appsv1.Cluster) { clusterObj.Spec.ComponentSpecs[0].Replicas = 4 })).Should(Succeed()) @@ -581,9 +581,9 @@ var _ = Describe("OpsRequest Controller", func() { } By("wait for cluster and component phase are Updating") - Eventually(testapps.CheckObj(&testCtx, clusterKey, func(g Gomega, cluster *appsv1alpha1.Cluster) { - g.Expect(cluster.Status.Components[mysqlCompName].Phase).Should(Equal(appsv1alpha1.UpdatingClusterCompPhase)) - g.Expect(cluster.Status.Phase).Should(Equal(appsv1alpha1.UpdatingClusterPhase)) + Eventually(testapps.CheckObj(&testCtx, clusterKey, func(g Gomega, cluster *appsv1.Cluster) { + g.Expect(cluster.Status.Components[mysqlCompName].Phase).Should(Equal(appsv1.UpdatingClusterCompPhase)) + g.Expect(cluster.Status.Phase).Should(Equal(appsv1.UpdatingClusterPhase)) })).Should(Succeed()) By("check the underlying workload been updated") @@ -622,7 +622,7 @@ var _ = Describe("OpsRequest Controller", func() { Eventually(testapps.GetOpsRequestPhase(&testCtx, opsKey)).Should(Equal(appsv1alpha1.OpsRunningPhase)) By("check if existing horizontalScaling opsRequest annotation in cluster") - Eventually(testapps.CheckObj(&testCtx, clusterKey, func(g Gomega, tmlCluster *appsv1alpha1.Cluster) { + Eventually(testapps.CheckObj(&testCtx, clusterKey, func(g Gomega, tmlCluster *appsv1.Cluster) { opsSlice, _ := opsutil.GetOpsRequestSliceFromCluster(tmlCluster) g.Expect(opsSlice).Should(HaveLen(1)) g.Expect(opsSlice[0].Name).Should(Equal(ops.Name)) @@ -635,7 +635,7 @@ var _ = Describe("OpsRequest Controller", func() { })).ShouldNot(HaveOccurred()) By("check the cluster annotation") - Eventually(testapps.CheckObj(&testCtx, clusterKey, func(g Gomega, tmlCluster *appsv1alpha1.Cluster) { + Eventually(testapps.CheckObj(&testCtx, clusterKey, func(g Gomega, tmlCluster *appsv1.Cluster) { opsSlice, _ := opsutil.GetOpsRequestSliceFromCluster(tmlCluster) g.Expect(opsSlice).Should(HaveLen(0)) })).Should(Succeed()) @@ -652,7 +652,7 @@ var _ = Describe("OpsRequest Controller", func() { ops := createClusterHscaleOps(5) opsKey := client.ObjectKeyFromObject(ops) Eventually(testapps.GetOpsRequestPhase(&testCtx, opsKey)).Should(Equal(appsv1alpha1.OpsRunningPhase)) - Eventually(testapps.GetClusterPhase(&testCtx, clusterKey)).Should(Equal(appsv1alpha1.UpdatingClusterPhase)) + Eventually(testapps.GetClusterPhase(&testCtx, clusterKey)).Should(Equal(appsv1.UpdatingClusterPhase)) By("create one pod") podName := fmt.Sprintf("%s-%s-%d", clusterObj.Name, mysqlCompName, 3) @@ -700,10 +700,10 @@ var _ = Describe("OpsRequest Controller", func() { })).Should(Succeed()) By("cluster phase should be Running and delete the opsRequest annotation") - Eventually(testapps.CheckObj(&testCtx, clusterKey, func(g Gomega, tmlCluster *appsv1alpha1.Cluster) { + Eventually(testapps.CheckObj(&testCtx, clusterKey, func(g Gomega, tmlCluster *appsv1.Cluster) { opsSlice, _ := opsutil.GetOpsRequestSliceFromCluster(tmlCluster) g.Expect(opsSlice).Should(HaveLen(0)) - g.Expect(tmlCluster.Status.Phase).Should(Equal(appsv1alpha1.RunningClusterPhase)) + g.Expect(tmlCluster.Status.Phase).Should(Equal(appsv1.RunningClusterPhase)) })).Should(Succeed()) By("check OpsRequest reclaimed after ttl") @@ -754,7 +754,7 @@ var _ = Describe("OpsRequest Controller", func() { Eventually(testapps.GetOpsRequestPhase(&testCtx, client.ObjectKeyFromObject(ops3))).Should(Equal(appsv1alpha1.OpsPendingPhase)) By("expect for all opsRequests in the queue") - Eventually(testapps.CheckObj(&testCtx, client.ObjectKeyFromObject(clusterObj), func(g Gomega, cluster *appsv1alpha1.Cluster) { + Eventually(testapps.CheckObj(&testCtx, client.ObjectKeyFromObject(clusterObj), func(g Gomega, cluster *appsv1.Cluster) { opsSlice, _ := opsutil.GetOpsRequestSliceFromCluster(cluster) g.Expect(len(opsSlice)).Should(Equal(3)) // ops1 is running @@ -772,7 +772,7 @@ var _ = Describe("OpsRequest Controller", func() { By("expect for next ops is Running") Eventually(testapps.GetOpsRequestPhase(&testCtx, client.ObjectKeyFromObject(ops2))).Should(Equal(appsv1alpha1.OpsRunningPhase)) - Eventually(testapps.CheckObj(&testCtx, client.ObjectKeyFromObject(clusterObj), func(g Gomega, cluster *appsv1alpha1.Cluster) { + Eventually(testapps.CheckObj(&testCtx, client.ObjectKeyFromObject(clusterObj), func(g Gomega, cluster *appsv1.Cluster) { // ops1 should be dequeue opsSlice, _ := opsutil.GetOpsRequestSliceFromCluster(cluster) g.Expect(len(opsSlice)).Should(Equal(2)) @@ -804,7 +804,7 @@ var _ = Describe("OpsRequest Controller", func() { Eventually(testapps.GetOpsRequestPhase(&testCtx, client.ObjectKeyFromObject(ops3))).Should(Equal(appsv1alpha1.OpsRunningPhase)) By("expect for ops3 is running and ops1/ops is aborted") - Eventually(testapps.CheckObj(&testCtx, client.ObjectKeyFromObject(clusterObj), func(g Gomega, cluster *appsv1alpha1.Cluster) { + Eventually(testapps.CheckObj(&testCtx, client.ObjectKeyFromObject(clusterObj), func(g Gomega, cluster *appsv1.Cluster) { opsSlice, _ := opsutil.GetOpsRequestSliceFromCluster(cluster) g.Expect(len(opsSlice)).Should(Equal(1)) g.Expect(opsSlice[0].InQueue).Should(BeFalse()) @@ -864,7 +864,7 @@ var _ = Describe("OpsRequest Controller", func() { Eventually(testapps.GetOpsRequestPhase(&testCtx, client.ObjectKeyFromObject(exposeOps2))).Should(Equal(appsv1alpha1.OpsPendingPhase)) By("check opsRequest queue") - Eventually(testapps.CheckObj(&testCtx, client.ObjectKeyFromObject(clusterObj), func(g Gomega, cluster *appsv1alpha1.Cluster) { + Eventually(testapps.CheckObj(&testCtx, client.ObjectKeyFromObject(clusterObj), func(g Gomega, cluster *appsv1.Cluster) { opsSlice, _ := opsutil.GetOpsRequestSliceFromCluster(cluster) g.Expect(len(opsSlice)).Should(Equal(4)) // restartOps1 is running diff --git a/controllers/apps/servicedescriptor_controller.go b/controllers/apps/servicedescriptor_controller.go index c2e087e8b3c..e2647c275ca 100644 --- a/controllers/apps/servicedescriptor_controller.go +++ b/controllers/apps/servicedescriptor_controller.go @@ -31,7 +31,6 @@ import ( "sigs.k8s.io/controller-runtime/pkg/log" appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" "github.com/apecloud/kubeblocks/pkg/constant" intctrlutil "github.com/apecloud/kubeblocks/pkg/controllerutil" ) @@ -75,7 +74,7 @@ func (r *ServiceDescriptorReconciler) Reconcile(ctx context.Context, req ctrl.Re "cannot be deleted because of existing service referencing Cluster.") } if res, err := intctrlutil.ValidateReferenceCR(reqCtx, r.Client, serviceDescriptor, - constant.ServiceDescriptorNameLabelKey, recordEvent, &appsv1alpha1.ClusterList{}); res != nil || err != nil { + constant.ServiceDescriptorNameLabelKey, recordEvent, &appsv1.ClusterList{}); res != nil || err != nil { return res, err } return nil, nil diff --git a/controllers/apps/transform_utils.go b/controllers/apps/transform_utils.go index eaf9db33e41..75e170ed429 100644 --- a/controllers/apps/transform_utils.go +++ b/controllers/apps/transform_utils.go @@ -36,7 +36,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client/apiutil" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" "github.com/apecloud/kubeblocks/pkg/constant" "github.com/apecloud/kubeblocks/pkg/controller/graph" @@ -62,7 +62,7 @@ func getGVKName(object client.Object, scheme *runtime.Scheme) (*gvkNObjKey, erro }, nil } -func getAppInstanceML(cluster appsv1alpha1.Cluster) client.MatchingLabels { +func getAppInstanceML(cluster appsv1.Cluster) client.MatchingLabels { return client.MatchingLabels{ constant.AppInstanceLabelKey: cluster.Name, } @@ -151,7 +151,7 @@ func isResourceEqual(a, b corev1.ResourceList) bool { return true } -func isVolumeClaimTemplatesEqual(a, b []appsv1alpha1.ClusterComponentVolumeClaimTemplate) bool { +func isVolumeClaimTemplatesEqual(a, b []appsv1.ClusterComponentVolumeClaimTemplate) bool { if len(a) != len(b) { return false } @@ -246,7 +246,7 @@ func removeOwnerRefOfType(obj client.Object, gvk schema.GroupVersionKind) { // isOwnedByComp is used to judge if the obj is owned by Component. func isOwnedByComp(obj client.Object) bool { for _, ref := range obj.GetOwnerReferences() { - if ref.Kind == appsv1alpha1.ComponentKind && ref.Controller != nil && *ref.Controller { + if ref.Kind == appsv1.ComponentKind && ref.Controller != nil && *ref.Controller { return true } } diff --git a/controllers/apps/transform_utils_test.go b/controllers/apps/transform_utils_test.go index 7445add2611..c646b9ee0dd 100644 --- a/controllers/apps/transform_utils_test.go +++ b/controllers/apps/transform_utils_test.go @@ -35,7 +35,7 @@ import ( "k8s.io/utils/pointer" "sigs.k8s.io/controller-runtime/pkg/client" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" + kbappsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" ) @@ -65,11 +65,11 @@ func TestReflect(t *testing.T) { } func TestIsVolumeClaimTemplatesEqual(t *testing.T) { - buildVCT := func(size string) []appsv1alpha1.ClusterComponentVolumeClaimTemplate { - return []appsv1alpha1.ClusterComponentVolumeClaimTemplate{ + buildVCT := func(size string) []kbappsv1.ClusterComponentVolumeClaimTemplate { + return []kbappsv1.ClusterComponentVolumeClaimTemplate{ { Name: "data", - Spec: appsv1alpha1.PersistentVolumeClaimSpec{ + Spec: kbappsv1.PersistentVolumeClaimSpec{ Resources: corev1.VolumeResourceRequirements{ Requests: corev1.ResourceList{ corev1.ResourceStorage: resource.MustParse(size), @@ -138,7 +138,7 @@ func TestIsOwnedByInstanceSet(t *testing.T) { its.OwnerReferences = []metav1.OwnerReference{ { - Kind: reflect.TypeOf(appsv1alpha1.Cluster{}).Name(), + Kind: reflect.TypeOf(kbappsv1.Cluster{}).Name(), Controller: pointer.Bool(true), }, } diff --git a/controllers/apps/transformer_cluster_api_normalization.go b/controllers/apps/transformer_cluster_api_normalization.go index 882f6fa2848..7b11ba4dc6a 100644 --- a/controllers/apps/transformer_cluster_api_normalization.go +++ b/controllers/apps/transformer_cluster_api_normalization.go @@ -28,7 +28,6 @@ import ( "k8s.io/apimachinery/pkg/util/sets" appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" "github.com/apecloud/kubeblocks/pkg/constant" "github.com/apecloud/kubeblocks/pkg/controller/component" "github.com/apecloud/kubeblocks/pkg/controller/graph" @@ -76,7 +75,7 @@ func (t *ClusterAPINormalizationTransformer) Transform(ctx graph.TransformContex return nil } -func (t *ClusterAPINormalizationTransformer) validateSpec(cluster *appsv1alpha1.Cluster) error { +func (t *ClusterAPINormalizationTransformer) validateSpec(cluster *appsv1.Cluster) error { if len(cluster.Spec.ShardingSpecs) == 0 { return nil } @@ -93,7 +92,7 @@ func (t *ClusterAPINormalizationTransformer) validateSpec(cluster *appsv1alpha1. } func (t *ClusterAPINormalizationTransformer) buildCompSpecs(transCtx *clusterTransformContext, - cluster *appsv1alpha1.Cluster) ([]*appsv1alpha1.ClusterComponentSpec, error) { + cluster *appsv1.Cluster) ([]*appsv1.ClusterComponentSpec, error) { if withClusterTopology(cluster) { return t.buildCompSpecs4Topology(transCtx.ClusterDef, cluster) } @@ -108,15 +107,15 @@ func (t *ClusterAPINormalizationTransformer) buildCompSpecs(transCtx *clusterTra } func (t *ClusterAPINormalizationTransformer) buildCompSpecs4Topology(clusterDef *appsv1.ClusterDefinition, - cluster *appsv1alpha1.Cluster) ([]*appsv1alpha1.ClusterComponentSpec, error) { - newCompSpec := func(comp appsv1.ClusterTopologyComponent) *appsv1alpha1.ClusterComponentSpec { - return &appsv1alpha1.ClusterComponentSpec{ + cluster *appsv1.Cluster) ([]*appsv1.ClusterComponentSpec, error) { + newCompSpec := func(comp appsv1.ClusterTopologyComponent) *appsv1.ClusterComponentSpec { + return &appsv1.ClusterComponentSpec{ Name: comp.Name, ComponentDef: comp.CompDef, } } - mergeCompSpec := func(comp appsv1.ClusterTopologyComponent, compSpec *appsv1alpha1.ClusterComponentSpec) *appsv1alpha1.ClusterComponentSpec { + mergeCompSpec := func(comp appsv1.ClusterTopologyComponent, compSpec *appsv1.ClusterComponentSpec) *appsv1.ClusterComponentSpec { if len(compSpec.ComponentDef) == 0 { compSpec.ComponentDef = comp.CompDef } @@ -128,12 +127,12 @@ func (t *ClusterAPINormalizationTransformer) buildCompSpecs4Topology(clusterDef return nil, fmt.Errorf("referred cluster topology not found : %s", cluster.Spec.Topology) } - specifiedCompSpecs := make(map[string]*appsv1alpha1.ClusterComponentSpec) + specifiedCompSpecs := make(map[string]*appsv1.ClusterComponentSpec) for i, compSpec := range cluster.Spec.ComponentSpecs { specifiedCompSpecs[compSpec.Name] = cluster.Spec.ComponentSpecs[i].DeepCopy() } - compSpecs := make([]*appsv1alpha1.ClusterComponentSpec, 0) + compSpecs := make([]*appsv1.ClusterComponentSpec, 0) for i := range clusterTopology.Components { comp := clusterTopology.Components[i] if _, ok := specifiedCompSpecs[comp.Name]; ok { @@ -146,8 +145,8 @@ func (t *ClusterAPINormalizationTransformer) buildCompSpecs4Topology(clusterDef } func (t *ClusterAPINormalizationTransformer) buildCompSpecs4Specified(transCtx *clusterTransformContext, - cluster *appsv1alpha1.Cluster) ([]*appsv1alpha1.ClusterComponentSpec, error) { - compSpecs := make([]*appsv1alpha1.ClusterComponentSpec, 0) + cluster *appsv1.Cluster) ([]*appsv1.ClusterComponentSpec, error) { + compSpecs := make([]*appsv1.ClusterComponentSpec, 0) for i := range cluster.Spec.ComponentSpecs { compSpecs = append(compSpecs, cluster.Spec.ComponentSpecs[i].DeepCopy()) } @@ -162,10 +161,10 @@ func (t *ClusterAPINormalizationTransformer) buildCompSpecs4Specified(transCtx * } func (t *ClusterAPINormalizationTransformer) buildCompSpecs4Sharding(transCtx *clusterTransformContext, - cluster *appsv1alpha1.Cluster) ([]*appsv1alpha1.ClusterComponentSpec, error) { - compSpecs := make([]*appsv1alpha1.ClusterComponentSpec, 0) + cluster *appsv1.Cluster) ([]*appsv1.ClusterComponentSpec, error) { + compSpecs := make([]*appsv1.ClusterComponentSpec, 0) if transCtx.ShardingComponentSpecs == nil { - transCtx.ShardingComponentSpecs = make(map[string][]*appsv1alpha1.ClusterComponentSpec, 0) + transCtx.ShardingComponentSpecs = make(map[string][]*appsv1.ClusterComponentSpec, 0) } for i, sharding := range cluster.Spec.ShardingSpecs { shardingComps, err := controllerutil.GenShardingCompSpecList(transCtx.Context, transCtx.Client, cluster, &cluster.Spec.ShardingSpecs[i]) @@ -179,7 +178,7 @@ func (t *ClusterAPINormalizationTransformer) buildCompSpecs4Sharding(transCtx *c } func (t *ClusterAPINormalizationTransformer) buildCompLabelsInheritedFromCluster(transCtx *clusterTransformContext, - cluster *appsv1alpha1.Cluster) map[string]map[string]string { + cluster *appsv1.Cluster) map[string]map[string]string { clusterLabels := filterReservedLabels(cluster.Labels) labels := make(map[string]map[string]string) for _, compSpec := range transCtx.ComponentSpecs { @@ -194,7 +193,7 @@ func (t *ClusterAPINormalizationTransformer) buildCompLabelsInheritedFromCluster } func (t *ClusterAPINormalizationTransformer) buildCompAnnotationsInheritedFromCluster(transCtx *clusterTransformContext, - cluster *appsv1alpha1.Cluster) map[string]map[string]string { + cluster *appsv1.Cluster) map[string]map[string]string { clusterAnnotations := filterReservedAnnotations(cluster.Annotations) annotations := make(map[string]map[string]string) for _, compSpec := range transCtx.ComponentSpecs { @@ -221,7 +220,7 @@ func (t *ClusterAPINormalizationTransformer) resolveCompDefinitions(transCtx *cl } func (t *ClusterAPINormalizationTransformer) resolveCompDefinitionNServiceVersion(transCtx *clusterTransformContext, - compSpec *appsv1alpha1.ClusterComponentSpec) (*appsv1.ComponentDefinition, string, error) { + compSpec *appsv1.ClusterComponentSpec) (*appsv1.ComponentDefinition, string, error) { if withClusterLegacyDefinition(transCtx.Cluster) || withClusterSimplifiedAPI(transCtx.Cluster) { return nil, "", fmt.Errorf("legacy cluster definition or simplified API are not supported") } @@ -229,7 +228,7 @@ func (t *ClusterAPINormalizationTransformer) resolveCompDefinitionNServiceVersio } func (t *ClusterAPINormalizationTransformer) resolveCompDefinitionNServiceVersionWithUpgrade(transCtx *clusterTransformContext, - compSpec *appsv1alpha1.ClusterComponentSpec) (*appsv1.ComponentDefinition, string, error) { + compSpec *appsv1.ClusterComponentSpec) (*appsv1.ComponentDefinition, string, error) { var ( ctx = transCtx.Context cli = transCtx.Client @@ -247,7 +246,7 @@ func (t *ClusterAPINormalizationTransformer) resolveCompDefinitionNServiceVersio return resolveCompDefinitionNServiceVersion(ctx, cli, comp.Spec.CompDef, comp.Spec.ServiceVersion) } -func (t *ClusterAPINormalizationTransformer) checkCompUpgrade(compSpec *appsv1alpha1.ClusterComponentSpec, comp *appsv1.Component) bool { +func (t *ClusterAPINormalizationTransformer) checkCompUpgrade(compSpec *appsv1.ClusterComponentSpec, comp *appsv1.Component) bool { return compSpec.ServiceVersion != comp.Spec.ServiceVersion || compSpec.ComponentDef != comp.Spec.CompDef } @@ -270,9 +269,9 @@ func (t *ClusterAPINormalizationTransformer) updateCompSpecs4Topology(transCtx * var ( cluster = transCtx.Cluster ) - compSpecs := make([]appsv1alpha1.ClusterComponentSpec, 0) + compSpecs := make([]appsv1.ClusterComponentSpec, 0) for i := range transCtx.ComponentSpecs { - compSpecs = append(compSpecs, appsv1alpha1.ClusterComponentSpec{ + compSpecs = append(compSpecs, appsv1.ClusterComponentSpec{ Name: transCtx.ComponentSpecs[i].Name, ComponentDef: transCtx.ComponentSpecs[i].ComponentDef, ServiceVersion: transCtx.ComponentSpecs[i].ServiceVersion, diff --git a/controllers/apps/transformer_cluster_backup_policy.go b/controllers/apps/transformer_cluster_backup_policy.go index 8ded1ced2c8..96b6c89b1e9 100644 --- a/controllers/apps/transformer_cluster_backup_policy.go +++ b/controllers/apps/transformer_cluster_backup_policy.go @@ -30,6 +30,7 @@ import ( "k8s.io/gengo/examples/set-gen/sets" "sigs.k8s.io/controller-runtime/pkg/client" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" dpv1alpha1 "github.com/apecloud/kubeblocks/apis/dataprotection/v1alpha1" workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" @@ -60,7 +61,7 @@ type clusterBackupPolicyTransformer struct { } type componentItem struct { - compSpec *appsv1alpha1.ClusterComponentSpec + compSpec *appsv1.ClusterComponentSpec // shardingSpec.Name or componentSpec.Name componentName string isSharding bool @@ -169,7 +170,7 @@ func (r *clusterBackupPolicyTransformer) Transform(ctx graph.TransformContext, d graphCli.Patch(dag, oldBackupSchedule, newBackupSchedule) } graphCli.DependOn(dag, backupPolicy, newBackupSchedule) - comps := graphCli.FindAll(dag, &appsv1alpha1.Component{}) + comps := graphCli.FindAll(dag, &appsv1.Component{}) graphCli.DependOn(dag, backupPolicy, comps...) backupScheduleNames[newBackupSchedule.Name] = struct{}{} } @@ -443,7 +444,7 @@ func (r *clusterBackupPolicyTransformer) syncBackupMethods(backupPolicy *dpv1alp backupPolicy.Spec.BackupMethods = backupMethods } -func (r *clusterBackupPolicyTransformer) doEnvMapping(comp *appsv1alpha1.ClusterComponentSpec, envMapping []appsv1alpha1.EnvMappingVar) []corev1.EnvVar { +func (r *clusterBackupPolicyTransformer) doEnvMapping(comp *appsv1.ClusterComponentSpec, envMapping []appsv1alpha1.EnvMappingVar) []corev1.EnvVar { var env []corev1.EnvVar for _, v := range envMapping { for _, cm := range v.ValueFrom.ComponentDef { @@ -637,7 +638,7 @@ func (r *clusterBackupPolicyTransformer) mergeClusterBackup( } func (r *clusterBackupPolicyTransformer) getClusterComponentItems() []componentItem { - matchedCompDef := func(compSpec appsv1alpha1.ClusterComponentSpec) bool { + matchedCompDef := func(compSpec appsv1.ClusterComponentSpec) bool { // TODO: support to create bp when using cluster topology and componentDef is empty if len(compSpec.ComponentDef) > 0 { for _, compDef := range r.backupPolicy.ComponentDefs { @@ -707,7 +708,7 @@ func (r *clusterBackupPolicyTransformer) buildLabels(compItem componentItem, pol return labels } -func (r *clusterBackupPolicyTransformer) compDefName(comp *appsv1alpha1.ClusterComponentSpec, +func (r *clusterBackupPolicyTransformer) compDefName(comp *appsv1.ClusterComponentSpec, policy *dpv1alpha1.BackupPolicy) string { switch { case comp != nil: @@ -719,7 +720,7 @@ func (r *clusterBackupPolicyTransformer) compDefName(comp *appsv1alpha1.ClusterC } } -func (r *clusterBackupPolicyTransformer) compDefNameFromSpec(comp *appsv1alpha1.ClusterComponentSpec) string { +func (r *clusterBackupPolicyTransformer) compDefNameFromSpec(comp *appsv1.ClusterComponentSpec) string { return comp.ComponentDef } @@ -766,7 +767,7 @@ func generateBackupScheduleName(clusterName, componentName, identifier string) s return fmt.Sprintf("%s-%s-backup-schedule-%s", clusterName, componentName, identifier) } -func buildBackupPathPrefix(cluster *appsv1alpha1.Cluster, compName string) string { +func buildBackupPathPrefix(cluster *appsv1.Cluster, compName string) string { return fmt.Sprintf("/%s-%s/%s", cluster.Name, cluster.UID, compName) } diff --git a/controllers/apps/transformer_cluster_component.go b/controllers/apps/transformer_cluster_component.go index b22b5caebc5..c26aac9ef9e 100644 --- a/controllers/apps/transformer_cluster_component.go +++ b/controllers/apps/transformer_cluster_component.go @@ -72,7 +72,7 @@ func (t *clusterComponentTransformer) Transform(ctx graph.TransformContext, dag func (t *clusterComponentTransformer) reconcileComponents(transCtx *clusterTransformContext, dag *graph.DAG) error { cluster := transCtx.Cluster - protoCompSpecMap := make(map[string]*appsv1alpha1.ClusterComponentSpec) + protoCompSpecMap := make(map[string]*appsv1.ClusterComponentSpec) for _, compSpec := range transCtx.ComponentSpecs { protoCompSpecMap[compSpec.Name] = compSpec } @@ -110,14 +110,14 @@ func (t *clusterComponentTransformer) reconcileComponents(transCtx *clusterTrans } func (t *clusterComponentTransformer) handleCompsCreate(transCtx *clusterTransformContext, dag *graph.DAG, - protoCompSpecMap map[string]*appsv1alpha1.ClusterComponentSpec, createCompSet sets.Set[string], + protoCompSpecMap map[string]*appsv1.ClusterComponentSpec, createCompSet sets.Set[string], protoCompLabelsMap, protoCompAnnotationsMap map[string]map[string]string) error { handler := newCompHandler(transCtx, protoCompSpecMap, protoCompLabelsMap, protoCompAnnotationsMap, createOp) return handleCompsInOrder(transCtx, dag, createCompSet, handler) } func (t *clusterComponentTransformer) handleCompsUpdate(transCtx *clusterTransformContext, dag *graph.DAG, - protoCompSpecMap map[string]*appsv1alpha1.ClusterComponentSpec, updateCompSet sets.Set[string], + protoCompSpecMap map[string]*appsv1.ClusterComponentSpec, updateCompSet sets.Set[string], protoCompLabelsMap, protoCompAnnotationsMap map[string]map[string]string) error { handler := newCompHandler(transCtx, protoCompSpecMap, protoCompLabelsMap, protoCompAnnotationsMap, updateOp) return handleCompsInOrder(transCtx, dag, updateCompSet, handler) @@ -156,7 +156,7 @@ func handleCompsInOrder(transCtx *clusterTransformContext, dag *graph.DAG, return nil } -func checkAllCompsUpToDate(transCtx *clusterTransformContext, cluster *appsv1alpha1.Cluster) (bool, error) { +func checkAllCompsUpToDate(transCtx *clusterTransformContext, cluster *appsv1.Cluster) (bool, error) { compList := &appsv1.ComponentList{} labels := constant.GetClusterWellKnownLabels(cluster.Name) if err := transCtx.Client.List(transCtx.Context, compList, client.InNamespace(cluster.Namespace), client.MatchingLabels(labels)); err != nil { @@ -178,7 +178,7 @@ func checkAllCompsUpToDate(transCtx *clusterTransformContext, cluster *appsv1alp } // getRunningCompObject gets the component object from cache snapshot -func getRunningCompObject(transCtx *clusterTransformContext, cluster *appsv1alpha1.Cluster, compName string) (*appsv1.Component, error) { +func getRunningCompObject(transCtx *clusterTransformContext, cluster *appsv1.Cluster, compName string) (*appsv1.Component, error) { compKey := types.NamespacedName{ Namespace: cluster.Namespace, Name: component.FullName(cluster.Name, compName), @@ -243,7 +243,7 @@ const ( updateOp int = 2 ) -func newCompHandler(transCtx *clusterTransformContext, compSpecs map[string]*appsv1alpha1.ClusterComponentSpec, +func newCompHandler(transCtx *clusterTransformContext, compSpecs map[string]*appsv1.ClusterComponentSpec, labels, annotations map[string]map[string]string, op int) compConditionalHandler { orders := definedOrders(transCtx, op) if len(orders) == 0 { @@ -278,7 +278,7 @@ func definedOrders(transCtx *clusterTransformContext, op int) []string { return nil } -func newParallelHandler(compSpecs map[string]*appsv1alpha1.ClusterComponentSpec, +func newParallelHandler(compSpecs map[string]*appsv1.ClusterComponentSpec, labels, annotations map[string]map[string]string, op int) compConditionalHandler { switch op { case createOp: @@ -304,7 +304,7 @@ func newParallelHandler(compSpecs map[string]*appsv1alpha1.ClusterComponentSpec, } } -func newOrderedHandler(compSpecs map[string]*appsv1alpha1.ClusterComponentSpec, +func newOrderedHandler(compSpecs map[string]*appsv1.ClusterComponentSpec, labels, annotations map[string]map[string]string, orders []string, op int) compConditionalHandler { upworking := func(comp *appsv1.Component) bool { target := appsv1.RunningClusterCompPhase @@ -487,7 +487,7 @@ func predecessors(orders []string, compName string) []string { } type createCompHandler struct { - compSpecs map[string]*appsv1alpha1.ClusterComponentSpec + compSpecs map[string]*appsv1.ClusterComponentSpec labels map[string]map[string]string annotations map[string]map[string]string } @@ -504,11 +504,11 @@ func (h *createCompHandler) handle(transCtx *clusterTransformContext, dag *graph return nil } -func (h *createCompHandler) initClusterCompStatus(cluster *appsv1alpha1.Cluster, compName string) { +func (h *createCompHandler) initClusterCompStatus(cluster *appsv1.Cluster, compName string) { if cluster.Status.Components == nil { - cluster.Status.Components = make(map[string]appsv1alpha1.ClusterComponentStatus) + cluster.Status.Components = make(map[string]appsv1.ClusterComponentStatus) } - cluster.Status.Components[compName] = appsv1alpha1.ClusterComponentStatus{} + cluster.Status.Components[compName] = appsv1.ClusterComponentStatus{} } type deleteCompHandler struct { @@ -540,7 +540,7 @@ func (h *deleteCompHandler) handle(transCtx *clusterTransformContext, dag *graph } type updateCompHandler struct { - compSpecs map[string]*appsv1alpha1.ClusterComponentSpec + compSpecs map[string]*appsv1.ClusterComponentSpec labels map[string]map[string]string annotations map[string]map[string]string } diff --git a/controllers/apps/transformer_cluster_component_status.go b/controllers/apps/transformer_cluster_component_status.go index 440ab331f15..c682cf6782c 100644 --- a/controllers/apps/transformer_cluster_component_status.go +++ b/controllers/apps/transformer_cluster_component_status.go @@ -25,11 +25,9 @@ import ( "golang.org/x/exp/slices" corev1 "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" "github.com/apecloud/kubeblocks/pkg/controller/component" "github.com/apecloud/kubeblocks/pkg/controller/graph" "github.com/apecloud/kubeblocks/pkg/controller/model" @@ -56,7 +54,7 @@ func (t *clusterComponentStatusTransformer) Transform(ctx graph.TransformContext func (t *clusterComponentStatusTransformer) reconcileComponentsStatus(transCtx *clusterTransformContext) error { cluster := transCtx.Cluster if cluster.Status.Components == nil { - cluster.Status.Components = make(map[string]appsv1alpha1.ClusterComponentStatus) + cluster.Status.Components = make(map[string]appsv1.ClusterComponentStatus) } // We cannot use cluster.status.components here because of simplified API generated component is not in it. for _, compSpec := range transCtx.ComponentSpecs { @@ -78,7 +76,7 @@ func (t *clusterComponentStatusTransformer) reconcileComponentsStatus(transCtx * // buildClusterCompStatus builds cluster component status from specified component object. func (t *clusterComponentStatusTransformer) buildClusterCompStatus(transCtx *clusterTransformContext, - comp *appsv1.Component, compName string) appsv1alpha1.ClusterComponentStatus { + comp *appsv1.Component, compName string) appsv1.ClusterComponentStatus { var ( cluster = transCtx.Cluster status = cluster.Status.Components[compName] @@ -101,7 +99,7 @@ func (t *clusterComponentStatusTransformer) buildClusterCompStatus(transCtx *clu // updateClusterComponentStatus sets the cluster component phase and messages conditionally. func (t *clusterComponentStatusTransformer) updateClusterComponentStatus(comp *appsv1.Component, - status *appsv1alpha1.ClusterComponentStatus) { + status *appsv1.ClusterComponentStatus) { if string(status.Phase) != string(comp.Status.Phase) { status.Phase = comp.Status.Phase if status.Message == nil { @@ -112,15 +110,16 @@ func (t *clusterComponentStatusTransformer) updateClusterComponentStatus(comp *a } } } - // if ready flag not changed, don't update the ready time - ready := t.isClusterComponentPodsReady(comp.Status.Phase) - if status.PodsReady == nil || *status.PodsReady != ready { - status.PodsReady = &ready - if ready { - now := metav1.Now() - status.PodsReadyTime = &now - } - } + // TODO(v1.0): status + //// if ready flag not changed, don't update the ready time + // ready := t.isClusterComponentPodsReady(comp.Status.Phase) + // if status.PodsReady == nil || *status.PodsReady != ready { + // status.PodsReady = &ready + // if ready { + // now := metav1.Now() + // status.PodsReadyTime = &now + // } + // } } func (t *clusterComponentStatusTransformer) isClusterComponentPodsReady(phase appsv1.ClusterComponentPhase) bool { @@ -132,7 +131,7 @@ func (t *clusterComponentStatusTransformer) isClusterComponentPodsReady(phase ap return slices.Contains(podsReadyPhases, phase) } -func clusterComponentPhaseTransitionMsg(phase appsv1alpha1.ClusterComponentPhase) string { +func clusterComponentPhaseTransitionMsg(phase appsv1.ClusterComponentPhase) string { if len(phase) == 0 { return "" } diff --git a/controllers/apps/transformer_cluster_component_test.go b/controllers/apps/transformer_cluster_component_test.go index 9c7638cdebb..4fb298d52c3 100644 --- a/controllers/apps/transformer_cluster_component_test.go +++ b/controllers/apps/transformer_cluster_component_test.go @@ -32,7 +32,6 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" "github.com/apecloud/kubeblocks/pkg/controller/component" "github.com/apecloud/kubeblocks/pkg/controller/graph" "github.com/apecloud/kubeblocks/pkg/controller/model" @@ -206,13 +205,13 @@ var _ = Describe("cluster component transformer test", func() { AfterEach(func() {}) - newDAG := func(graphCli model.GraphClient, cluster *appsv1alpha1.Cluster) *graph.DAG { + newDAG := func(graphCli model.GraphClient, cluster *appsv1.Cluster) *graph.DAG { d := graph.NewDAG() graphCli.Root(d, cluster, cluster, model.ActionStatusPtr()) return d } - buildCompSpecs := func(clusterDef *appsv1.ClusterDefinition, cluster *appsv1alpha1.Cluster) []*appsv1alpha1.ClusterComponentSpec { + buildCompSpecs := func(clusterDef *appsv1.ClusterDefinition, cluster *appsv1.Cluster) []*appsv1.ClusterComponentSpec { apiTransformer := ClusterAPINormalizationTransformer{} compSpecs, err := apiTransformer.buildCompSpecs4Topology(clusterDef, cluster) Expect(err).Should(BeNil()) @@ -220,7 +219,7 @@ var _ = Describe("cluster component transformer test", func() { } mockCompObj := func(transCtx *clusterTransformContext, compName string, setters ...func(*appsv1.Component)) *appsv1.Component { - var compSpec *appsv1alpha1.ClusterComponentSpec + var compSpec *appsv1.ClusterComponentSpec for i, spec := range transCtx.ComponentSpecs { if spec.Name == compName { compSpec = transCtx.ComponentSpecs[i] diff --git a/controllers/apps/transformer_cluster_deletion.go b/controllers/apps/transformer_cluster_deletion.go index cd217cd909f..ca5c49affb5 100644 --- a/controllers/apps/transformer_cluster_deletion.go +++ b/controllers/apps/transformer_cluster_deletion.go @@ -57,20 +57,20 @@ func (t *clusterDeletionTransformer) Transform(ctx graph.TransformContext, dag * graphCli, _ := transCtx.Client.(model.GraphClient) - transCtx.Cluster.Status.Phase = appsv1alpha1.DeletingClusterPhase + transCtx.Cluster.Status.Phase = kbappsv1.DeletingClusterPhase // list all kinds to be deleted based on v1alpha1.TerminationPolicyType var toDeleteNamespacedKinds, toDeleteNonNamespacedKinds []client.ObjectList switch cluster.Spec.TerminationPolicy { - case appsv1alpha1.DoNotTerminate: + case kbappsv1.DoNotTerminate: transCtx.EventRecorder.Eventf(cluster, corev1.EventTypeWarning, "DoNotTerminate", "spec.terminationPolicy %s is preventing deletion.", cluster.Spec.TerminationPolicy) return graph.ErrPrematureStop - case appsv1alpha1.Halt: + case kbappsv1.Halt: toDeleteNamespacedKinds, toDeleteNonNamespacedKinds = kindsForHalt() - case appsv1alpha1.Delete: + case kbappsv1.Delete: toDeleteNamespacedKinds, toDeleteNonNamespacedKinds = kindsForDelete() - case appsv1alpha1.WipeOut: + case kbappsv1.WipeOut: toDeleteNamespacedKinds, toDeleteNonNamespacedKinds = kindsForWipeOut() } @@ -189,7 +189,7 @@ func kindsForWipeOut() ([]client.ObjectList, []client.ObjectList) { } // shouldSkipObjOwnedByComp is used to judge whether the object owned by component should be skipped when deleting the cluster -func shouldSkipObjOwnedByComp(obj client.Object, cluster appsv1alpha1.Cluster) bool { +func shouldSkipObjOwnedByComp(obj client.Object, cluster kbappsv1.Cluster) bool { ownByComp := isOwnedByComp(obj) if !ownByComp { // if the object is not owned by component, it should not be skipped diff --git a/controllers/apps/transformer_cluster_deletion_test.go b/controllers/apps/transformer_cluster_deletion_test.go index a2820ece9e3..bd143af2a2a 100644 --- a/controllers/apps/transformer_cluster_deletion_test.go +++ b/controllers/apps/transformer_cluster_deletion_test.go @@ -42,7 +42,7 @@ var _ = Describe("clusterDeletionTransformer", func() { reader client.Reader dag *graph.DAG clusterDef *appsv1.ClusterDefinition - cluster *appsv1alpha1.Cluster + cluster *appsv1.Cluster ) newDag := func(graphCli model.GraphClient) *graph.DAG { diff --git a/controllers/apps/transformer_cluster_halt.go b/controllers/apps/transformer_cluster_halt.go index a6c564d86f6..2e547063cc4 100644 --- a/controllers/apps/transformer_cluster_halt.go +++ b/controllers/apps/transformer_cluster_halt.go @@ -25,7 +25,7 @@ import ( corev1 "k8s.io/api/core/v1" "sigs.k8s.io/controller-runtime/pkg/client" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" "github.com/apecloud/kubeblocks/pkg/constant" "github.com/apecloud/kubeblocks/pkg/controller/graph" "github.com/apecloud/kubeblocks/pkg/controller/model" @@ -38,7 +38,7 @@ var _ graph.Transformer = &clusterHaltTransformer{} func (t *clusterHaltTransformer) Transform(ctx graph.TransformContext, dag *graph.DAG) error { transCtx, _ := ctx.(*clusterTransformContext) cluster := transCtx.OrigCluster - if !cluster.IsDeleting() || cluster.Spec.TerminationPolicy != appsv1alpha1.Halt { + if !cluster.IsDeleting() || cluster.Spec.TerminationPolicy != appsv1.Halt { return nil } @@ -60,6 +60,6 @@ func haltPreserveKinds() []client.ObjectList { // preserveClusterObjects preserves the objects owned by the cluster when the cluster is being deleted func preserveClusterObjects(ctx context.Context, cli client.Reader, graphCli model.GraphClient, dag *graph.DAG, - cluster *appsv1alpha1.Cluster, ml client.MatchingLabels, toPreserveKinds []client.ObjectList) error { + cluster *appsv1.Cluster, ml client.MatchingLabels, toPreserveKinds []client.ObjectList) error { return preserveObjects(ctx, cli, graphCli, dag, cluster, ml, toPreserveKinds, constant.DBClusterFinalizerName, constant.LastAppliedClusterAnnotationKey) } diff --git a/controllers/apps/transformer_cluster_halt_recovering.go b/controllers/apps/transformer_cluster_halt_recovering.go index bd1a4df0c54..d2d5cdc1213 100644 --- a/controllers/apps/transformer_cluster_halt_recovering.go +++ b/controllers/apps/transformer_cluster_halt_recovering.go @@ -28,7 +28,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/client" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" "github.com/apecloud/kubeblocks/pkg/constant" "github.com/apecloud/kubeblocks/pkg/controller/graph" ) @@ -81,14 +81,14 @@ func (t *clusterHaltRecoveryTransformer) Transform(ctx graph.TransformContext, d l, ok := pvcList.Items[0].Annotations[constant.LastAppliedClusterAnnotationKey] if !ok || l == "" { return emitError(metav1.Condition{ - Type: appsv1alpha1.ConditionTypeHaltRecovery, + Type: appsv1.ConditionTypeHaltRecovery, Reason: "UncleanedResources", Message: fmt.Sprintf("found uncleaned resources, requires manual deletion, check with `kubectl -n %s get pvc,secret,cm -l %s=%s`", cluster.Namespace, constant.AppInstanceLabelKey, cluster.Name), }) } - lc := &appsv1alpha1.Cluster{} + lc := &appsv1.Cluster{} if err := json.Unmarshal([]byte(l), lc); err != nil { return newRequeueError(requeueDuration, err.Error()) } @@ -101,7 +101,7 @@ func (t *clusterHaltRecoveryTransformer) Transform(ctx graph.TransformContext, d // check clusterDefRef equality if cluster.Spec.ClusterDefRef != lc.Spec.ClusterDefRef { return emitError(metav1.Condition{ - Type: appsv1alpha1.ConditionTypeHaltRecovery, + Type: appsv1.ConditionTypeHaltRecovery, Reason: "HaltRecoveryFailed", Message: fmt.Sprintf("not equal to last applied cluster.spec.clusterDefRef %s", lc.Spec.ClusterDefRef), }) @@ -110,7 +110,7 @@ func (t *clusterHaltRecoveryTransformer) Transform(ctx graph.TransformContext, d // check component len equality if l := len(lc.Spec.ComponentSpecs); l != len(cluster.Spec.ComponentSpecs) { return emitError(metav1.Condition{ - Type: appsv1alpha1.ConditionTypeHaltRecovery, + Type: appsv1.ConditionTypeHaltRecovery, Reason: "HaltRecoveryFailed", Message: fmt.Sprintf("inconsistent spec.componentSpecs counts to last applied cluster.spec.componentSpecs (len=%d)", l), }) @@ -126,7 +126,7 @@ func (t *clusterHaltRecoveryTransformer) Transform(ctx graph.TransformContext, d } if comp.ComponentDefRef != lastUsedComp.ComponentDefRef { return emitError(metav1.Condition{ - Type: appsv1alpha1.ConditionTypeHaltRecovery, + Type: appsv1.ConditionTypeHaltRecovery, Reason: "HaltRecoveryFailed", Message: fmt.Sprintf("not equal to last applied cluster.spec.componentSpecs[%s].componentDefRef=%s", comp.Name, lastUsedComp.ComponentDefRef), @@ -134,7 +134,7 @@ func (t *clusterHaltRecoveryTransformer) Transform(ctx graph.TransformContext, d } if comp.Replicas != lastUsedComp.Replicas { return emitError(metav1.Condition{ - Type: appsv1alpha1.ConditionTypeHaltRecovery, + Type: appsv1.ConditionTypeHaltRecovery, Reason: "HaltRecoveryFailed", Message: fmt.Sprintf("not equal to last applied cluster.spec.componentSpecs[%s].replicas=%d", comp.Name, lastUsedComp.Replicas), @@ -150,7 +150,7 @@ func (t *clusterHaltRecoveryTransformer) Transform(ctx graph.TransformContext, d if !isVolumeClaimTemplatesEqual(comp.VolumeClaimTemplates, lastUsedComp.VolumeClaimTemplates) { objJSON, _ := json.Marshal(&lastUsedComp.VolumeClaimTemplates) return emitError(metav1.Condition{ - Type: appsv1alpha1.ConditionTypeHaltRecovery, + Type: appsv1.ConditionTypeHaltRecovery, Reason: "HaltRecoveryFailed", Message: fmt.Sprintf("not equal to last applied cluster.spec.componentSpecs[%s].volumeClaimTemplates=%s; add '%s=true' annotation to void this check", comp.Name, objJSON, constant.HaltRecoveryAllowInconsistentResAnnotKey), @@ -160,7 +160,7 @@ func (t *clusterHaltRecoveryTransformer) Transform(ctx graph.TransformContext, d if !isResourceRequirementsEqual(comp.Resources, lastUsedComp.Resources) { objJSON, _ := json.Marshal(&lastUsedComp.Resources) return emitError(metav1.Condition{ - Type: appsv1alpha1.ConditionTypeHaltRecovery, + Type: appsv1.ConditionTypeHaltRecovery, Reason: "HaltRecoveryFailed", Message: fmt.Sprintf("not equal to last applied cluster.spec.componentSpecs[%s].resources=%s; add '%s=true' annotation to void this check", comp.Name, objJSON, constant.HaltRecoveryAllowInconsistentResAnnotKey), @@ -172,7 +172,7 @@ func (t *clusterHaltRecoveryTransformer) Transform(ctx graph.TransformContext, d } if !found { return emitError(metav1.Condition{ - Type: appsv1alpha1.ConditionTypeHaltRecovery, + Type: appsv1.ConditionTypeHaltRecovery, Reason: "HaltRecoveryFailed", Message: fmt.Sprintf("cluster.spec.componentSpecs[%s] not found in last applied cluster", comp.Name), diff --git a/controllers/apps/transformer_cluster_init.go b/controllers/apps/transformer_cluster_init.go index d869ab8b22e..d42c800ffbf 100644 --- a/controllers/apps/transformer_cluster_init.go +++ b/controllers/apps/transformer_cluster_init.go @@ -20,13 +20,13 @@ along with this program. If not, see . package apps import ( - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" "github.com/apecloud/kubeblocks/pkg/controller/graph" "github.com/apecloud/kubeblocks/pkg/controller/model" ) type clusterInitTransformer struct { - cluster *appsv1alpha1.Cluster + cluster *appsv1.Cluster } var _ graph.Transformer = &clusterInitTransformer{} diff --git a/controllers/apps/transformer_cluster_load_resources.go b/controllers/apps/transformer_cluster_load_resources.go index 46f6578990f..7dc9394ca4c 100644 --- a/controllers/apps/transformer_cluster_load_resources.go +++ b/controllers/apps/transformer_cluster_load_resources.go @@ -25,7 +25,6 @@ import ( "k8s.io/apimachinery/pkg/types" appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" "github.com/apecloud/kubeblocks/pkg/controller/graph" "github.com/apecloud/kubeblocks/pkg/generics" ) @@ -64,7 +63,7 @@ func (t *clusterLoadRefResourcesTransformer) Transform(ctx graph.TransformContex return nil } -func (t *clusterLoadRefResourcesTransformer) apiValidation(cluster *appsv1alpha1.Cluster) error { +func (t *clusterLoadRefResourcesTransformer) apiValidation(cluster *appsv1.Cluster) error { if withClusterTopology(cluster) || withClusterUserDefined(cluster) || withClusterLegacyDefinition(cluster) || @@ -75,7 +74,7 @@ func (t *clusterLoadRefResourcesTransformer) apiValidation(cluster *appsv1alpha1 cluster.Spec.ClusterDefRef, cluster.Spec.Topology, clusterCompCnt(cluster), legacyClusterCompCnt(cluster), withClusterSimplifiedAPI(cluster)) } -func (t *clusterLoadRefResourcesTransformer) checkNUpdateClusterTopology(transCtx *clusterTransformContext, cluster *appsv1alpha1.Cluster) error { +func (t *clusterLoadRefResourcesTransformer) checkNUpdateClusterTopology(transCtx *clusterTransformContext, cluster *appsv1.Cluster) error { clusterTopology := referredClusterTopology(transCtx.ClusterDef, cluster.Spec.Topology) if clusterTopology == nil { return fmt.Errorf("specified cluster topology not found: %s", cluster.Spec.Topology) @@ -96,7 +95,7 @@ func (t *clusterLoadRefResourcesTransformer) checkNUpdateClusterTopology(transCt return nil } -func loadNCheckClusterDefinition(transCtx *clusterTransformContext, cluster *appsv1alpha1.Cluster) error { +func loadNCheckClusterDefinition(transCtx *clusterTransformContext, cluster *appsv1.Cluster) error { var cd *appsv1.ClusterDefinition if len(cluster.Spec.ClusterDefRef) > 0 { cd = &appsv1.ClusterDefinition{} @@ -122,20 +121,20 @@ func loadNCheckClusterDefinition(transCtx *clusterTransformContext, cluster *app return nil } -func withClusterTopology(cluster *appsv1alpha1.Cluster) bool { +func withClusterTopology(cluster *appsv1.Cluster) bool { return len(cluster.Spec.ClusterDefRef) > 0 && legacyClusterCompCnt(cluster) == 0 && !compatibleUserDefinedInNewAPI(cluster) } -func withClusterUserDefined(cluster *appsv1alpha1.Cluster) bool { +func withClusterUserDefined(cluster *appsv1.Cluster) bool { return (len(cluster.Spec.ClusterDefRef) == 0 && len(cluster.Spec.Topology) == 0 && legacyClusterCompCnt(cluster) == 0) || compatibleUserDefinedInNewAPI(cluster) } -func withClusterLegacyDefinition(cluster *appsv1alpha1.Cluster) bool { +func withClusterLegacyDefinition(cluster *appsv1.Cluster) bool { return len(cluster.Spec.ClusterDefRef) > 0 && len(cluster.Spec.Topology) == 0 && clusterCompCnt(cluster) == legacyClusterCompCnt(cluster) } -func withClusterSimplifiedAPI(cluster *appsv1alpha1.Cluster) bool { +func withClusterSimplifiedAPI(cluster *appsv1.Cluster) bool { return cluster.Spec.Replicas != nil || !cluster.Spec.Resources.CPU.IsZero() || !cluster.Spec.Resources.Memory.IsZero() || @@ -146,25 +145,25 @@ func withClusterSimplifiedAPI(cluster *appsv1alpha1.Cluster) bool { len(cluster.Spec.AvailabilityPolicy) > 0 } -func clusterCompCnt(cluster *appsv1alpha1.Cluster) int { - return clusterCompCntWithFunc(cluster, func(spec appsv1alpha1.ClusterComponentSpec) bool { return true }) +func clusterCompCnt(cluster *appsv1.Cluster) int { + return clusterCompCntWithFunc(cluster, func(spec appsv1.ClusterComponentSpec) bool { return true }) } -func legacyClusterCompCnt(cluster *appsv1alpha1.Cluster) int { - isLegacyComp := func(spec appsv1alpha1.ClusterComponentSpec) bool { +func legacyClusterCompCnt(cluster *appsv1.Cluster) int { + isLegacyComp := func(spec appsv1.ClusterComponentSpec) bool { return len(spec.ComponentDefRef) != 0 && len(spec.ComponentDef) == 0 } return clusterCompCntWithFunc(cluster, isLegacyComp) } -func hasLegacyClusterCompSet(cluster *appsv1alpha1.Cluster) bool { - hasLegacyCompSet := func(spec appsv1alpha1.ClusterComponentSpec) bool { +func hasLegacyClusterCompSet(cluster *appsv1.Cluster) bool { + hasLegacyCompSet := func(spec appsv1.ClusterComponentSpec) bool { return len(spec.ComponentDefRef) != 0 } return clusterCompCntWithFunc(cluster, hasLegacyCompSet) > 0 } -func clusterCompCntWithFunc(cluster *appsv1alpha1.Cluster, match func(spec appsv1alpha1.ClusterComponentSpec) bool) int { +func clusterCompCntWithFunc(cluster *appsv1.Cluster, match func(spec appsv1.ClusterComponentSpec) bool) int { cnt := generics.CountFunc(cluster.Spec.ComponentSpecs, match) for _, sharding := range cluster.Spec.ShardingSpecs { if match(sharding.Template) { @@ -174,7 +173,7 @@ func clusterCompCntWithFunc(cluster *appsv1alpha1.Cluster, match func(spec appsv return cnt } -func compatibleUserDefinedInNewAPI(cluster *appsv1alpha1.Cluster) bool { +func compatibleUserDefinedInNewAPI(cluster *appsv1.Cluster) bool { // clusterDefinitionRef = xxxxx, componentDefRef = abc, componentDef = xyz return len(cluster.Spec.ClusterDefRef) > 0 && len(cluster.Spec.Topology) == 0 && legacyClusterCompCnt(cluster) == 0 && hasLegacyClusterCompSet(cluster) } diff --git a/controllers/apps/transformer_cluster_load_resources_test.go b/controllers/apps/transformer_cluster_load_resources_test.go index 78e5dae3f78..aa38d943d82 100644 --- a/controllers/apps/transformer_cluster_load_resources_test.go +++ b/controllers/apps/transformer_cluster_load_resources_test.go @@ -23,18 +23,18 @@ import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" ) var _ = Describe("cluster load resources transformer test", func() { Context("cluster api validation", func() { It("with cluster topology", func() { By("explicitly specify topology") - cluster := &appsv1alpha1.Cluster{ - Spec: appsv1alpha1.ClusterSpec{ + cluster := &appsv1.Cluster{ + Spec: appsv1.ClusterSpec{ ClusterDefRef: "clusterdef", Topology: "topology", - ComponentSpecs: []appsv1alpha1.ClusterComponentSpec{ + ComponentSpecs: []appsv1.ClusterComponentSpec{ { ComponentDef: "compdef", }, @@ -63,9 +63,9 @@ var _ = Describe("cluster load resources transformer test", func() { It("with cluster user defined", func() { By("specify componentDef only") - cluster := &appsv1alpha1.Cluster{ - Spec: appsv1alpha1.ClusterSpec{ - ComponentSpecs: []appsv1alpha1.ClusterComponentSpec{ + cluster := &appsv1.Cluster{ + Spec: appsv1.ClusterSpec{ + ComponentSpecs: []appsv1.ClusterComponentSpec{ { ComponentDef: "compdef", }, @@ -88,10 +88,10 @@ var _ = Describe("cluster load resources transformer test", func() { }) It("with cluster legacy definition", func() { - cluster := &appsv1alpha1.Cluster{ - Spec: appsv1alpha1.ClusterSpec{ + cluster := &appsv1.Cluster{ + Spec: appsv1.ClusterSpec{ ClusterDefRef: "clusterdef", - ComponentSpecs: []appsv1alpha1.ClusterComponentSpec{ + ComponentSpecs: []appsv1.ClusterComponentSpec{ { ComponentDefRef: "compdef", }, diff --git a/controllers/apps/transformer_cluster_ownership.go b/controllers/apps/transformer_cluster_ownership.go index f19920bd741..78a6bfe7228 100644 --- a/controllers/apps/transformer_cluster_ownership.go +++ b/controllers/apps/transformer_cluster_ownership.go @@ -23,7 +23,7 @@ import ( rbacv1 "k8s.io/api/rbac/v1" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" "github.com/apecloud/kubeblocks/pkg/constant" "github.com/apecloud/kubeblocks/pkg/controller/graph" "github.com/apecloud/kubeblocks/pkg/controller/model" @@ -40,7 +40,7 @@ func (f *clusterOwnershipTransformer) Transform(ctx graph.TransformContext, dag graphCli, _ := transCtx.Client.(model.GraphClient) cluster := transCtx.Cluster - objects := graphCli.FindAll(dag, &appsv1alpha1.Cluster{}, &model.HaveDifferentTypeWithOption{}) + objects := graphCli.FindAll(dag, &appsv1.Cluster{}, &model.HaveDifferentTypeWithOption{}) controllerutil.AddFinalizer(cluster, constant.DBClusterFinalizerName) for _, object := range objects { diff --git a/controllers/apps/transformer_cluster_restore.go b/controllers/apps/transformer_cluster_restore.go index 1c70afb75f6..0cb6543a926 100644 --- a/controllers/apps/transformer_cluster_restore.go +++ b/controllers/apps/transformer_cluster_restore.go @@ -23,7 +23,7 @@ import ( "k8s.io/apimachinery/pkg/util/json" "sigs.k8s.io/controller-runtime/pkg/client" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" "github.com/apecloud/kubeblocks/pkg/constant" "github.com/apecloud/kubeblocks/pkg/controller/component" "github.com/apecloud/kubeblocks/pkg/controller/graph" @@ -108,7 +108,7 @@ func (c *clusterRestoreTransformer) Transform(ctx graph.TransformContext, dag *g } } // if component needs to do post ready restore after cluster is running, annotate component - if c.Cluster.Status.Phase == appsv1alpha1.RunningClusterPhase { + if c.Cluster.Status.Phase == appsv1.RunningClusterPhase { for _, compSpec := range c.Cluster.Spec.ComponentSpecs { backupSource, ok := backupMap[compSpec.Name] if !ok { @@ -118,7 +118,7 @@ func (c *clusterRestoreTransformer) Transform(ctx graph.TransformContext, dag *g continue } compObjName := component.FullName(c.Cluster.Name, compSpec.Name) - compObj := &appsv1alpha1.Component{} + compObj := &appsv1.Component{} if err = c.Client.Get(c.GetContext(), client.ObjectKey{Name: compObjName, Namespace: c.Cluster.Namespace}, compObj); err != nil { return err } @@ -132,7 +132,7 @@ func (c *clusterRestoreTransformer) Transform(ctx graph.TransformContext, dag *g func (c *clusterRestoreTransformer) cleanupRestoreAnnotationForSharding(dag *graph.DAG, shardName string, restoreDoneForShardComponents bool) error { - if c.Cluster.Status.Phase != appsv1alpha1.RunningClusterPhase { + if c.Cluster.Status.Phase != appsv1.RunningClusterPhase { return nil } if !restoreDoneForShardComponents { @@ -149,7 +149,7 @@ func (c *clusterRestoreTransformer) cleanupRestoreAnnotationForSharding(dag *gra return nil } -func (c *clusterRestoreTransformer) annotateComponent(dag *graph.DAG, compObj *appsv1alpha1.Component) { +func (c *clusterRestoreTransformer) annotateComponent(dag *graph.DAG, compObj *appsv1.Component) { // annotate component to reconcile for postReady restore. compObj.Labels[constant.ReconcileAnnotationKey] = "DoPostReadyRestore" graphCli, _ := c.Client.(model.GraphClient) diff --git a/controllers/apps/transformer_cluster_secret.go b/controllers/apps/transformer_cluster_secret.go index b2cfd766044..24657b93f9e 100644 --- a/controllers/apps/transformer_cluster_secret.go +++ b/controllers/apps/transformer_cluster_secret.go @@ -23,7 +23,7 @@ import ( corev1 "k8s.io/api/core/v1" "sigs.k8s.io/controller-runtime/pkg/client" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" "github.com/apecloud/kubeblocks/pkg/controller/graph" "github.com/apecloud/kubeblocks/pkg/controller/model" ) @@ -39,7 +39,7 @@ func (c *clusterSecretTransformer) Transform(ctx graph.TransformContext, dag *gr var secrets, noneClusterObjects []client.Object secrets = graphCli.FindAll(dag, &corev1.Secret{}) - noneClusterObjects = graphCli.FindAll(dag, &appsv1alpha1.Cluster{}, &model.HaveDifferentTypeWithOption{}) + noneClusterObjects = graphCli.FindAll(dag, &appsv1.Cluster{}, &model.HaveDifferentTypeWithOption{}) for _, secret := range secrets { if graphCli.IsAction(dag, secret, model.ActionUpdatePtr()) { graphCli.Noop(dag, secret) diff --git a/controllers/apps/transformer_cluster_service.go b/controllers/apps/transformer_cluster_service.go index 91de1aa106c..2d244956101 100644 --- a/controllers/apps/transformer_cluster_service.go +++ b/controllers/apps/transformer_cluster_service.go @@ -31,7 +31,6 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" "github.com/apecloud/kubeblocks/pkg/common" "github.com/apecloud/kubeblocks/pkg/constant" "github.com/apecloud/kubeblocks/pkg/controller/builder" @@ -67,7 +66,7 @@ func (t *clusterServiceTransformer) Transform(ctx graph.TransformContext, dag *g return err } - handleServiceFunc := func(origSvc, genSvc *appsv1alpha1.ClusterService) error { + handleServiceFunc := func(origSvc, genSvc *appsv1.ClusterService) error { service, err := t.buildService(transCtx, cluster, origSvc, genSvc) if err != nil { return err @@ -110,13 +109,13 @@ func (t *clusterServiceTransformer) Transform(ctx graph.TransformContext, dag *g } // convertLegacyClusterCompSpecServices converts legacy services defined in Cluster.Spec.ComponentSpecs[x].Services to Cluster.Spec.Services. -func (t *clusterServiceTransformer) convertLegacyClusterCompSpecServices(transCtx *clusterTransformContext, cluster *appsv1alpha1.Cluster) ([]appsv1alpha1.ClusterService, error) { +func (t *clusterServiceTransformer) convertLegacyClusterCompSpecServices(transCtx *clusterTransformContext, cluster *appsv1.Cluster) ([]appsv1.ClusterService, error) { // don't convert services if the cluster has defined in new API if withClusterTopology(cluster) || withClusterUserDefined(cluster) { return nil, nil } - convertedServices := make([]appsv1alpha1.ClusterService, 0) + convertedServices := make([]appsv1.ClusterService, 0) for _, compSpec := range transCtx.ComponentSpecs { if len(compSpec.Services) == 0 { continue @@ -135,8 +134,8 @@ func (t *clusterServiceTransformer) convertLegacyClusterCompSpecServices(transCt // } // // for _, item := range compSpec.Services { - // legacyService := &appsv1alpha1.ClusterService{ - // Service: appsv1alpha1.Service{ + // legacyService := &appsv1.ClusterService{ + // Service: appsv1.Service{ // Name: constant.GenerateClusterServiceName(cluster.Name, item.Name), // ServiceName: constant.GenerateClusterServiceName(cluster.Name, item.Name), // Annotations: item.Annotations, @@ -163,8 +162,8 @@ func (t *clusterServiceTransformer) convertLegacyClusterCompSpecServices(transCt return convertedServices, nil } -func (t *clusterServiceTransformer) buildService(transCtx *clusterTransformContext, cluster *appsv1alpha1.Cluster, - origSvc, genSvc *appsv1alpha1.ClusterService) (*corev1.Service, error) { +func (t *clusterServiceTransformer) buildService(transCtx *clusterTransformContext, cluster *appsv1.Cluster, + origSvc, genSvc *appsv1.ClusterService) (*corev1.Service, error) { var ( namespace = cluster.Namespace clusterName = cluster.Name @@ -202,13 +201,13 @@ func (t *clusterServiceTransformer) buildService(transCtx *clusterTransformConte } func (t *clusterServiceTransformer) genMultiServiceIfNeed(transCtx *clusterTransformContext, - cluster *appsv1alpha1.Cluster, clusterService *appsv1alpha1.ClusterService) ([]*appsv1alpha1.ClusterService, error) { + cluster *appsv1.Cluster, clusterService *appsv1.ClusterService) ([]*appsv1.ClusterService, error) { if len(clusterService.ShardingSelector) == 0 || len(cluster.Spec.ShardingSpecs) == 0 { - return []*appsv1alpha1.ClusterService{clusterService}, nil + return []*appsv1.ClusterService{clusterService}, nil } shardingName := "" - shardingCompSpecs := make([]*appsv1alpha1.ClusterComponentSpec, 0) + shardingCompSpecs := make([]*appsv1.ClusterComponentSpec, 0) for k, v := range transCtx.ShardingComponentSpecs { if k != clusterService.ShardingSelector { continue @@ -222,10 +221,10 @@ func (t *clusterServiceTransformer) genMultiServiceIfNeed(transCtx *clusterTrans } if !enableShardService(cluster, shardingName) { - return []*appsv1alpha1.ClusterService{clusterService}, nil + return []*appsv1.ClusterService{clusterService}, nil } - shardOrdinalClusterSvcs := make([]*appsv1alpha1.ClusterService, 0, len(shardingCompSpecs)) + shardOrdinalClusterSvcs := make([]*appsv1.ClusterService, 0, len(shardingCompSpecs)) for _, shardingCompSpec := range shardingCompSpecs { svc := clusterService.DeepCopy() svc.Name = fmt.Sprintf("%s-%s", clusterService.Name, shardingCompSpec.Name) @@ -239,7 +238,7 @@ func (t *clusterServiceTransformer) genMultiServiceIfNeed(transCtx *clusterTrans return shardOrdinalClusterSvcs, nil } -func (t *clusterServiceTransformer) builtinSelector(cluster *appsv1alpha1.Cluster) map[string]string { +func (t *clusterServiceTransformer) builtinSelector(cluster *appsv1.Cluster) map[string]string { selectors := map[string]string{ constant.AppManagedByLabelKey: constant.AppName, constant.AppInstanceLabelKey: cluster.Name, @@ -247,7 +246,7 @@ func (t *clusterServiceTransformer) builtinSelector(cluster *appsv1alpha1.Cluste return selectors } -func (t *clusterServiceTransformer) checkComponent(transCtx *clusterTransformContext, clusterService *appsv1alpha1.ClusterService) (*appsv1.ComponentDefinition, error) { +func (t *clusterServiceTransformer) checkComponent(transCtx *clusterTransformContext, clusterService *appsv1.ClusterService) (*appsv1.ComponentDefinition, error) { compName := clusterService.ComponentSelector for _, compSpec := range transCtx.ComponentSpecs { if compSpec.Name == compName { @@ -261,7 +260,7 @@ func (t *clusterServiceTransformer) checkComponent(transCtx *clusterTransformCon return nil, fmt.Errorf("the component of service selector is not exist, service: %s, component: %s", clusterService.Name, compName) } -func (t *clusterServiceTransformer) checkComponentRoles(compDef *appsv1.ComponentDefinition, clusterService *appsv1alpha1.ClusterService) error { +func (t *clusterServiceTransformer) checkComponentRoles(compDef *appsv1.ComponentDefinition, clusterService *appsv1.ClusterService) error { definedRoles := make(map[string]bool) for _, role := range compDef.Spec.Roles { definedRoles[strings.ToLower(role.Name)] = true @@ -273,7 +272,7 @@ func (t *clusterServiceTransformer) checkComponentRoles(compDef *appsv1.Componen } func (t *clusterServiceTransformer) listOwnedClusterServices(transCtx *clusterTransformContext, - cluster *appsv1alpha1.Cluster) (map[string]*corev1.Service, error) { + cluster *appsv1.Cluster) (map[string]*corev1.Service, error) { svcList := &corev1.ServiceList{} labels := client.MatchingLabels(constant.GetClusterWellKnownLabels(cluster.Name)) if err := transCtx.Client.List(transCtx.Context, svcList, labels, client.InNamespace(cluster.Namespace)); err != nil { @@ -378,7 +377,7 @@ func resolveServiceDefaultFields(obj, objCopy *corev1.ServiceSpec) { // return true, nil // } -func enableShardService(cluster *appsv1alpha1.Cluster, shardingName string) bool { +func enableShardService(cluster *appsv1.Cluster, shardingName string) bool { enableShardSvcList, ok := cluster.Annotations[constant.ShardSvcAnnotationKey] if !ok || !slices.Contains(strings.Split(enableShardSvcList, ","), shardingName) { return false @@ -387,7 +386,7 @@ func enableShardService(cluster *appsv1alpha1.Cluster, shardingName string) bool } // genComponentSelector generates component selector for sharding service. -func genComponentSelector(origSvc, genSvc *appsv1alpha1.ClusterService) string { +func genComponentSelector(origSvc, genSvc *appsv1.ClusterService) string { origSvcPrefix := constant.GenerateShardingNameSvcPrefix(origSvc.Name) if strings.HasPrefix(genSvc.Name, origSvcPrefix) { return strings.TrimPrefix(genSvc.Name, origSvcPrefix) diff --git a/controllers/apps/transformer_cluster_status.go b/controllers/apps/transformer_cluster_status.go index 077041ee13f..8f210bfa6e6 100644 --- a/controllers/apps/transformer_cluster_status.go +++ b/controllers/apps/transformer_cluster_status.go @@ -24,7 +24,7 @@ import ( "k8s.io/apimachinery/pkg/api/meta" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" "github.com/apecloud/kubeblocks/pkg/controller/graph" "github.com/apecloud/kubeblocks/pkg/controller/model" ) @@ -69,7 +69,7 @@ func (t *clusterStatusTransformer) Transform(ctx graph.TransformContext, dag *gr return nil } -func (t *clusterStatusTransformer) markClusterDagStatusAction(graphCli model.GraphClient, dag *graph.DAG, origCluster, cluster *appsv1alpha1.Cluster) { +func (t *clusterStatusTransformer) markClusterDagStatusAction(graphCli model.GraphClient, dag *graph.DAG, origCluster, cluster *appsv1.Cluster) { if vertex := graphCli.FindMatchedVertex(dag, cluster); vertex != nil { // check if the component needs to do other action. ov, _ := vertex.(*model.ObjectVertex) @@ -80,7 +80,7 @@ func (t *clusterStatusTransformer) markClusterDagStatusAction(graphCli model.Gra graphCli.Status(dag, origCluster, cluster) } -func (t *clusterStatusTransformer) reconcileClusterPhase(cluster *appsv1alpha1.Cluster) { +func (t *clusterStatusTransformer) reconcileClusterPhase(cluster *appsv1.Cluster) { var ( isAllComponentCreating = true isAllComponentRunning = true @@ -90,7 +90,7 @@ func (t *clusterStatusTransformer) reconcileClusterPhase(cluster *appsv1alpha1.C isAllComponentFailed = true hasComponentAbnormalOrFailed = false ) - isPhaseIn := func(phase appsv1alpha1.ClusterComponentPhase, phases ...appsv1alpha1.ClusterComponentPhase) bool { + isPhaseIn := func(phase appsv1.ClusterComponentPhase, phases ...appsv1.ClusterComponentPhase) bool { for _, p := range phases { if p == phase { return true @@ -100,57 +100,57 @@ func (t *clusterStatusTransformer) reconcileClusterPhase(cluster *appsv1alpha1.C } for _, status := range cluster.Status.Components { phase := status.Phase - if !isPhaseIn(phase, appsv1alpha1.CreatingClusterCompPhase) { + if !isPhaseIn(phase, appsv1.CreatingClusterCompPhase) { isAllComponentCreating = false } - if !isPhaseIn(phase, appsv1alpha1.RunningClusterCompPhase) { + if !isPhaseIn(phase, appsv1.RunningClusterCompPhase) { isAllComponentRunning = false } - if !isPhaseIn(phase, appsv1alpha1.CreatingClusterCompPhase, - appsv1alpha1.RunningClusterCompPhase, - appsv1alpha1.UpdatingClusterCompPhase) { + if !isPhaseIn(phase, appsv1.CreatingClusterCompPhase, + appsv1.RunningClusterCompPhase, + appsv1.UpdatingClusterCompPhase) { isAllComponentWorking = false } - if isPhaseIn(phase, appsv1alpha1.StoppingClusterCompPhase) { + if isPhaseIn(phase, appsv1.StoppingClusterCompPhase) { hasComponentStopping = true } - if !isPhaseIn(phase, appsv1alpha1.StoppedClusterCompPhase) { + if !isPhaseIn(phase, appsv1.StoppedClusterCompPhase) { isAllComponentStopped = false } - if !isPhaseIn(phase, appsv1alpha1.FailedClusterCompPhase) { + if !isPhaseIn(phase, appsv1.FailedClusterCompPhase) { isAllComponentFailed = false } - if isPhaseIn(phase, appsv1alpha1.AbnormalClusterCompPhase, appsv1alpha1.FailedClusterCompPhase) { + if isPhaseIn(phase, appsv1.AbnormalClusterCompPhase, appsv1.FailedClusterCompPhase) { hasComponentAbnormalOrFailed = true } } switch { case isAllComponentRunning: - if cluster.Status.Phase != appsv1alpha1.RunningClusterPhase { + if cluster.Status.Phase != appsv1.RunningClusterPhase { t.syncClusterPhaseToRunning(cluster) } case isAllComponentCreating: - cluster.Status.Phase = appsv1alpha1.CreatingClusterPhase + cluster.Status.Phase = appsv1.CreatingClusterPhase case isAllComponentWorking: - cluster.Status.Phase = appsv1alpha1.UpdatingClusterPhase + cluster.Status.Phase = appsv1.UpdatingClusterPhase case isAllComponentStopped: - if cluster.Status.Phase != appsv1alpha1.StoppedClusterPhase { + if cluster.Status.Phase != appsv1.StoppedClusterPhase { t.syncClusterPhaseToStopped(cluster) } case hasComponentStopping: - cluster.Status.Phase = appsv1alpha1.StoppingClusterPhase + cluster.Status.Phase = appsv1.StoppingClusterPhase case isAllComponentFailed: - cluster.Status.Phase = appsv1alpha1.FailedClusterPhase + cluster.Status.Phase = appsv1.FailedClusterPhase case hasComponentAbnormalOrFailed: - cluster.Status.Phase = appsv1alpha1.AbnormalClusterPhase + cluster.Status.Phase = appsv1.AbnormalClusterPhase default: // nothing } } // reconcileClusterStatus reconciles phase and conditions of the Cluster.status. -func (t *clusterStatusTransformer) reconcileClusterStatus(transCtx *clusterTransformContext, cluster *appsv1alpha1.Cluster) error { +func (t *clusterStatusTransformer) reconcileClusterStatus(transCtx *clusterTransformContext, cluster *appsv1.Cluster) error { if len(cluster.Status.Components) == 0 { return nil } @@ -178,14 +178,14 @@ func (t *clusterStatusTransformer) reconcileClusterStatus(transCtx *clusterTrans } // removeInvalidCompStatus removes the invalid component of status.components which is deleted from spec.components. -func (t *clusterStatusTransformer) removeInvalidCompStatus(transCtx *clusterTransformContext, cluster *appsv1alpha1.Cluster) { +func (t *clusterStatusTransformer) removeInvalidCompStatus(transCtx *clusterTransformContext, cluster *appsv1.Cluster) { // removes deleted components and keeps created components by simplified API t.removeCompStatus(cluster, transCtx.ComponentSpecs) } // removeInnerCompStatus removes the component of status.components which is created by simplified API. -func (t *clusterStatusTransformer) removeInnerCompStatus(transCtx *clusterTransformContext, cluster *appsv1alpha1.Cluster) { - compSpecs := make([]*appsv1alpha1.ClusterComponentSpec, 0) +func (t *clusterStatusTransformer) removeInnerCompStatus(transCtx *clusterTransformContext, cluster *appsv1.Cluster) { + compSpecs := make([]*appsv1.ClusterComponentSpec, 0) for i := range cluster.Spec.ComponentSpecs { compSpecs = append(compSpecs, &cluster.Spec.ComponentSpecs[i]) } @@ -197,8 +197,8 @@ func (t *clusterStatusTransformer) removeInnerCompStatus(transCtx *clusterTransf } // removeCompStatus removes the component of status.components which is not in comp specs. -func (t *clusterStatusTransformer) removeCompStatus(cluster *appsv1alpha1.Cluster, compSpecs []*appsv1alpha1.ClusterComponentSpec) { - tmpCompsStatus := map[string]appsv1alpha1.ClusterComponentStatus{} +func (t *clusterStatusTransformer) removeCompStatus(cluster *appsv1.Cluster, compSpecs []*appsv1.ClusterComponentSpec) { + tmpCompsStatus := map[string]appsv1.ClusterComponentStatus{} compsStatus := cluster.Status.Components for _, v := range compSpecs { if compStatus, ok := compsStatus[v.Name]; ok { @@ -210,22 +210,22 @@ func (t *clusterStatusTransformer) removeCompStatus(cluster *appsv1alpha1.Cluste } // doAnalysisAndUpdateSynchronizer analyzes the Cluster.Status.Components and updates the results to the synchronizer. -func (t *clusterStatusTransformer) doAnalysisAndUpdateSynchronizer(cluster *appsv1alpha1.Cluster) { +func (t *clusterStatusTransformer) doAnalysisAndUpdateSynchronizer(cluster *appsv1.Cluster) { // analysis the status of components and calculate the cluster phase. for k, v := range cluster.Status.Components { - if v.PodsReady == nil || !*v.PodsReady { - t.replicasNotReadyCompNames[k] = struct{}{} - t.notReadyCompNames[k] = struct{}{} - } + // if v.PodsReady == nil || !*v.PodsReady { + // t.replicasNotReadyCompNames[k] = struct{}{} + // t.notReadyCompNames[k] = struct{}{} + // } switch v.Phase { - case appsv1alpha1.AbnormalClusterCompPhase, appsv1alpha1.FailedClusterCompPhase: + case appsv1.AbnormalClusterCompPhase, appsv1.FailedClusterCompPhase: t.notReadyCompNames[k] = struct{}{} } } } // syncReadyConditionForCluster syncs the cluster conditions with ClusterReady and ReplicasReady type. -func (t *clusterStatusTransformer) syncReadyConditionForCluster(cluster *appsv1alpha1.Cluster) { +func (t *clusterStatusTransformer) syncReadyConditionForCluster(cluster *appsv1.Cluster) { if len(t.replicasNotReadyCompNames) == 0 { // if all replicas of cluster are ready, set ReasonAllReplicasReady to status.conditions readyCondition := newAllReplicasPodsReadyConditions() @@ -240,12 +240,12 @@ func (t *clusterStatusTransformer) syncReadyConditionForCluster(cluster *appsv1a } // syncClusterPhaseToRunning syncs the cluster phase to Running. -func (t *clusterStatusTransformer) syncClusterPhaseToRunning(cluster *appsv1alpha1.Cluster) { - cluster.Status.Phase = appsv1alpha1.RunningClusterPhase +func (t *clusterStatusTransformer) syncClusterPhaseToRunning(cluster *appsv1.Cluster) { + cluster.Status.Phase = appsv1.RunningClusterPhase meta.SetStatusCondition(&cluster.Status.Conditions, newClusterReadyCondition(cluster.Name)) } // syncClusterPhaseToStopped syncs the cluster phase to Stopped. -func (t *clusterStatusTransformer) syncClusterPhaseToStopped(cluster *appsv1alpha1.Cluster) { - cluster.Status.Phase = appsv1alpha1.StoppedClusterPhase +func (t *clusterStatusTransformer) syncClusterPhaseToStopped(cluster *appsv1.Cluster) { + cluster.Status.Phase = appsv1.StoppedClusterPhase } diff --git a/controllers/apps/transformer_component_custom_volumes.go b/controllers/apps/transformer_component_custom_volumes.go index a4cee937bd0..38bceb47b87 100644 --- a/controllers/apps/transformer_component_custom_volumes.go +++ b/controllers/apps/transformer_component_custom_volumes.go @@ -25,7 +25,7 @@ import ( "golang.org/x/exp/slices" corev1 "k8s.io/api/core/v1" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" "github.com/apecloud/kubeblocks/pkg/controller/graph" "github.com/apecloud/kubeblocks/pkg/controller/model" ) @@ -67,7 +67,7 @@ func newSourceFromResource(name string, source any) corev1.Volume { return volume } -func doBuildCustomVolumes(podSpec *corev1.PodSpec, cluster *appsv1alpha1.Cluster, componentName string, namespace string) error { +func doBuildCustomVolumes(podSpec *corev1.PodSpec, cluster *appsv1.Cluster, componentName string, namespace string) error { comp := cluster.Spec.GetComponentByName(componentName) if comp == nil || comp.UserResourceRefs == nil { return nil @@ -85,7 +85,7 @@ func doBuildCustomVolumes(podSpec *corev1.PodSpec, cluster *appsv1alpha1.Cluster return nil } -func buildVolumeMountForContainers(podSpec *corev1.PodSpec, resourceRefs appsv1alpha1.UserResourceRefs) { +func buildVolumeMountForContainers(podSpec *corev1.PodSpec, resourceRefs appsv1.UserResourceRefs) { for _, configMap := range resourceRefs.ConfigMapRefs { newVolumeMount(podSpec, configMap.ResourceMeta) } @@ -94,7 +94,7 @@ func buildVolumeMountForContainers(podSpec *corev1.PodSpec, resourceRefs appsv1a } } -func newVolumeMount(podSpec *corev1.PodSpec, res appsv1alpha1.ResourceMeta) { +func newVolumeMount(podSpec *corev1.PodSpec, res appsv1.ResourceMeta) { for i := range podSpec.Containers { container := &podSpec.Containers[i] if !slices.Contains(res.AsVolumeFrom, container.Name) { diff --git a/controllers/apps/transformer_component_deletion.go b/controllers/apps/transformer_component_deletion.go index d40d3862862..24a7d4392c7 100644 --- a/controllers/apps/transformer_component_deletion.go +++ b/controllers/apps/transformer_component_deletion.go @@ -90,17 +90,17 @@ func (t *componentDeletionTransformer) handleCompDeleteWhenScaleIn(transCtx *com // handleCompDeleteWhenClusterDelete handles the component deletion when the cluster is being deleted, the sub-resources owned by the component depends on the cluster's TerminationPolicy. func (t *componentDeletionTransformer) handleCompDeleteWhenClusterDelete(transCtx *componentTransformContext, graphCli model.GraphClient, - dag *graph.DAG, cluster *appsv1alpha1.Cluster, comp *appsv1.Component, matchLabels map[string]string) error { + dag *graph.DAG, cluster *appsv1.Cluster, comp *appsv1.Component, matchLabels map[string]string) error { var ( toPreserveKinds, toDeleteKinds []client.ObjectList ) switch cluster.Spec.TerminationPolicy { - case appsv1alpha1.Halt: + case appsv1.Halt: toPreserveKinds = compOwnedPreserveKinds() toDeleteKinds = kindsForCompHalt() - case appsv1alpha1.Delete: + case appsv1.Delete: toDeleteKinds = kindsForCompDelete() - case appsv1alpha1.WipeOut: + case appsv1.WipeOut: toDeleteKinds = kindsForCompWipeOut() } @@ -159,12 +159,12 @@ func (t *componentDeletionTransformer) deleteCompResources(transCtx *componentTr return graph.ErrPrematureStop } -func (t *componentDeletionTransformer) getCluster(transCtx *componentTransformContext, comp *appsv1.Component) (*appsv1alpha1.Cluster, error) { +func (t *componentDeletionTransformer) getCluster(transCtx *componentTransformContext, comp *appsv1.Component) (*appsv1.Cluster, error) { clusterName, err := component.GetClusterName(comp) if err != nil { return nil, err } - cluster := &appsv1alpha1.Cluster{} + cluster := &appsv1.Cluster{} err = transCtx.Client.Get(transCtx.Context, types.NamespacedName{Name: clusterName, Namespace: comp.Namespace}, cluster) if err != nil { return nil, errors.New(fmt.Sprintf("failed to get cluster %s: %v", clusterName, err)) diff --git a/controllers/apps/transformer_component_load_resources.go b/controllers/apps/transformer_component_load_resources.go index b1552905699..1c71b2d09f3 100644 --- a/controllers/apps/transformer_component_load_resources.go +++ b/controllers/apps/transformer_component_load_resources.go @@ -24,7 +24,7 @@ import ( "k8s.io/apimachinery/pkg/types" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" "github.com/apecloud/kubeblocks/pkg/controller/component" "github.com/apecloud/kubeblocks/pkg/controller/graph" ictrlutil "github.com/apecloud/kubeblocks/pkg/controllerutil" @@ -49,7 +49,7 @@ func (t *componentLoadResourcesTransformer) Transform(ctx graph.TransformContext return newRequeueError(requeueDuration, err.Error()) } - cluster := &appsv1alpha1.Cluster{} + cluster := &appsv1.Cluster{} err = transCtx.Client.Get(transCtx.Context, types.NamespacedName{Name: clusterName, Namespace: comp.Namespace}, cluster) if err != nil { return newRequeueError(requeueDuration, err.Error()) diff --git a/controllers/apps/transformer_component_pre_terminate.go b/controllers/apps/transformer_component_pre_terminate.go index 732c08cbbe2..71c58482b9b 100644 --- a/controllers/apps/transformer_component_pre_terminate.go +++ b/controllers/apps/transformer_component_pre_terminate.go @@ -26,7 +26,6 @@ import ( "k8s.io/apimachinery/pkg/types" appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" "github.com/apecloud/kubeblocks/pkg/controller/component" "github.com/apecloud/kubeblocks/pkg/controller/component/lifecycle" "github.com/apecloud/kubeblocks/pkg/controller/graph" @@ -139,7 +138,7 @@ func (t *componentPreTerminateTransformer) synthesizedComponent(transCtx *compon if err != nil { return nil, newRequeueError(requeueDuration, err.Error()) } - cluster := &appsv1alpha1.Cluster{} + cluster := &appsv1.Cluster{} err = cli.Get(ctx, types.NamespacedName{Name: clusterName, Namespace: comp.Namespace}, cluster) if err != nil { return nil, newRequeueError(requeueDuration, err.Error()) diff --git a/controllers/apps/transformer_component_rbac.go b/controllers/apps/transformer_component_rbac.go index c9286d606a4..af528478a8b 100644 --- a/controllers/apps/transformer_component_rbac.go +++ b/controllers/apps/transformer_component_rbac.go @@ -109,7 +109,7 @@ func isLifecycleActionsEnabled(compDef *appsv1.ComponentDefinition) bool { return compDef.Spec.LifecycleActions != nil } -func isDataProtectionEnabled(backupTpl *appsv1alpha1.BackupPolicyTemplate, cluster *appsv1alpha1.Cluster, comp *appsv1.Component) bool { +func isDataProtectionEnabled(backupTpl *appsv1alpha1.BackupPolicyTemplate, cluster *appsv1.Cluster, comp *appsv1.Component) bool { if backupTpl != nil && len(comp.Spec.CompDef) > 0 { for _, policy := range backupTpl.Spec.BackupPolicies { for _, compDef := range policy.ComponentDefs { @@ -284,7 +284,7 @@ func buildServiceAccount(transCtx *componentTransformContext) (*corev1.ServiceAc return saObj, volumeProtectionEnable, nil } -func buildRoleBinding(cluster *appsv1alpha1.Cluster, comp *appsv1.Component, serviceAccountName string) (*rbacv1.RoleBinding, error) { +func buildRoleBinding(cluster *appsv1.Cluster, comp *appsv1.Component, serviceAccountName string) (*rbacv1.RoleBinding, error) { roleBinding := factory.BuildRoleBinding(cluster, serviceAccountName) if err := setCompOwnershipNFinalizer(comp, roleBinding); err != nil { return nil, err diff --git a/controllers/apps/transformer_component_rbac_test.go b/controllers/apps/transformer_component_rbac_test.go index 6a8469eeb54..6f75cdf46c9 100644 --- a/controllers/apps/transformer_component_rbac_test.go +++ b/controllers/apps/transformer_component_rbac_test.go @@ -27,7 +27,6 @@ import ( "k8s.io/apimachinery/pkg/types" appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" "github.com/apecloud/kubeblocks/pkg/constant" "github.com/apecloud/kubeblocks/pkg/controller/component" @@ -49,7 +48,7 @@ var _ = Describe("object rbac transformer test.", func() { var dag *graph.DAG var graphCli model.GraphClient var transformer graph.Transformer - var cluster *appsv1alpha1.Cluster + var cluster *appsv1.Cluster var compDefObj *appsv1.ComponentDefinition var compObj *appsv1.Component var saKey types.NamespacedName @@ -180,7 +179,7 @@ var _ = Describe("object rbac transformer test.", func() { }) }) -func mockDAG(graphCli model.GraphClient, cluster *appsv1alpha1.Cluster) *graph.DAG { +func mockDAG(graphCli model.GraphClient, cluster *appsv1.Cluster) *graph.DAG { d := graph.NewDAG() graphCli.Root(d, cluster, cluster, model.ActionStatusPtr()) its := &workloads.InstanceSet{} diff --git a/controllers/apps/transformer_component_status.go b/controllers/apps/transformer_component_status.go index 9052c267371..7295e58c851 100644 --- a/controllers/apps/transformer_component_status.go +++ b/controllers/apps/transformer_component_status.go @@ -55,7 +55,7 @@ const ( type componentStatusTransformer struct { client.Client - cluster *appsv1alpha1.Cluster + cluster *appsv1.Cluster comp *appsv1.Component synthesizeComp *component.SynthesizedComponent dag *graph.DAG diff --git a/controllers/apps/transformer_component_tls_test.go b/controllers/apps/transformer_component_tls_test.go index bbe3d8256ad..ee4f481fda5 100644 --- a/controllers/apps/transformer_component_tls_test.go +++ b/controllers/apps/transformer_component_tls_test.go @@ -32,7 +32,6 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" appsv1beta1 "github.com/apecloud/kubeblocks/apis/apps/v1beta1" cfgcore "github.com/apecloud/kubeblocks/pkg/configuration/core" "github.com/apecloud/kubeblocks/pkg/constant" @@ -129,9 +128,9 @@ var _ = Describe("TLS self-signed cert function", func() { }) It("should create the cluster when secret referenced exist", func() { - tlsIssuer := &appsv1alpha1.Issuer{ - Name: appsv1alpha1.IssuerUserProvided, - SecretRef: &appsv1alpha1.TLSSecretRef{ + tlsIssuer := &appsv1.Issuer{ + Name: appsv1.IssuerUserProvided, + SecretRef: &appsv1.TLSSecretRef{ Name: userProvidedTLSSecretObj.Name, CA: "ca.crt", Cert: "tls.crt", @@ -167,7 +166,7 @@ var _ = Describe("TLS self-signed cert function", func() { clusterKey := client.ObjectKeyFromObject(clusterObj) Eventually(k8sClient.Get(ctx, clusterKey, clusterObj)).Should(Succeed()) Eventually(testapps.GetClusterObservedGeneration(&testCtx, clusterKey)).Should(BeEquivalentTo(1)) - Eventually(testapps.GetClusterPhase(&testCtx, clusterKey)).Should(Equal(appsv1alpha1.CreatingClusterPhase)) + Eventually(testapps.GetClusterPhase(&testCtx, clusterKey)).Should(Equal(appsv1.CreatingClusterPhase)) itsList := testk8s.ListAndCheckInstanceSet(&testCtx, clusterKey) its := itsList.Items[0] @@ -192,7 +191,7 @@ var _ = Describe("TLS self-signed cert function", func() { Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(clusterObj), clusterObj)).Should(Succeed()) patch := client.MergeFrom(clusterObj.DeepCopy()) clusterObj.Spec.ComponentSpecs[0].TLS = true - clusterObj.Spec.ComponentSpecs[0].Issuer = &appsv1alpha1.Issuer{Name: appsv1alpha1.IssuerKubeBlocks} + clusterObj.Spec.ComponentSpecs[0].Issuer = &appsv1.Issuer{Name: appsv1.IssuerKubeBlocks} Expect(k8sClient.Patch(ctx, clusterObj, patch)).Should(Succeed()) Eventually(hasTLSSettings).Should(BeTrue()) @@ -207,12 +206,12 @@ var _ = Describe("TLS self-signed cert function", func() { Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(clusterObj), clusterObj)).Should(Succeed()) patch = client.MergeFrom(clusterObj.DeepCopy()) clusterObj.Spec.ComponentSpecs[0].TLS = true - clusterObj.Spec.ComponentSpecs[0].Issuer = &appsv1alpha1.Issuer{Name: appsv1alpha1.IssuerKubeBlocks} + clusterObj.Spec.ComponentSpecs[0].Issuer = &appsv1.Issuer{Name: appsv1.IssuerKubeBlocks} Expect(k8sClient.Patch(ctx, clusterObj, patch)).Should(Succeed()) Eventually(hasTLSSettings).Should(BeTrue()) - testapps.DeleteObject(&testCtx, clusterKey, &appsv1alpha1.Cluster{}) - Eventually(testapps.CheckObjExists(&testCtx, clusterKey, &appsv1alpha1.Cluster{}, false)).Should(Succeed()) + testapps.DeleteObject(&testCtx, clusterKey, &appsv1.Cluster{}) + Eventually(testapps.CheckObjExists(&testCtx, clusterKey, &appsv1.Cluster{}, false)).Should(Succeed()) }) }) diff --git a/controllers/apps/transformer_component_workload.go b/controllers/apps/transformer_component_workload.go index 65d97f5fae9..7823654b90e 100644 --- a/controllers/apps/transformer_component_workload.go +++ b/controllers/apps/transformer_component_workload.go @@ -37,7 +37,6 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" "github.com/apecloud/kubeblocks/pkg/constant" "github.com/apecloud/kubeblocks/pkg/controller/component" @@ -58,7 +57,7 @@ type componentWorkloadTransformer struct { type componentWorkloadOps struct { cli client.Client reqCtx intctrlutil.RequestCtx - cluster *appsv1alpha1.Cluster + cluster *appsv1.Cluster synthesizeComp *component.SynthesizedComponent dag *graph.DAG @@ -173,7 +172,7 @@ func (t *componentWorkloadTransformer) stopWorkload(protoITS *workloads.Instance } func (t *componentWorkloadTransformer) handleUpdate(reqCtx intctrlutil.RequestCtx, cli model.GraphClient, dag *graph.DAG, - cluster *appsv1alpha1.Cluster, synthesizeComp *component.SynthesizedComponent, runningITS, protoITS *workloads.InstanceSet) error { + cluster *appsv1.Cluster, synthesizeComp *component.SynthesizedComponent, runningITS, protoITS *workloads.InstanceSet) error { if !isCompStopped(synthesizeComp) { // postpone the update of the workload until the component is back to running. if err := t.handleWorkloadUpdate(reqCtx, dag, cluster, synthesizeComp, runningITS, protoITS); err != nil { @@ -190,7 +189,7 @@ func (t *componentWorkloadTransformer) handleUpdate(reqCtx intctrlutil.RequestCt } func (t *componentWorkloadTransformer) handleWorkloadUpdate(reqCtx intctrlutil.RequestCtx, dag *graph.DAG, - cluster *appsv1alpha1.Cluster, synthesizeComp *component.SynthesizedComponent, obj, its *workloads.InstanceSet) error { + cluster *appsv1.Cluster, synthesizeComp *component.SynthesizedComponent, obj, its *workloads.InstanceSet) error { cwo, err := newComponentWorkloadOps(reqCtx, t.Client, cluster, synthesizeComp, obj, its, dag) if err != nil { return err @@ -918,7 +917,7 @@ func buildInstanceSetPlacementAnnotation(comp *appsv1.Component, its *workloads. func newComponentWorkloadOps(reqCtx intctrlutil.RequestCtx, cli client.Client, - cluster *appsv1alpha1.Cluster, + cluster *appsv1.Cluster, synthesizeComp *component.SynthesizedComponent, runningITS *workloads.InstanceSet, protoITS *workloads.InstanceSet, diff --git a/controllers/dataprotection/backup_controller.go b/controllers/dataprotection/backup_controller.go index 29df6d75c06..90c36cec363 100644 --- a/controllers/dataprotection/backup_controller.go +++ b/controllers/dataprotection/backup_controller.go @@ -46,7 +46,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/log" "sigs.k8s.io/controller-runtime/pkg/reconcile" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" + kbappsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" dpv1alpha1 "github.com/apecloud/kubeblocks/apis/dataprotection/v1alpha1" "github.com/apecloud/kubeblocks/pkg/constant" intctrlutil "github.com/apecloud/kubeblocks/pkg/controllerutil" @@ -625,13 +625,13 @@ func (r *BackupReconciler) checkIsCompletedDuringRunning(reqCtx intctrlutil.Requ // check if target cluster exits clusterName := backup.Labels[constant.AppInstanceLabelKey] if clusterName != "" { - cluster := &appsv1alpha1.Cluster{} + cluster := &kbappsv1.Cluster{} backupTargetExists, err = intctrlutil.CheckResourceExists(reqCtx.Ctx, r.Client, client.ObjectKey{Name: clusterName, Namespace: backup.Namespace}, cluster) if err != nil { return false, err } - backupTargetIsStoppedOrDeleting = cluster.IsDeleting() || cluster.Status.Phase == appsv1alpha1.StoppedClusterPhase + backupTargetIsStoppedOrDeleting = cluster.IsDeleting() || cluster.Status.Phase == kbappsv1.StoppedClusterPhase } // if backup target exists, and it is not deleting or stopped, check if the schedule is enabled. if backupTargetExists && !backupTargetIsStoppedOrDeleting { @@ -824,7 +824,7 @@ func updateBackupStatusByActionStatus(backupStatus *dpv1alpha1.BackupStatus) { } } -func setEncryptedSystemAccountsAnnotation(request *dpbackup.Request, cluster *appsv1alpha1.Cluster) error { +func setEncryptedSystemAccountsAnnotation(request *dpbackup.Request, cluster *kbappsv1.Cluster) error { usernameKey := constant.AccountNameForSecret passwordKey := constant.AccountPasswdForSecret isSystemAccountSecret := func(secret *corev1.Secret) bool { @@ -868,9 +868,9 @@ func setEncryptedSystemAccountsAnnotation(request *dpbackup.Request, cluster *ap } // getClusterObjectString gets the cluster object and convert it to string. -func getClusterObjectString(cluster *appsv1alpha1.Cluster) (*string, error) { +func getClusterObjectString(cluster *kbappsv1.Cluster) (*string, error) { // maintain only the cluster's spec and name/namespace. - newCluster := &appsv1alpha1.Cluster{ + newCluster := &kbappsv1.Cluster{ Spec: cluster.Spec, ObjectMeta: metav1.ObjectMeta{ Namespace: cluster.Namespace, @@ -888,7 +888,7 @@ func getClusterObjectString(cluster *appsv1alpha1.Cluster) (*string, error) { } // setClusterSnapshotAnnotation sets the snapshot of cluster to the backup's annotations. -func setClusterSnapshotAnnotation(request *dpbackup.Request, cluster *appsv1alpha1.Cluster) error { +func setClusterSnapshotAnnotation(request *dpbackup.Request, cluster *kbappsv1.Cluster) error { if request.Backup.Annotations == nil { request.Backup.Annotations = map[string]string{} } diff --git a/controllers/dataprotection/backup_controller_test.go b/controllers/dataprotection/backup_controller_test.go index 983a943f5a7..e78b631de6d 100644 --- a/controllers/dataprotection/backup_controller_test.go +++ b/controllers/dataprotection/backup_controller_test.go @@ -37,7 +37,7 @@ import ( "k8s.io/utils/pointer" "sigs.k8s.io/controller-runtime/pkg/client" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" dpv1alpha1 "github.com/apecloud/kubeblocks/apis/dataprotection/v1alpha1" "github.com/apecloud/kubeblocks/pkg/constant" intctrlutil "github.com/apecloud/kubeblocks/pkg/controllerutil" @@ -101,7 +101,7 @@ var _ = Describe("Backup Controller test", func() { var ( backupPolicy *dpv1alpha1.BackupPolicy repoPVCName string - cluster *appsv1alpha1.Cluster + cluster *appsv1.Cluster pvcName string targetPod *corev1.Pod ) @@ -1041,7 +1041,7 @@ var _ = Describe("Backup Controller test", func() { var ( backupPolicy *dpv1alpha1.BackupPolicy repoPVCName string - cluster *appsv1alpha1.Cluster + cluster *appsv1.Cluster ) BeforeEach(func() { diff --git a/controllers/dataprotection/utils.go b/controllers/dataprotection/utils.go index f1c0e5493ad..12de1a6205e 100644 --- a/controllers/dataprotection/utils.go +++ b/controllers/dataprotection/utils.go @@ -38,7 +38,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/reconcile" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" dpv1alpha1 "github.com/apecloud/kubeblocks/apis/dataprotection/v1alpha1" "github.com/apecloud/kubeblocks/pkg/constant" "github.com/apecloud/kubeblocks/pkg/controller/multicluster" @@ -215,12 +215,12 @@ func GetTargetPods(reqCtx intctrlutil.RequestCtx, // getCluster gets the cluster and will ignore the error. func getCluster(ctx context.Context, cli client.Client, - targetPod *corev1.Pod) *appsv1alpha1.Cluster { + targetPod *corev1.Pod) *appsv1.Cluster { clusterName := targetPod.Labels[constant.AppInstanceLabelKey] if len(clusterName) == 0 { return nil } - cluster := &appsv1alpha1.Cluster{} + cluster := &appsv1.Cluster{} if err := cli.Get(ctx, client.ObjectKey{ Namespace: targetPod.Namespace, Name: clusterName, @@ -234,7 +234,7 @@ func getCluster(ctx context.Context, // listObjectsOfCluster list the objects of the cluster by labels. func listObjectsOfCluster(ctx context.Context, cli client.Client, - cluster *appsv1alpha1.Cluster, + cluster *appsv1.Cluster, object client.ObjectList) (client.ObjectList, error) { labels := constant.GetClusterWellKnownLabels(cluster.Name) if err := cli.List(ctx, object, client.InNamespace(cluster.Namespace), client.MatchingLabels(labels)); err != nil { diff --git a/controllers/experimental/nodecountscaler_controller.go b/controllers/experimental/nodecountscaler_controller.go index 03be4aa43d7..dafa1b4d6ae 100644 --- a/controllers/experimental/nodecountscaler_controller.go +++ b/controllers/experimental/nodecountscaler_controller.go @@ -29,7 +29,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/log" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" experimental "github.com/apecloud/kubeblocks/apis/experimental/v1alpha1" "github.com/apecloud/kubeblocks/pkg/controller/kubebuilderx" ) @@ -72,6 +72,6 @@ func (r *NodeCountScalerReconciler) SetupWithManager(mgr ctrl.Manager) error { return ctrl.NewControllerManagedBy(mgr). For(&experimental.NodeCountScaler{}). Watches(&corev1.Node{}, &nodeScalingHandler{r.Client}). - Watches(&appsv1alpha1.Cluster{}, &clusterHandler{r.Client}). + Watches(&appsv1.Cluster{}, &clusterHandler{r.Client}). Complete(r) } diff --git a/controllers/experimental/reconciler_scale_target_cluster.go b/controllers/experimental/reconciler_scale_target_cluster.go index 33b4f38d9a6..f492d97480d 100644 --- a/controllers/experimental/reconciler_scale_target_cluster.go +++ b/controllers/experimental/reconciler_scale_target_cluster.go @@ -26,7 +26,7 @@ import ( corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" experimental "github.com/apecloud/kubeblocks/apis/experimental/v1alpha1" "github.com/apecloud/kubeblocks/pkg/controller/builder" "github.com/apecloud/kubeblocks/pkg/controller/kubebuilderx" @@ -49,7 +49,7 @@ func (r *scaleTargetClusterReconciler) Reconcile(tree *kubebuilderx.ObjectTree) if err != nil { return kubebuilderx.Continue, err } - cluster, _ := object.(*appsv1alpha1.Cluster) + cluster, _ := object.(*appsv1.Cluster) nodes := tree.List(&corev1.Node{}) // TODO(free6om): filter nodes that satisfy pod template spec of each component (by nodeSelector, nodeAffinity&nodeAntiAffinity, tolerations) desiredReplicas := int32(len(nodes)) diff --git a/controllers/experimental/reconciler_scale_target_cluster_test.go b/controllers/experimental/reconciler_scale_target_cluster_test.go index ae6420ee084..a980fcb7a50 100644 --- a/controllers/experimental/reconciler_scale_target_cluster_test.go +++ b/controllers/experimental/reconciler_scale_target_cluster_test.go @@ -26,7 +26,7 @@ import ( corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" experimentalv1alpha1 "github.com/apecloud/kubeblocks/apis/experimental/v1alpha1" "github.com/apecloud/kubeblocks/pkg/controller/builder" "github.com/apecloud/kubeblocks/pkg/controller/kubebuilderx" @@ -53,7 +53,7 @@ var _ = Describe("scale target cluster reconciler test", func() { Expect(newNCS.Status.LastScaleTime.Compare(beforeReconcile.Time)).Should(BeNumerically(">=", 0)) object, err := tree.Get(builder.NewClusterBuilder(newNCS.Namespace, newNCS.Spec.TargetClusterName).GetObject()) Expect(err).Should(BeNil()) - newCluster, ok := object.(*appsv1alpha1.Cluster) + newCluster, ok := object.(*appsv1.Cluster) Expect(ok).Should(BeTrue()) nodes := tree.List(&corev1.Node{}) desiredReplicas := int32(len(nodes)) diff --git a/controllers/experimental/suite_test.go b/controllers/experimental/suite_test.go index fe706753c9a..8675c7196c1 100644 --- a/controllers/experimental/suite_test.go +++ b/controllers/experimental/suite_test.go @@ -31,7 +31,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/log/zap" //+kubebuilder:scaffold:imports - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" experimentalv1alpha1 "github.com/apecloud/kubeblocks/apis/experimental/v1alpha1" workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" "github.com/apecloud/kubeblocks/pkg/constant" @@ -61,7 +61,7 @@ func mockTestTree() *kubebuilderx.ObjectTree { SetTargetComponentNames(componentNames). GetObject() - specs := []appsv1alpha1.ClusterComponentSpec{ + specs := []appsv1.ClusterComponentSpec{ { Name: componentNames[0], }, @@ -102,7 +102,7 @@ var _ = BeforeSuite(func() { logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))) model.AddScheme(experimentalv1alpha1.AddToScheme) - model.AddScheme(appsv1alpha1.AddToScheme) + model.AddScheme(appsv1.AddToScheme) model.AddScheme(workloads.AddToScheme) //+kubebuilder:scaffold:scheme diff --git a/controllers/experimental/tree_loader.go b/controllers/experimental/tree_loader.go index 1b9cb35e669..d27af5065c0 100644 --- a/controllers/experimental/tree_loader.go +++ b/controllers/experimental/tree_loader.go @@ -29,7 +29,7 @@ import ( ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" experimental "github.com/apecloud/kubeblocks/apis/experimental/v1alpha1" workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" "github.com/apecloud/kubeblocks/pkg/constant" @@ -49,7 +49,7 @@ func (t *treeLoader) Load(ctx context.Context, reader client.Reader, req ctrl.Re } scaler, _ := root.(*experimental.NodeCountScaler) key := types.NamespacedName{Namespace: scaler.Namespace, Name: scaler.Spec.TargetClusterName} - cluster := &appsv1alpha1.Cluster{} + cluster := &appsv1.Cluster{} if err = reader.Get(ctx, key, cluster); err != nil { return nil, err } diff --git a/controllers/experimental/tree_loader_test.go b/controllers/experimental/tree_loader_test.go index 7a6f6eb9185..845ebb64a60 100644 --- a/controllers/experimental/tree_loader_test.go +++ b/controllers/experimental/tree_loader_test.go @@ -32,7 +32,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" logf "sigs.k8s.io/controller-runtime/pkg/log" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" experimental "github.com/apecloud/kubeblocks/apis/experimental/v1alpha1" workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" "github.com/apecloud/kubeblocks/pkg/constant" @@ -74,8 +74,8 @@ var _ = Describe("tree loader test", func() { return nil }).Times(1) k8sMock.EXPECT(). - Get(gomock.Any(), gomock.Any(), &appsv1alpha1.Cluster{}, gomock.Any()). - DoAndReturn(func(_ context.Context, objKey client.ObjectKey, obj *appsv1alpha1.Cluster, _ ...client.GetOption) error { + Get(gomock.Any(), gomock.Any(), &appsv1.Cluster{}, gomock.Any()). + DoAndReturn(func(_ context.Context, objKey client.ObjectKey, obj *appsv1.Cluster, _ ...client.GetOption) error { *obj = *cluster return nil }).Times(1) diff --git a/controllers/extensions/addon_controller_stages.go b/controllers/extensions/addon_controller_stages.go index f41bd32fff7..9e37c95514a 100644 --- a/controllers/extensions/addon_controller_stages.go +++ b/controllers/extensions/addon_controller_stages.go @@ -40,7 +40,7 @@ import ( ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" extensionsv1alpha1 "github.com/apecloud/kubeblocks/apis/extensions/v1alpha1" "github.com/apecloud/kubeblocks/pkg/constant" intctrlutil "github.com/apecloud/kubeblocks/pkg/controllerutil" @@ -186,7 +186,7 @@ func (r *fetchNDeletionCheckStage) Handle(ctx context.Context) { "Addon is used by cluster, please check") } if res, err := intctrlutil.ValidateReferenceCR(*r.reqCtx, r.reconciler.Client, addon, constant.ClusterDefLabelKey, - recordEvent, &appsv1alpha1.ClusterList{}); res != nil || err != nil { + recordEvent, &appsv1.ClusterList{}); res != nil || err != nil { r.updateResultNErr(res, err) return } diff --git a/controllers/extensions/addon_controller_test.go b/controllers/extensions/addon_controller_test.go index e63ce76ce4e..d5bd7c31ad6 100644 --- a/controllers/extensions/addon_controller_test.go +++ b/controllers/extensions/addon_controller_test.go @@ -42,7 +42,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/metrics/server" "sigs.k8s.io/controller-runtime/pkg/reconcile" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" + kbappsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" extensionsv1alpha1 "github.com/apecloud/kubeblocks/apis/extensions/v1alpha1" "github.com/apecloud/kubeblocks/pkg/constant" "github.com/apecloud/kubeblocks/pkg/generics" @@ -847,7 +847,7 @@ var _ = Describe("Addon controller", func() { GetObject() clusterKey = client.ObjectKeyFromObject(clusterObj) - cluster := &appsv1alpha1.Cluster{} + cluster := &kbappsv1.Cluster{} Eventually(func(g Gomega) { err := testCtx.Cli.Get(ctx, clusterKey, cluster) g.Expect(err).To(Not(HaveOccurred())) @@ -887,7 +887,7 @@ var _ = Describe("Addon controller", func() { GetObject() clusterKey = client.ObjectKeyFromObject(clusterObj) - cluster := &appsv1alpha1.Cluster{} + cluster := &kbappsv1.Cluster{} Eventually(func(g Gomega) { err := testCtx.Cli.Get(ctx, clusterKey, cluster) g.Expect(err).To(Not(HaveOccurred())) diff --git a/controllers/k8score/event_controller_test.go b/controllers/k8score/event_controller_test.go index ae713b72717..3c34232bcb1 100644 --- a/controllers/k8score/event_controller_test.go +++ b/controllers/k8score/event_controller_test.go @@ -34,7 +34,7 @@ import ( "k8s.io/apimachinery/pkg/types" "sigs.k8s.io/controller-runtime/pkg/client" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" "github.com/apecloud/kubeblocks/pkg/constant" "github.com/apecloud/kubeblocks/pkg/controller/builder" @@ -133,7 +133,7 @@ var _ = Describe("Event Controller", func() { WithRandomName(). AddComponent(defaultCompName, compDefObj.GetName()). Create(&testCtx).GetObject() - Eventually(testapps.CheckObjExists(&testCtx, client.ObjectKeyFromObject(clusterObj), &appsv1alpha1.Cluster{}, true)).Should(Succeed()) + Eventually(testapps.CheckObjExists(&testCtx, client.ObjectKeyFromObject(clusterObj), &appsv1.Cluster{}, true)).Should(Succeed()) itsName := fmt.Sprintf("%s-%s", clusterObj.Name, defaultCompName) its := testapps.NewInstanceSetFactory(clusterObj.Namespace, itsName, clusterObj.Name, defaultCompName). diff --git a/deploy/helm/crds/apps.kubeblocks.io_clusters.yaml b/deploy/helm/crds/apps.kubeblocks.io_clusters.yaml index 2cdcc981f4d..8eb9ec1959a 100644 --- a/deploy/helm/crds/apps.kubeblocks.io_clusters.yaml +++ b/deploy/helm/crds/apps.kubeblocks.io_clusters.yaml @@ -89,15 +89,16517 @@ spec: metadata: type: object spec: - description: ClusterSpec defines the desired state of Cluster + description: ClusterSpec defines the desired state of Cluster. properties: - foo: - description: Foo is an example field of Cluster. Edit cluster_types.go - to remove/update + backup: + description: Specifies the backup configuration of the Cluster. + properties: + cronExpression: + description: The cron expression for the schedule. The timezone + is in UTC. See https://en.wikipedia.org/wiki/Cron. + type: string + enabled: + default: false + description: Specifies whether automated backup is enabled for + the Cluster. + type: boolean + method: + description: Specifies the backup method to use, as defined in + backupPolicy. + type: string + pitrEnabled: + default: false + description: Specifies whether to enable point-in-time recovery. + type: boolean + repoName: + description: Specifies the name of the backupRepo. If not set, + the default backupRepo will be used. + type: string + retentionPeriod: + default: 7d + description: "Determines the duration to retain backups. Backups + older than this period are automatically removed.\n\n\nFor example, + RetentionPeriod of `30d` will keep only the backups of last + 30 days.\nSample duration format:\n\n\n- years: \t2y\n- months: + \t6mo\n- days: \t\t30d\n- hours: \t12h\n- minutes: \t30m\n\n\nYou + can also combine the above durations. For example: 30d12h30m.\nDefault + value is 7d." + type: string + startingDeadlineMinutes: + description: |- + Specifies the maximum time in minutes that the system will wait to start a missed backup job. + If the scheduled backup time is missed for any reason, the backup job must start within this deadline. + Values must be between 0 (immediate execution) and 1440 (one day). + format: int64 + maximum: 1440 + minimum: 0 + type: integer + required: + - method + type: object + clusterDefinitionRef: + description: |- + Specifies the name of the ClusterDefinition to use when creating a Cluster. + + + This field enables users to create a Cluster based on a specific ClusterDefinition. + Which, in conjunction with the `topology` field, determine: + + + - The Components to be included in the Cluster. + - The sequences in which the Components are created, updated, and terminate. + + + This facilitates multiple-components management with predefined ClusterDefinition. + + + Users with advanced requirements can bypass this general setting and specify more precise control over + the composition of the Cluster by directly referencing specific ComponentDefinitions for each component + within `componentSpecs[*].componentDef`. + + + If this field is not provided, each component must be explicitly defined in `componentSpecs[*].componentDef`. + + + Note: Once set, this field cannot be modified; it is immutable. + maxLength: 63 + pattern: ^[a-z0-9]([a-z0-9\.\-]*[a-z0-9])?$ + type: string + x-kubernetes-validations: + - message: clusterDefinitionRef is immutable + rule: self == oldSelf + clusterVersionRef: + description: |- + Refers to the ClusterVersion name. + + + Deprecated since v0.9, use ComponentVersion instead. + This field is maintained for backward compatibility and its use is discouraged. + Existing usage should be updated to the current preferred approach to avoid compatibility issues in future releases. + maxLength: 63 + pattern: ^[a-z0-9]([a-z0-9\.\-]*[a-z0-9])?$ + type: string + componentSpecs: + description: |- + Specifies a list of ClusterComponentSpec objects used to define the individual Components that make up a Cluster. + This field allows for detailed configuration of each Component within the Cluster. + + + Note: `shardingSpecs` and `componentSpecs` cannot both be empty; at least one must be defined to configure a Cluster. + items: + description: |- + ClusterComponentSpec defines the specification of a Component within a Cluster. + TODO +kubebuilder:validation:XValidation:rule="!has(oldSelf.componentDefRef) || has(self.componentDefRef)", message="componentDefRef is required once set" + TODO +kubebuilder:validation:XValidation:rule="!has(oldSelf.componentDef) || has(self.componentDef)", message="componentDef is required once set" + properties: + annotations: + additionalProperties: + type: string + description: Specifies Annotations to override or add for underlying + Pods. + type: object + componentDef: + description: |- + References the name of a ComponentDefinition object. + The ComponentDefinition specifies the behavior and characteristics of the Component. + If both `componentDefRef` and `componentDef` are provided, + the `componentDef` will take precedence over `componentDefRef`. + maxLength: 64 + pattern: ^[a-z0-9]([a-z0-9\.\-]*[a-z0-9])?$ + type: string + componentDefRef: + description: |- + References a ClusterComponentDefinition defined in the `clusterDefinition.spec.componentDef` field. + Must comply with the IANA service naming rule. + + + Deprecated since v0.9, + because defining Components in `clusterDefinition.spec.componentDef` field has been deprecated. + This field is replaced by the `componentDef` field, use `componentDef` instead. + This field is maintained for backward compatibility and its use is discouraged. + Existing usage should be updated to the current preferred approach to avoid compatibility issues in future releases. + + + TODO +kubebuilder:validation:XValidation:rule="self == oldSelf",message="componentDefRef is immutable" + maxLength: 22 + pattern: ^[a-z]([a-z0-9\-]*[a-z0-9])?$ + type: string + configs: + description: Specifies the configuration content of a config + template. + items: + description: ClusterComponentConfig represents a config with + its source bound. + properties: + configMap: + description: ConfigMap source for the config. + properties: + defaultMode: + description: |- + defaultMode is optional: mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + items: + description: |- + items if unspecified, each key-value pair in the Data field of the referenced + ConfigMap will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the ConfigMap, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within + a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + 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 + optional: + description: optional specify whether the ConfigMap + or its keys must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + name: + description: The name of the config. + type: string + type: object + type: array + disableExporter: + description: |- + Determines whether metrics exporter information is annotated on the Component's headless Service. + + + If set to true, the following annotations will not be patched into the Service: + + + - "monitor.kubeblocks.io/path" + - "monitor.kubeblocks.io/port" + - "monitor.kubeblocks.io/scheme" + + + These annotations allow the Prometheus installed by KubeBlocks to discover and scrape metrics from the exporter. + type: boolean + enabledLogs: + description: |- + Specifies which types of logs should be collected for the Component. + The log types are defined in the `componentDefinition.spec.logConfigs` field with the LogConfig entries. + + + The elements in the `enabledLogs` array correspond to the names of the LogConfig entries. + For example, if the `componentDefinition.spec.logConfigs` defines LogConfig entries with + names "slow_query_log" and "error_log", + you can enable the collection of these logs by including their names in the `enabledLogs` array: + ```yaml + enabledLogs: + - slow_query_log + - error_log + ``` + items: + type: string + type: array + x-kubernetes-list-type: set + env: + description: |- + List of environment variables to add. + These environment variables will be placed after the environment variables declared in the Pod. + items: + description: EnvVar represents an environment variable present + in a Container. + properties: + name: + description: Name of the environment variable. Must be + a C_IDENTIFIER. + type: string + value: + description: |- + Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in the container and + any service environment variables. If a variable cannot be resolved, + the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless of whether the variable + exists or not. + Defaults to "". + type: string + valueFrom: + description: Source for the environment variable's value. + Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap or + its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the + specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the + exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in the pod's + namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its + key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + instances: + description: |- + Allows for the customization of configuration values for each instance within a Component. + An instance represent a single replica (Pod and associated K8s resources like PVCs, Services, and ConfigMaps). + While instances typically share a common configuration as defined in the ClusterComponentSpec, + they can require unique settings in various scenarios: + + + For example: + - A database Component might require different resource allocations for primary and secondary instances, + with primaries needing more resources. + - During a rolling upgrade, a Component may first update the image for one or a few instances, + and then update the remaining instances after verifying that the updated instances are functioning correctly. + + + InstanceTemplate allows for specifying these unique configurations per instance. + Each instance's name is constructed using the pattern: $(component.name)-$(template.name)-$(ordinal), + starting with an ordinal of 0. + It is crucial to maintain unique names for each InstanceTemplate to avoid conflicts. + + + The sum of replicas across all InstanceTemplates should not exceed the total number of replicas specified for the Component. + Any remaining replicas will be generated using the default template and will follow the default naming rules. + items: + description: InstanceTemplate allows customization of individual + replica configurations in a Component. + properties: + annotations: + additionalProperties: + type: string + description: |- + Specifies a map of key-value pairs to be merged into the Pod's existing annotations. + Existing keys will have their values overwritten, while new keys will be added to the annotations. + type: object + env: + description: |- + Defines Env to override. + Add new or override existing envs. + items: + description: EnvVar represents an environment variable + present in a Container. + properties: + name: + description: Name of the environment variable. Must + be a C_IDENTIFIER. + type: string + value: + description: |- + Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in the container and + any service environment variables. If a variable cannot be resolved, + the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless of whether the variable + exists or not. + Defaults to "". + type: string + valueFrom: + description: Source for the environment variable's + value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select + in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required for + volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format + of the exposed resources, defaults to + "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in the + pod's namespace + properties: + key: + description: The key of the secret to select + from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + image: + description: Specifies an override for the first container's + image in the Pod. + type: string + labels: + additionalProperties: + type: string + description: |- + Specifies a map of key-value pairs that will be merged into the Pod's existing labels. + Values for existing keys will be overwritten, and new keys will be added. + type: object + name: + description: |- + Name specifies the unique name of the instance Pod created using this InstanceTemplate. + This name is constructed by concatenating the Component's name, the template's name, and the instance's ordinal + using the pattern: $(cluster.name)-$(component.name)-$(template.name)-$(ordinal). Ordinals start from 0. + The specified name overrides any default naming conventions or patterns. + maxLength: 54 + pattern: ^[a-z0-9]([a-z0-9\.\-]*[a-z0-9])?$ + type: string + replicas: + default: 1 + description: |- + Specifies the number of instances (Pods) to create from this InstanceTemplate. + This field allows setting how many replicated instances of the Component, + with the specific overrides in the InstanceTemplate, are created. + The default value is 1. A value of 0 disables instance creation. + format: int32 + minimum: 0 + type: integer + resources: + description: |- + Specifies an override for the resource requirements of the first container in the Pod. + This field allows for customizing resource allocation (CPU, memory, etc.) for the container. + properties: + claims: + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + + + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + + + This field is immutable. It can only be set for containers. + items: + description: ResourceClaim references one entry + in PodSpec.ResourceClaims. + properties: + name: + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + schedulingPolicy: + description: Specifies the scheduling policy for the Component. + properties: + affinity: + description: Specifies a group of affinity scheduling + rules of the Cluster, including NodeAffinity, PodAffinity, + and PodAntiAffinity. + properties: + nodeAffinity: + description: Describes node affinity scheduling + rules for the pod. + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node matches the corresponding matchExpressions; the + node(s) with the highest sum are the most preferred. + items: + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). + properties: + preference: + description: A node selector term, associated + with the corresponding weight. + properties: + matchExpressions: + description: A list of node selector + requirements by node's labels. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key + that the selector applies + to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector + requirements by node's fields. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key + that the selector applies + to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + weight: + description: Weight associated with + matching the corresponding nodeSelectorTerm, + in the range 1-100. + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. + properties: + nodeSelectorTerms: + description: Required. A list of node + selector terms. The terms are ORed. + items: + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. + properties: + matchExpressions: + description: A list of node selector + requirements by node's labels. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key + that the selector applies + to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector + requirements by node's fields. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key + that the selector applies + to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + type: array + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + description: Describes pod affinity scheduling + rules (e.g. co-locate this pod in the same node, + zone, etc. as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched + WeightedPodAffinityTerm fields are added + per-node to find the most preferred node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity + term, associated with the corresponding + weight. + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions + is a list of label selector + requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the + label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. + Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions + is a list of label selector + requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the + label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: |- + weight associated with matching the corresponding podAffinityTerm, + in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. + items: + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is + a list of label selector requirements. + The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. + Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is + a list of label selector requirements. + The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + description: Describes pod anti-affinity scheduling + rules (e.g. avoid putting this pod in the same + node, zone, etc. as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the anti-affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched + WeightedPodAffinityTerm fields are added + per-node to find the most preferred node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity + term, associated with the corresponding + weight. + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions + is a list of label selector + requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the + label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. + Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions + is a list of label selector + requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the + label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: |- + weight associated with matching the corresponding podAffinityTerm, + in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the anti-affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the anti-affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. + items: + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is + a list of label selector requirements. + The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. + Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is + a list of label selector requirements. + The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + nodeName: + description: |- + NodeName is a request to schedule this Pod onto a specific node. If it is non-empty, + the scheduler simply schedules this Pod onto that node, assuming that it fits resource + requirements. + type: string + nodeSelector: + additionalProperties: + type: string + description: |- + NodeSelector is a selector which must be true for the Pod to fit on a node. + Selector which must match a node's labels for the Pod to be scheduled on that node. + More info: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ + type: object + x-kubernetes-map-type: atomic + schedulerName: + description: |- + If specified, the Pod will be dispatched by specified scheduler. + If not specified, the Pod will be dispatched by default scheduler. + type: string + tolerations: + description: |- + Allows Pods to be scheduled onto nodes with matching taints. + Each toleration in the array allows the Pod to tolerate node taints based on + specified `key`, `value`, `effect`, and `operator`. + + + - The `key`, `value`, and `effect` identify the taint that the toleration matches. + - The `operator` determines how the toleration matches the taint. + + + Pods with matching tolerations are allowed to be scheduled on tainted nodes, typically reserved for specific purposes. + items: + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . + properties: + effect: + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. + type: string + operator: + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. + type: string + tolerationSeconds: + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. + format: int64 + type: integer + value: + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. + type: string + type: object + type: array + topologySpreadConstraints: + description: |- + TopologySpreadConstraints describes how a group of Pods ought to spread across topology + domains. Scheduler will schedule Pods in a way which abides by the constraints. + All topologySpreadConstraints are ANDed. + items: + description: TopologySpreadConstraint specifies + how to spread matching pods among the given topology. + properties: + labelSelector: + description: |- + LabelSelector is used to find matching pods. + Pods that match this label selector are counted to determine the number of pods + in their corresponding topology domain. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select the pods over which + spreading will be calculated. The keys are used to lookup values from the + incoming pod labels, those key-value labels are ANDed with labelSelector + to select the group of existing pods over which spreading will be calculated + for the incoming pod. The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + MatchLabelKeys cannot be set when LabelSelector isn't set. + Keys that don't exist in the incoming pod labels will + be ignored. A null or empty list means only match against labelSelector. + + + This is a beta field and requires the MatchLabelKeysInPodTopologySpread feature gate to be enabled (enabled by default). + items: + type: string + type: array + x-kubernetes-list-type: atomic + maxSkew: + description: |- + MaxSkew describes the degree to which pods may be unevenly distributed. + When `whenUnsatisfiable=DoNotSchedule`, it is the maximum permitted difference + between the number of matching pods in the target topology and the global minimum. + The global minimum is the minimum number of matching pods in an eligible domain + or zero if the number of eligible domains is less than MinDomains. + For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same + labelSelector spread as 2/2/1: + In this case, the global minimum is 1. + | zone1 | zone2 | zone3 | + | P P | P P | P | + - if MaxSkew is 1, incoming pod can only be scheduled to zone3 to become 2/2/2; + scheduling it onto zone1(zone2) would make the ActualSkew(3-1) on zone1(zone2) + violate MaxSkew(1). + - if MaxSkew is 2, incoming pod can be scheduled onto any zone. + When `whenUnsatisfiable=ScheduleAnyway`, it is used to give higher precedence + to topologies that satisfy it. + It's a required field. Default value is 1 and 0 is not allowed. + format: int32 + type: integer + minDomains: + description: |- + MinDomains indicates a minimum number of eligible domains. + When the number of eligible domains with matching topology keys is less than minDomains, + Pod Topology Spread treats "global minimum" as 0, and then the calculation of Skew is performed. + And when the number of eligible domains with matching topology keys equals or greater than minDomains, + this value has no effect on scheduling. + As a result, when the number of eligible domains is less than minDomains, + scheduler won't schedule more than maxSkew Pods to those domains. + If value is nil, the constraint behaves as if MinDomains is equal to 1. + Valid values are integers greater than 0. + When value is not nil, WhenUnsatisfiable must be DoNotSchedule. + + + For example, in a 3-zone cluster, MaxSkew is set to 2, MinDomains is set to 5 and pods with the same + labelSelector spread as 2/2/2: + | zone1 | zone2 | zone3 | + | P P | P P | P P | + The number of domains is less than 5(MinDomains), so "global minimum" is treated as 0. + In this situation, new pod with the same labelSelector cannot be scheduled, + because computed skew will be 3(3 - 0) if new Pod is scheduled to any of the three zones, + it will violate MaxSkew. + + + This is a beta field and requires the MinDomainsInPodTopologySpread feature gate to be enabled (enabled by default). + format: int32 + type: integer + nodeAffinityPolicy: + description: |- + NodeAffinityPolicy indicates how we will treat Pod's nodeAffinity/nodeSelector + when calculating pod topology spread skew. Options are: + - Honor: only nodes matching nodeAffinity/nodeSelector are included in the calculations. + - Ignore: nodeAffinity/nodeSelector are ignored. All nodes are included in the calculations. + + + If this value is nil, the behavior is equivalent to the Honor policy. + This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag. + type: string + nodeTaintsPolicy: + description: |- + NodeTaintsPolicy indicates how we will treat node taints when calculating + pod topology spread skew. Options are: + - Honor: nodes without taints, along with tainted nodes for which the incoming pod + has a toleration, are included. + - Ignore: node taints are ignored. All nodes are included. + + + If this value is nil, the behavior is equivalent to the Ignore policy. + This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag. + type: string + topologyKey: + description: |- + TopologyKey is the key of node labels. Nodes that have a label with this key + and identical values are considered to be in the same topology. + We consider each as a "bucket", and try to put balanced number + of pods into each bucket. + We define a domain as a particular instance of a topology. + Also, we define an eligible domain as a domain whose nodes meet the requirements of + nodeAffinityPolicy and nodeTaintsPolicy. + e.g. If TopologyKey is "kubernetes.io/hostname", each Node is a domain of that topology. + And, if TopologyKey is "topology.kubernetes.io/zone", each zone is a domain of that topology. + It's a required field. + type: string + whenUnsatisfiable: + description: |- + WhenUnsatisfiable indicates how to deal with a pod if it doesn't satisfy + the spread constraint. + - DoNotSchedule (default) tells the scheduler not to schedule it. + - ScheduleAnyway tells the scheduler to schedule the pod in any location, + but giving higher precedence to topologies that would help reduce the + skew. + A constraint is considered "Unsatisfiable" for an incoming pod + if and only if every possible node assignment for that pod would violate + "MaxSkew" on some topology. + For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same + labelSelector spread as 3/1/1: + | zone1 | zone2 | zone3 | + | P P P | P | P | + If WhenUnsatisfiable is set to DoNotSchedule, incoming pod can only be scheduled + to zone2(zone3) to become 3/2/1(3/1/2) as ActualSkew(2-1) on zone2(zone3) satisfies + MaxSkew(1). In other words, the cluster can still be imbalanced, but scheduler + won't make it *more* imbalanced. + It's a required field. + type: string + required: + - maxSkew + - topologyKey + - whenUnsatisfiable + type: object + type: array + type: object + volumeClaimTemplates: + description: |- + Defines VolumeClaimTemplates to override. + Add new or override existing volume claim templates. + items: + properties: + name: + description: |- + Refers to the name of a volumeMount defined in either: + + + - `componentDefinition.spec.runtime.containers[*].volumeMounts` + - `clusterDefinition.spec.componentDefs[*].podSpec.containers[*].volumeMounts` (deprecated) + + + The value of `name` must match the `name` field of a volumeMount specified in the corresponding `volumeMounts` array. + type: string + spec: + description: |- + Defines the desired characteristics of a PersistentVolumeClaim that will be created for the volume + with the mount name specified in the `name` field. + + + When a Pod is created for this ClusterComponent, a new PVC will be created based on the specification + defined in the `spec` field. The PVC will be associated with the volume mount specified by the `name` field. + properties: + accessModes: + description: |- + Contains the desired access modes the volume should have. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1. + items: + type: string + type: array + x-kubernetes-preserve-unknown-fields: true + resources: + description: |- + Represents the minimum resources the volume should have. + If the RecoverVolumeExpansionFailure feature is enabled, users are allowed to specify resource requirements that + are lower than the previous value but must still be higher than the capacity recorded in the status field of the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources. + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + x-kubernetes-preserve-unknown-fields: true + storageClassName: + description: |- + The name of the StorageClass required by the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1. + type: string + volumeMode: + description: Defines what type of volume is + required by the claim, either Block or Filesystem. + type: string + type: object + required: + - name + type: object + type: array + volumeMounts: + description: |- + Defines VolumeMounts to override. + Add new or override existing volume mounts of the first container in the Pod. + items: + description: VolumeMount describes a mounting of a Volume + within a container. + properties: + mountPath: + description: |- + Path within the container at which the volume should be mounted. Must + not contain ':'. + type: string + mountPropagation: + description: |- + mountPropagation determines how mounts are propagated from the host + to container and the other way around. + When not set, MountPropagationNone is used. + This field is beta in 1.10. + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: |- + Mounted read-only if true, read-write otherwise (false or unspecified). + Defaults to false. + type: boolean + subPath: + description: |- + Path within the volume from which the container's volume should be mounted. + Defaults to "" (volume's root). + type: string + subPathExpr: + description: |- + Expanded path within the volume from which the container's volume should be mounted. + Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment. + Defaults to "" (volume's root). + SubPathExpr and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + volumes: + description: |- + Defines Volumes to override. + Add new or override existing volumes. + items: + description: Volume represents a named volume in a pod + that may be accessed by any container in the pod. + properties: + awsElasticBlockStore: + description: |- + awsElasticBlockStore represents an AWS Disk resource that is attached to a + kubelet's host machine and then exposed to the pod. + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + properties: + fsType: + description: |- + fsType is the filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + partition: + description: |- + partition is the partition in the volume that you want to mount. + If omitted, the default is to mount by volume name. + Examples: For volume /dev/sda1, you specify the partition as "1". + Similarly, the volume partition for /dev/sda is "0" (or you can leave the property empty). + format: int32 + type: integer + readOnly: + description: |- + readOnly value true will force the readOnly setting in VolumeMounts. + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + type: boolean + volumeID: + description: |- + volumeID is unique ID of the persistent disk resource in AWS (Amazon EBS volume). + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + type: string + required: + - volumeID + type: object + azureDisk: + description: azureDisk represents an Azure Data + Disk mount on the host and bind mount to the pod. + properties: + cachingMode: + description: 'cachingMode is the Host Caching + mode: None, Read Only, Read Write.' + type: string + diskName: + description: diskName is the Name of the data + disk in the blob storage + type: string + diskURI: + description: diskURI is the URI of data disk + in the blob storage + type: string + fsType: + description: |- + fsType is Filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + kind: + description: 'kind expected values are Shared: + multiple blob disks per storage account Dedicated: + single blob disk per storage account Managed: + azure managed data disk (only in managed availability + set). defaults to shared' + type: string + readOnly: + description: |- + readOnly Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + description: azureFile represents an Azure File + Service mount on the host and bind mount to the + pod. + properties: + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretName: + description: secretName is the name of secret + that contains Azure Storage Account Name and + Key + type: string + shareName: + description: shareName is the azure share Name + type: string + required: + - secretName + - shareName + type: object + cephfs: + description: cephFS represents a Ceph FS mount on + the host that shares a pod's lifetime + properties: + monitors: + description: |- + monitors is Required: Monitors is a collection of Ceph monitors + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + items: + type: string + type: array + path: + description: 'path is Optional: Used as the + mounted root, rather than the full Ceph tree, + default is /' + type: string + readOnly: + description: |- + readOnly is Optional: Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + type: boolean + secretFile: + description: |- + secretFile is Optional: SecretFile is the path to key ring for User, default is /etc/ceph/user.secret + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + type: string + secretRef: + description: |- + secretRef is Optional: SecretRef is reference to the authentication secret for User, default is empty. + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + 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 + user: + description: |- + user is optional: User is the rados user name, default is admin + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + type: string + required: + - monitors + type: object + cinder: + description: |- + cinder represents a cinder volume attached and mounted on kubelets host machine. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + type: string + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + type: boolean + secretRef: + description: |- + secretRef is optional: points to a secret object containing parameters used to connect + to OpenStack. + 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 + volumeID: + description: |- + volumeID used to identify the volume in cinder. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + type: string + required: + - volumeID + type: object + configMap: + description: configMap represents a configMap that + should populate this volume + properties: + defaultMode: + description: |- + defaultMode is optional: mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + items: + description: |- + items if unspecified, each key-value pair in the Data field of the referenced + ConfigMap will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the ConfigMap, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within + a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + 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 + optional: + description: optional specify whether the ConfigMap + or its keys must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + csi: + description: csi (Container Storage Interface) represents + ephemeral storage that is handled by certain external + CSI drivers (Beta feature). + properties: + driver: + description: |- + driver is the name of the CSI driver that handles this volume. + Consult with your admin for the correct name as registered in the cluster. + type: string + fsType: + description: |- + fsType to mount. Ex. "ext4", "xfs", "ntfs". + If not provided, the empty value is passed to the associated CSI driver + which will determine the default filesystem to apply. + type: string + nodePublishSecretRef: + description: |- + nodePublishSecretRef is a reference to the secret object containing + sensitive information to pass to the CSI driver to complete the CSI + NodePublishVolume and NodeUnpublishVolume calls. + This field is optional, and may be empty if no secret is required. If the + secret object contains more than one secret, all secret references are passed. + 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 + readOnly: + description: |- + readOnly specifies a read-only configuration for the volume. + Defaults to false (read/write). + type: boolean + volumeAttributes: + additionalProperties: + type: string + description: |- + volumeAttributes stores driver-specific properties that are passed to the CSI + driver. Consult your driver's documentation for supported values. + type: object + required: + - driver + type: object + downwardAPI: + description: downwardAPI represents downward API + about the pod that should populate this volume + properties: + defaultMode: + description: |- + Optional: mode bits to use on created files by default. Must be a + Optional: mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + items: + description: Items is a list of downward API + volume file + items: + description: DownwardAPIVolumeFile represents + information to create the file containing + the pod field + properties: + fieldRef: + description: 'Required: Selects a field + of the pod: only annotations, labels, + name and namespace are supported.' + properties: + apiVersion: + description: Version of the schema + the FieldPath is written in terms + of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to + select in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + description: |- + Optional: mode bits used to set permissions on this file, must be an octal value + between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: 'Required: Path is the relative + path name of the file to be created. + Must not be absolute or contain the + ''..'' path. Must be utf-8 encoded. + The first item of the relative path + must not start with ''..''' + type: string + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported. + properties: + containerName: + description: 'Container name: required + for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output + format of the exposed resources, + defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to + select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + type: object + emptyDir: + description: |- + emptyDir represents a temporary directory that shares a pod's lifetime. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir + properties: + medium: + description: |- + medium represents what type of storage medium should back this directory. + The default is "" which means to use the node's default medium. + Must be an empty string (default) or Memory. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + description: |- + sizeLimit is the total amount of local storage required for this EmptyDir volume. + The size limit is also applicable for memory medium. + The maximum usage on memory medium EmptyDir would be the minimum value between + the SizeLimit specified here and the sum of memory limits of all containers in a pod. + The default is nil which means that the limit is undefined. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + description: |- + ephemeral represents a volume that is handled by a cluster storage driver. + The volume's lifecycle is tied to the pod that defines it - it will be created before the pod starts, + and deleted when the pod is removed. + + + Use this if: + a) the volume is only needed while the pod runs, + b) features of normal volumes like restoring from snapshot or capacity + tracking are needed, + c) the storage driver is specified through a storage class, and + d) the storage driver supports dynamic volume provisioning through + a PersistentVolumeClaim (see EphemeralVolumeSource for more + information on the connection between this volume type + and PersistentVolumeClaim). + + + Use PersistentVolumeClaim or one of the vendor-specific + APIs for volumes that persist for longer than the lifecycle + of an individual pod. + + + Use CSI for light-weight local ephemeral volumes if the CSI driver is meant to + be used that way - see the documentation of the driver for + more information. + + + A pod can use both types of ephemeral volumes and + persistent volumes at the same time. + properties: + volumeClaimTemplate: + description: |- + Will be used to create a stand-alone PVC to provision the volume. + The pod in which this EphemeralVolumeSource is embedded will be the + owner of the PVC, i.e. the PVC will be deleted together with the + pod. The name of the PVC will be `-` where + `` is the name from the `PodSpec.Volumes` array + entry. Pod validation will reject the pod if the concatenated name + is not valid for a PVC (for example, too long). + + + An existing PVC with that name that is not owned by the pod + will *not* be used for the pod to avoid using an unrelated + volume by mistake. Starting the pod is then blocked until + the unrelated PVC is removed. If such a pre-created PVC is + meant to be used by the pod, the PVC has to updated with an + owner reference to the pod once the pod exists. Normally + this should not be necessary, but it may be useful when + manually reconstructing a broken cluster. + + + This field is read-only and no changes will be made by Kubernetes + to the PVC after it has been created. + + + Required, must not be nil. + properties: + metadata: + description: |- + May contain labels and annotations that will be copied into the PVC + when creating it. No other fields are allowed and will be rejected during + validation. + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + description: |- + The specification for the PersistentVolumeClaim. The entire content is + copied unchanged into the PVC that gets created from this + template. The same fields as in a PersistentVolumeClaim + are also valid here. + properties: + accessModes: + description: |- + accessModes contains the desired access modes the volume should have. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1 + items: + type: string + type: array + dataSource: + description: |- + dataSource field can be used to specify either: + * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) + * An existing PVC (PersistentVolumeClaim) + If the provisioner or an external controller can support the specified data source, + it will create a new volume based on the contents of the specified data source. + When the AnyVolumeDataSource feature gate is enabled, dataSource contents will be copied to dataSourceRef, + and dataSourceRef contents will be copied to dataSource when dataSourceRef.namespace is not specified. + If the namespace is specified, then dataSourceRef will not be copied to dataSource. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of + resource being referenced + type: string + name: + description: Name is the name of + resource being referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + description: |- + dataSourceRef specifies the object from which to populate the volume with data, if a non-empty + volume is desired. This may be any object from a non-empty API group (non + core object) or a PersistentVolumeClaim object. + When this field is specified, volume binding will only succeed if the type of + the specified object matches some installed volume populator or dynamic + provisioner. + This field will replace the functionality of the dataSource field and as such + if both fields are non-empty, they must have the same value. For backwards + compatibility, when namespace isn't specified in dataSourceRef, + both fields (dataSource and dataSourceRef) will be set to the same + value automatically if one of them is empty and the other is non-empty. + When namespace is specified in dataSourceRef, + dataSource isn't set to the same value and must be empty. + There are three important differences between dataSource and dataSourceRef: + * While dataSource only allows two specific types of objects, dataSourceRef + allows any non-core object, as well as PersistentVolumeClaim objects. + * While dataSource ignores disallowed values (dropping them), dataSourceRef + preserves all values, and generates an error if a disallowed value is + specified. + * While dataSource only allows local objects, dataSourceRef allows objects + in any namespaces. + (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled. + (Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of + resource being referenced + type: string + name: + description: Name is the name of + resource being referenced + type: string + namespace: + description: |- + Namespace is the namespace of resource being referenced + Note that when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details. + (Alpha) This field requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + type: string + required: + - kind + - name + type: object + resources: + description: |- + resources represents the minimum resources the volume should have. + If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements + that are lower than previous value but must still be higher than capacity recorded in the + status field of the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + selector: + description: selector is a label query + over volumes to consider for binding. + properties: + matchExpressions: + description: matchExpressions is + a list of label selector requirements. + The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + description: |- + storageClassName is the name of the StorageClass required by the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1 + type: string + volumeAttributesClassName: + description: |- + volumeAttributesClassName may be used to set the VolumeAttributesClass used by this claim. + If specified, the CSI driver will create or update the volume with the attributes defined + in the corresponding VolumeAttributesClass. This has a different purpose than storageClassName, + it can be changed after the claim is created. An empty string value means that no VolumeAttributesClass + will be applied to the claim but it's not allowed to reset this field to empty string once it is set. + If unspecified and the PersistentVolumeClaim is unbound, the default VolumeAttributesClass + will be set by the persistentvolume controller if it exists. + If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be + set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource + exists. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#volumeattributesclass + (Alpha) Using this field requires the VolumeAttributesClass feature gate to be enabled. + type: string + volumeMode: + description: |- + volumeMode defines what type of volume is required by the claim. + Value of Filesystem is implied when not included in claim spec. + type: string + volumeName: + description: volumeName is the binding + reference to the PersistentVolume + backing this claim. + type: string + type: object + required: + - spec + type: object + type: object + fc: + description: fc represents a Fibre Channel resource + that is attached to a kubelet's host machine and + then exposed to the pod. + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + lun: + description: 'lun is Optional: FC target lun + number' + format: int32 + type: integer + readOnly: + description: |- + readOnly is Optional: Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + targetWWNs: + description: 'targetWWNs is Optional: FC target + worldwide names (WWNs)' + items: + type: string + type: array + wwids: + description: |- + wwids Optional: FC volume world wide identifiers (wwids) + Either wwids or combination of targetWWNs and lun must be set, but not both simultaneously. + items: + type: string + type: array + type: object + flexVolume: + description: |- + flexVolume represents a generic volume resource that is + provisioned/attached using an exec based plugin. + properties: + driver: + description: driver is the name of the driver + to use for this volume. + type: string + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". The default filesystem depends on FlexVolume script. + type: string + options: + additionalProperties: + type: string + description: 'options is Optional: this field + holds extra command options if any.' + type: object + readOnly: + description: |- + readOnly is Optional: defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: |- + secretRef is Optional: secretRef is reference to the secret object containing + sensitive information to pass to the plugin scripts. This may be + empty if no secret object is specified. If the secret object + contains more than one secret, all secrets are passed to the plugin + scripts. + 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 + required: + - driver + type: object + flocker: + description: flocker represents a Flocker volume + attached to a kubelet's host machine. This depends + on the Flocker control service being running + properties: + datasetName: + description: |- + datasetName is Name of the dataset stored as metadata -> name on the dataset for Flocker + should be considered as deprecated + type: string + datasetUUID: + description: datasetUUID is the UUID of the + dataset. This is unique identifier of a Flocker + dataset + type: string + type: object + gcePersistentDisk: + description: |- + gcePersistentDisk represents a GCE Disk resource that is attached to a + kubelet's host machine and then exposed to the pod. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + properties: + fsType: + description: |- + fsType is filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + partition: + description: |- + partition is the partition in the volume that you want to mount. + If omitted, the default is to mount by volume name. + Examples: For volume /dev/sda1, you specify the partition as "1". + Similarly, the volume partition for /dev/sda is "0" (or you can leave the property empty). + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + format: int32 + type: integer + pdName: + description: |- + pdName is unique name of the PD resource in GCE. Used to identify the disk in GCE. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + type: string + readOnly: + description: |- + readOnly here will force the ReadOnly setting in VolumeMounts. + Defaults to false. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + type: boolean + required: + - pdName + type: object + gitRepo: + description: |- + gitRepo represents a git repository at a particular revision. + DEPRECATED: GitRepo is deprecated. To provision a container with a git repo, mount an + EmptyDir into an InitContainer that clones the repo using git, then mount the EmptyDir + into the Pod's container. + properties: + directory: + description: |- + directory is the target directory name. + Must not contain or start with '..'. If '.' is supplied, the volume directory will be the + git repository. Otherwise, if specified, the volume will contain the git repository in + the subdirectory with the given name. + type: string + repository: + description: repository is the URL + type: string + revision: + description: revision is the commit hash for + the specified revision. + type: string + required: + - repository + type: object + glusterfs: + description: |- + glusterfs represents a Glusterfs mount on the host that shares a pod's lifetime. + More info: https://examples.k8s.io/volumes/glusterfs/README.md + properties: + endpoints: + description: |- + endpoints is the endpoint name that details Glusterfs topology. + More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod + type: string + path: + description: |- + path is the Glusterfs volume path. + More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod + type: string + readOnly: + description: |- + readOnly here will force the Glusterfs volume to be mounted with read-only permissions. + Defaults to false. + More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod + type: boolean + required: + - endpoints + - path + type: object + hostPath: + description: |- + hostPath represents a pre-existing file or directory on the host + machine that is directly exposed to the container. This is generally + used for system agents or other privileged things that are allowed + to see the host machine. Most containers will NOT need this. + More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + --- + TODO(jonesdl) We need to restrict who can use host directory mounts and who can/can not + mount host directories as read/write. + properties: + path: + description: |- + path of the directory on the host. + If the path is a symlink, it will follow the link to the real path. + More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + type: string + type: + description: |- + type for HostPath Volume + Defaults to "" + More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + type: string + required: + - path + type: object + iscsi: + description: |- + iscsi represents an ISCSI Disk resource that is attached to a + kubelet's host machine and then exposed to the pod. + More info: https://examples.k8s.io/volumes/iscsi/README.md + properties: + chapAuthDiscovery: + description: chapAuthDiscovery defines whether + support iSCSI Discovery CHAP authentication + type: boolean + chapAuthSession: + description: chapAuthSession defines whether + support iSCSI Session CHAP authentication + type: boolean + fsType: + description: |- + fsType is the filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#iscsi + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + initiatorName: + description: |- + initiatorName is the custom iSCSI Initiator Name. + If initiatorName is specified with iscsiInterface simultaneously, new iSCSI interface + : will be created for the connection. + type: string + iqn: + description: iqn is the target iSCSI Qualified + Name. + type: string + iscsiInterface: + description: |- + iscsiInterface is the interface Name that uses an iSCSI transport. + Defaults to 'default' (tcp). + type: string + lun: + description: lun represents iSCSI Target Lun + number. + format: int32 + type: integer + portals: + description: |- + portals is the iSCSI Target Portal List. The portal is either an IP or ip_addr:port if the port + is other than default (typically TCP ports 860 and 3260). + items: + type: string + type: array + readOnly: + description: |- + readOnly here will force the ReadOnly setting in VolumeMounts. + Defaults to false. + type: boolean + secretRef: + description: secretRef is the CHAP Secret for + iSCSI target and initiator authentication + 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 + targetPortal: + description: |- + targetPortal is iSCSI Target Portal. The Portal is either an IP or ip_addr:port if the port + is other than default (typically TCP ports 860 and 3260). + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + description: |- + name of the volume. + Must be a DNS_LABEL and unique within the pod. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + nfs: + description: |- + nfs represents an NFS mount on the host that shares a pod's lifetime + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + properties: + path: + description: |- + path that is exported by the NFS server. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + type: string + readOnly: + description: |- + readOnly here will force the NFS export to be mounted with read-only permissions. + Defaults to false. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + type: boolean + server: + description: |- + server is the hostname or IP address of the NFS server. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + description: |- + persistentVolumeClaimVolumeSource represents a reference to a + PersistentVolumeClaim in the same namespace. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims + properties: + claimName: + description: |- + claimName is the name of a PersistentVolumeClaim in the same namespace as the pod using this volume. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims + type: string + readOnly: + description: |- + readOnly Will force the ReadOnly setting in VolumeMounts. + Default false. + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + description: photonPersistentDisk represents a PhotonController + persistent disk attached and mounted on kubelets + host machine + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + pdID: + description: pdID is the ID that identifies + Photon Controller persistent disk + type: string + required: + - pdID + type: object + portworxVolume: + description: portworxVolume represents a portworx + volume attached and mounted on kubelets host machine + properties: + fsType: + description: |- + fSType represents the filesystem type to mount + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs". Implicitly inferred to be "ext4" if unspecified. + type: string + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + volumeID: + description: volumeID uniquely identifies a + Portworx volume + type: string + required: + - volumeID + type: object + projected: + description: projected items for all in one resources + secrets, configmaps, and downward API + properties: + defaultMode: + description: |- + defaultMode are the mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + sources: + description: sources is the list of volume projections + items: + description: Projection that may be projected + along with other supported volume types + properties: + clusterTrustBundle: + description: |- + ClusterTrustBundle allows a pod to access the `.spec.trustBundle` field + of ClusterTrustBundle objects in an auto-updating file. + + + Alpha, gated by the ClusterTrustBundleProjection feature gate. + + + ClusterTrustBundle objects can either be selected by name, or by the + combination of signer name and a label selector. + + + Kubelet performs aggressive normalization of the PEM contents written + into the pod filesystem. Esoteric PEM features such as inter-block + comments and block headers are stripped. Certificates are deduplicated. + The ordering of certificates within the file is arbitrary, and Kubelet + may change the order over time. + properties: + labelSelector: + description: |- + Select all ClusterTrustBundles that match this label selector. Only has + effect if signerName is set. Mutually-exclusive with name. If unset, + interpreted as "match nothing". If set but empty, interpreted as "match + everything". + properties: + matchExpressions: + description: matchExpressions + is a list of label selector + requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the + label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + name: + description: |- + Select a single ClusterTrustBundle by object name. Mutually-exclusive + with signerName and labelSelector. + type: string + optional: + description: |- + If true, don't block pod startup if the referenced ClusterTrustBundle(s) + aren't available. If using name, then the named ClusterTrustBundle is + allowed not to exist. If using signerName, then the combination of + signerName and labelSelector is allowed to match zero + ClusterTrustBundles. + type: boolean + path: + description: Relative path from the + volume root to write the bundle. + type: string + signerName: + description: |- + Select all ClusterTrustBundles that match this signer name. + Mutually-exclusive with name. The contents of all selected + ClusterTrustBundles will be unified and deduplicated. + type: string + required: + - path + type: object + configMap: + description: configMap information about + the configMap data to project + properties: + items: + description: |- + items if unspecified, each key-value pair in the Data field of the referenced + ConfigMap will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the ConfigMap, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to + a path within a volume. + properties: + key: + description: key is the key + to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + 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 + optional: + description: optional specify whether + the ConfigMap or its keys must be + defined + type: boolean + type: object + x-kubernetes-map-type: atomic + downwardAPI: + description: downwardAPI information about + the downwardAPI data to project + properties: + items: + description: Items is a list of DownwardAPIVolume + file + items: + description: DownwardAPIVolumeFile + represents information to create + the file containing the pod field + properties: + fieldRef: + description: 'Required: Selects + a field of the pod: only annotations, + labels, name and namespace + are supported.' + properties: + apiVersion: + description: Version of + the schema the FieldPath + is written in terms of, + defaults to "v1". + type: string + fieldPath: + description: Path of the + field to select in the + specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + description: |- + Optional: mode bits used to set permissions on this file, must be an octal value + between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: 'Required: Path + is the relative path name + of the file to be created. + Must not be absolute or contain + the ''..'' path. Must be utf-8 + encoded. The first item of + the relative path must not + start with ''..''' + type: string + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported. + properties: + containerName: + description: 'Container + name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the + output format of the exposed + resources, defaults to + "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: + resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + type: object + secret: + description: secret information about + the secret data to project + properties: + items: + description: |- + items if unspecified, each key-value pair in the Data field of the referenced + Secret will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the Secret, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to + a path within a volume. + properties: + key: + description: key is the key + to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + 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 + optional: + description: optional field specify + whether the Secret or its key must + be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + serviceAccountToken: + description: serviceAccountToken is information + about the serviceAccountToken data to + project + properties: + audience: + description: |- + audience is the intended audience of the token. A recipient of a token + must identify itself with an identifier specified in the audience of the + token, and otherwise should reject the token. The audience defaults to the + identifier of the apiserver. + type: string + expirationSeconds: + description: |- + expirationSeconds is the requested duration of validity of the service + account token. As the token approaches expiration, the kubelet volume + plugin will proactively rotate the service account token. The kubelet will + start trying to rotate the token if the token is older than 80 percent of + its time to live or if the token is older than 24 hours.Defaults to 1 hour + and must be at least 10 minutes. + format: int64 + type: integer + path: + description: |- + path is the path relative to the mount point of the file to project the + token into. + type: string + required: + - path + type: object + type: object + type: array + type: object + quobyte: + description: quobyte represents a Quobyte mount + on the host that shares a pod's lifetime + properties: + group: + description: |- + group to map volume access to + Default is no group + type: string + readOnly: + description: |- + readOnly here will force the Quobyte volume to be mounted with read-only permissions. + Defaults to false. + type: boolean + registry: + description: |- + registry represents a single or multiple Quobyte Registry services + specified as a string as host:port pair (multiple entries are separated with commas) + which acts as the central registry for volumes + type: string + tenant: + description: |- + tenant owning the given Quobyte volume in the Backend + Used with dynamically provisioned Quobyte volumes, value is set by the plugin + type: string + user: + description: |- + user to map volume access to + Defaults to serivceaccount user + type: string + volume: + description: volume is a string that references + an already created Quobyte volume by name. + type: string + required: + - registry + - volume + type: object + rbd: + description: |- + rbd represents a Rados Block Device mount on the host that shares a pod's lifetime. + More info: https://examples.k8s.io/volumes/rbd/README.md + properties: + fsType: + description: |- + fsType is the filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#rbd + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + image: + description: |- + image is the rados image name. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + keyring: + description: |- + keyring is the path to key ring for RBDUser. + Default is /etc/ceph/keyring. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + monitors: + description: |- + monitors is a collection of Ceph monitors. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + items: + type: string + type: array + pool: + description: |- + pool is the rados pool name. + Default is rbd. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + readOnly: + description: |- + readOnly here will force the ReadOnly setting in VolumeMounts. + Defaults to false. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: boolean + secretRef: + description: |- + secretRef is name of the authentication secret for RBDUser. If provided + overrides keyring. + Default is nil. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + 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 + user: + description: |- + user is the rados user name. + Default is admin. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + required: + - image + - monitors + type: object + scaleIO: + description: scaleIO represents a ScaleIO persistent + volume attached and mounted on Kubernetes nodes. + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". + Default is "xfs". + type: string + gateway: + description: gateway is the host address of + the ScaleIO API Gateway. + type: string + protectionDomain: + description: protectionDomain is the name of + the ScaleIO Protection Domain for the configured + storage. + type: string + readOnly: + description: |- + readOnly Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: |- + secretRef references to the secret for ScaleIO user and other + sensitive information. If this is not provided, Login operation will fail. + 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 + sslEnabled: + description: sslEnabled Flag enable/disable + SSL communication with Gateway, default false + type: boolean + storageMode: + description: |- + storageMode indicates whether the storage for a volume should be ThickProvisioned or ThinProvisioned. + Default is ThinProvisioned. + type: string + storagePool: + description: storagePool is the ScaleIO Storage + Pool associated with the protection domain. + type: string + system: + description: system is the name of the storage + system as configured in ScaleIO. + type: string + volumeName: + description: |- + volumeName is the name of a volume already created in the ScaleIO system + that is associated with this volume source. + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + description: |- + secret represents a secret that should populate this volume. + More info: https://kubernetes.io/docs/concepts/storage/volumes#secret + properties: + defaultMode: + description: |- + defaultMode is Optional: mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values + for mode bits. Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + items: + description: |- + items If unspecified, each key-value pair in the Data field of the referenced + Secret will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the Secret, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within + a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + optional: + description: optional field specify whether + the Secret or its keys must be defined + type: boolean + secretName: + description: |- + secretName is the name of the secret in the pod's namespace to use. + More info: https://kubernetes.io/docs/concepts/storage/volumes#secret + type: string + type: object + storageos: + description: storageOS represents a StorageOS volume + attached and mounted on Kubernetes nodes. + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: |- + secretRef specifies the secret to use for obtaining the StorageOS API + credentials. If not specified, default values will be attempted. + 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 + volumeName: + description: |- + volumeName is the human-readable name of the StorageOS volume. Volume + names are only unique within a namespace. + type: string + volumeNamespace: + description: |- + volumeNamespace specifies the scope of the volume within StorageOS. If no + namespace is specified then the Pod's namespace will be used. This allows the + Kubernetes name scoping to be mirrored within StorageOS for tighter integration. + Set VolumeName to any name to override the default behaviour. + Set to "default" if you are not using namespaces within StorageOS. + Namespaces that do not pre-exist within StorageOS will be created. + type: string + type: object + vsphereVolume: + description: vsphereVolume represents a vSphere + volume attached and mounted on kubelets host machine + properties: + fsType: + description: |- + fsType is filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + storagePolicyID: + description: storagePolicyID is the storage + Policy Based Management (SPBM) profile ID + associated with the StoragePolicyName. + type: string + storagePolicyName: + description: storagePolicyName is the storage + Policy Based Management (SPBM) profile name. + type: string + volumePath: + description: volumePath is the path that identifies + vSphere volume vmdk + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + issuer: + description: |- + Specifies the configuration for the TLS certificates issuer. + It allows defining the issuer name and the reference to the secret containing the TLS certificates and key. + The secret should contain the CA certificate, TLS certificate, and private key in the specified keys. + Required when TLS is enabled. + properties: + name: + allOf: + - enum: + - KubeBlocks + - UserProvided + - enum: + - KubeBlocks + - UserProvided + default: KubeBlocks + description: |- + The issuer for TLS certificates. + It only allows two enum values: `KubeBlocks` and `UserProvided`. + + + - `KubeBlocks` indicates that the self-signed TLS certificates generated by the KubeBlocks Operator will be used. + - `UserProvided` means that the user is responsible for providing their own CA, Cert, and Key. + In this case, the user-provided CA certificate, server certificate, and private key will be used + for TLS communication. + type: string + secretRef: + description: |- + SecretRef is the reference to the secret that contains user-provided certificates. + It is required when the issuer is set to `UserProvided`. + properties: + ca: + description: Key of CA cert in Secret + type: string + cert: + description: Key of Cert in Secret + type: string + key: + description: Key of TLS private key in Secret + type: string + name: + description: Name of the Secret that contains user-provided + certificates. + type: string + required: + - ca + - cert + - key + - name + type: object + required: + - name + type: object + labels: + additionalProperties: + type: string + description: Specifies Labels to override or add for underlying + Pods. + type: object + monitor: + description: |- + Deprecated since v0.9 + Determines whether metrics exporter information is annotated on the Component's headless Service. + + + If set to true, the following annotations will be patched into the Service: + + + - "monitor.kubeblocks.io/path" + - "monitor.kubeblocks.io/port" + - "monitor.kubeblocks.io/scheme" + + + These annotations allow the Prometheus installed by KubeBlocks to discover and scrape metrics from the exporter. + type: boolean + name: + description: |- + Specifies the Component's name. + It's part of the Service DNS name and must comply with the IANA service naming rule. + The name is optional when ClusterComponentSpec is used as a template (e.g., in `shardingSpec`), + but required otherwise. + + + TODO +kubebuilder:validation:XValidation:rule="self == oldSelf",message="name is immutable" + maxLength: 22 + pattern: ^[a-z]([a-z0-9\-]*[a-z0-9])?$ + type: string + offlineInstances: + description: |- + Specifies the names of instances to be transitioned to offline status. + + + Marking an instance as offline results in the following: + + + 1. The associated Pod is stopped, and its PersistentVolumeClaim (PVC) is retained for potential + future reuse or data recovery, but it is no longer actively used. + 2. The ordinal number assigned to this instance is preserved, ensuring it remains unique + and avoiding conflicts with new instances. + + + Setting instances to offline allows for a controlled scale-in process, preserving their data and maintaining + ordinal consistency within the Cluster. + Note that offline instances and their associated resources, such as PVCs, are not automatically deleted. + The administrator must manually manage the cleanup and removal of these resources when they are no longer needed. + items: + type: string + type: array + parallelPodManagementConcurrency: + anyOf: + - type: integer + - type: string + description: |- + Controls the concurrency of pods during initial scale up, when replacing pods on nodes, + or when scaling down. It only used when `PodManagementPolicy` is set to `Parallel`. + The default Concurrency is 100%. + x-kubernetes-int-or-string: true + podUpdatePolicy: + description: |- + PodUpdatePolicy indicates how pods should be updated + + + - `StrictInPlace` indicates that only allows in-place upgrades. + Any attempt to modify other fields will be rejected. + - `PreferInPlace` indicates that we will first attempt an in-place upgrade of the Pod. + If that fails, it will fall back to the ReCreate, where pod will be recreated. + Default value is "PreferInPlace" + enum: + - StrictInPlace + - PreferInPlace + type: string + replicas: + default: 1 + description: Specifies the desired number of replicas in the + Component for enhancing availability and durability, or load + balancing. + format: int32 + minimum: 0 + type: integer + resources: + description: |- + Specifies the resources required by the Component. + It allows defining the CPU, memory requirements and limits for the Component's containers. + properties: + claims: + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + + + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + + + This field is immutable. It can only be set for containers. + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + x-kubernetes-preserve-unknown-fields: true + schedulingPolicy: + description: Specifies the scheduling policy for the Component. + properties: + affinity: + description: Specifies a group of affinity scheduling rules + of the Cluster, including NodeAffinity, PodAffinity, and + PodAntiAffinity. + properties: + nodeAffinity: + description: Describes node affinity scheduling rules + for the pod. + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node matches the corresponding matchExpressions; the + node(s) with the highest sum are the most preferred. + items: + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). + properties: + preference: + description: A node selector term, associated + with the corresponding weight. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that + the selector applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that + the selector applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + weight: + description: Weight associated with matching + the corresponding nodeSelectorTerm, in the + range 1-100. + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. + properties: + nodeSelectorTerms: + description: Required. A list of node selector + terms. The terms are ORed. + items: + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that + the selector applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that + the selector applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + type: array + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + description: Describes pod affinity scheduling rules + (e.g. co-locate this pod in the same node, zone, etc. + as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched + WeightedPodAffinityTerm fields are added per-node + to find the most preferred node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, + associated with the corresponding weight. + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a + list of label selector requirements. + The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. + Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a + list of label selector requirements. + The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: |- + weight associated with matching the corresponding podAffinityTerm, + in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. + items: + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. + Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + description: Describes pod anti-affinity scheduling + rules (e.g. avoid putting this pod in the same node, + zone, etc. as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the anti-affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched + WeightedPodAffinityTerm fields are added per-node + to find the most preferred node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, + associated with the corresponding weight. + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a + list of label selector requirements. + The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. + Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a + list of label selector requirements. + The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: |- + weight associated with matching the corresponding podAffinityTerm, + in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the anti-affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the anti-affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. + items: + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. + Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + nodeName: + description: |- + NodeName is a request to schedule this Pod onto a specific node. If it is non-empty, + the scheduler simply schedules this Pod onto that node, assuming that it fits resource + requirements. + type: string + nodeSelector: + additionalProperties: + type: string + description: |- + NodeSelector is a selector which must be true for the Pod to fit on a node. + Selector which must match a node's labels for the Pod to be scheduled on that node. + More info: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ + type: object + x-kubernetes-map-type: atomic + schedulerName: + description: |- + If specified, the Pod will be dispatched by specified scheduler. + If not specified, the Pod will be dispatched by default scheduler. + type: string + tolerations: + description: |- + Allows Pods to be scheduled onto nodes with matching taints. + Each toleration in the array allows the Pod to tolerate node taints based on + specified `key`, `value`, `effect`, and `operator`. + + + - The `key`, `value`, and `effect` identify the taint that the toleration matches. + - The `operator` determines how the toleration matches the taint. + + + Pods with matching tolerations are allowed to be scheduled on tainted nodes, typically reserved for specific purposes. + items: + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . + properties: + effect: + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. + type: string + operator: + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. + type: string + tolerationSeconds: + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. + format: int64 + type: integer + value: + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. + type: string + type: object + type: array + topologySpreadConstraints: + description: |- + TopologySpreadConstraints describes how a group of Pods ought to spread across topology + domains. Scheduler will schedule Pods in a way which abides by the constraints. + All topologySpreadConstraints are ANDed. + items: + description: TopologySpreadConstraint specifies how to + spread matching pods among the given topology. + properties: + labelSelector: + description: |- + LabelSelector is used to find matching pods. + Pods that match this label selector are counted to determine the number of pods + in their corresponding topology domain. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select the pods over which + spreading will be calculated. The keys are used to lookup values from the + incoming pod labels, those key-value labels are ANDed with labelSelector + to select the group of existing pods over which spreading will be calculated + for the incoming pod. The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + MatchLabelKeys cannot be set when LabelSelector isn't set. + Keys that don't exist in the incoming pod labels will + be ignored. A null or empty list means only match against labelSelector. + + + This is a beta field and requires the MatchLabelKeysInPodTopologySpread feature gate to be enabled (enabled by default). + items: + type: string + type: array + x-kubernetes-list-type: atomic + maxSkew: + description: |- + MaxSkew describes the degree to which pods may be unevenly distributed. + When `whenUnsatisfiable=DoNotSchedule`, it is the maximum permitted difference + between the number of matching pods in the target topology and the global minimum. + The global minimum is the minimum number of matching pods in an eligible domain + or zero if the number of eligible domains is less than MinDomains. + For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same + labelSelector spread as 2/2/1: + In this case, the global minimum is 1. + | zone1 | zone2 | zone3 | + | P P | P P | P | + - if MaxSkew is 1, incoming pod can only be scheduled to zone3 to become 2/2/2; + scheduling it onto zone1(zone2) would make the ActualSkew(3-1) on zone1(zone2) + violate MaxSkew(1). + - if MaxSkew is 2, incoming pod can be scheduled onto any zone. + When `whenUnsatisfiable=ScheduleAnyway`, it is used to give higher precedence + to topologies that satisfy it. + It's a required field. Default value is 1 and 0 is not allowed. + format: int32 + type: integer + minDomains: + description: |- + MinDomains indicates a minimum number of eligible domains. + When the number of eligible domains with matching topology keys is less than minDomains, + Pod Topology Spread treats "global minimum" as 0, and then the calculation of Skew is performed. + And when the number of eligible domains with matching topology keys equals or greater than minDomains, + this value has no effect on scheduling. + As a result, when the number of eligible domains is less than minDomains, + scheduler won't schedule more than maxSkew Pods to those domains. + If value is nil, the constraint behaves as if MinDomains is equal to 1. + Valid values are integers greater than 0. + When value is not nil, WhenUnsatisfiable must be DoNotSchedule. + + + For example, in a 3-zone cluster, MaxSkew is set to 2, MinDomains is set to 5 and pods with the same + labelSelector spread as 2/2/2: + | zone1 | zone2 | zone3 | + | P P | P P | P P | + The number of domains is less than 5(MinDomains), so "global minimum" is treated as 0. + In this situation, new pod with the same labelSelector cannot be scheduled, + because computed skew will be 3(3 - 0) if new Pod is scheduled to any of the three zones, + it will violate MaxSkew. + + + This is a beta field and requires the MinDomainsInPodTopologySpread feature gate to be enabled (enabled by default). + format: int32 + type: integer + nodeAffinityPolicy: + description: |- + NodeAffinityPolicy indicates how we will treat Pod's nodeAffinity/nodeSelector + when calculating pod topology spread skew. Options are: + - Honor: only nodes matching nodeAffinity/nodeSelector are included in the calculations. + - Ignore: nodeAffinity/nodeSelector are ignored. All nodes are included in the calculations. + + + If this value is nil, the behavior is equivalent to the Honor policy. + This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag. + type: string + nodeTaintsPolicy: + description: |- + NodeTaintsPolicy indicates how we will treat node taints when calculating + pod topology spread skew. Options are: + - Honor: nodes without taints, along with tainted nodes for which the incoming pod + has a toleration, are included. + - Ignore: node taints are ignored. All nodes are included. + + + If this value is nil, the behavior is equivalent to the Ignore policy. + This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag. + type: string + topologyKey: + description: |- + TopologyKey is the key of node labels. Nodes that have a label with this key + and identical values are considered to be in the same topology. + We consider each as a "bucket", and try to put balanced number + of pods into each bucket. + We define a domain as a particular instance of a topology. + Also, we define an eligible domain as a domain whose nodes meet the requirements of + nodeAffinityPolicy and nodeTaintsPolicy. + e.g. If TopologyKey is "kubernetes.io/hostname", each Node is a domain of that topology. + And, if TopologyKey is "topology.kubernetes.io/zone", each zone is a domain of that topology. + It's a required field. + type: string + whenUnsatisfiable: + description: |- + WhenUnsatisfiable indicates how to deal with a pod if it doesn't satisfy + the spread constraint. + - DoNotSchedule (default) tells the scheduler not to schedule it. + - ScheduleAnyway tells the scheduler to schedule the pod in any location, + but giving higher precedence to topologies that would help reduce the + skew. + A constraint is considered "Unsatisfiable" for an incoming pod + if and only if every possible node assignment for that pod would violate + "MaxSkew" on some topology. + For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same + labelSelector spread as 3/1/1: + | zone1 | zone2 | zone3 | + | P P P | P | P | + If WhenUnsatisfiable is set to DoNotSchedule, incoming pod can only be scheduled + to zone2(zone3) to become 3/2/1(3/1/2) as ActualSkew(2-1) on zone2(zone3) satisfies + MaxSkew(1). In other words, the cluster can still be imbalanced, but scheduler + won't make it *more* imbalanced. + It's a required field. + type: string + required: + - maxSkew + - topologyKey + - whenUnsatisfiable + type: object + type: array + type: object + serviceAccountName: + description: |- + Specifies the name of the ServiceAccount required by the running Component. + This ServiceAccount is used to grant necessary permissions for the Component's Pods to interact + with other Kubernetes resources, such as modifying Pod labels or sending events. + + + Defaults: + To perform certain operational tasks, agent sidecars running in Pods require specific RBAC permissions. + The service account will be bound to a default role named "kubeblocks-cluster-pod-role" which is installed together with KubeBlocks. + If not specified, KubeBlocks automatically assigns a default ServiceAccount named "kb-{cluster.name}" + + + Future Changes: + Future versions might change the default ServiceAccount creation strategy to one per Component, + potentially revising the naming to "kb-{cluster.name}-{component.name}". + + + Users can override the automatic ServiceAccount assignment by explicitly setting the name of + an existed ServiceAccount in this field. + type: string + serviceRefs: + description: |- + Defines a list of ServiceRef for a Component, enabling access to both external services and + Services provided by other Clusters. + + + Types of services: + + + - External services: Not managed by KubeBlocks or managed by a different KubeBlocks operator; + Require a ServiceDescriptor for connection details. + - Services provided by a Cluster: Managed by the same KubeBlocks operator; + identified using Cluster, Component and Service names. + + + ServiceRefs with identical `serviceRef.name` in the same Cluster are considered the same. + + + Example: + ```yaml + serviceRefs: + - name: "redis-sentinel" + serviceDescriptor: + name: "external-redis-sentinel" + - name: "postgres-cluster" + clusterServiceSelector: + cluster: "my-postgres-cluster" + service: + component: "postgresql" + ``` + The example above includes ServiceRefs to an external Redis Sentinel service and a PostgreSQL Cluster. + items: + properties: + cluster: + description: |- + Specifies the name of the KubeBlocks Cluster being referenced. + This is used when services from another KubeBlocks Cluster are consumed. + + + By default, the referenced KubeBlocks Cluster's `clusterDefinition.spec.connectionCredential` + will be utilized to bind to the current Component. This credential should include: + `endpoint`, `port`, `username`, and `password`. + + + Note: + + + - The `ServiceKind` and `ServiceVersion` specified in the service reference within the + ClusterDefinition are not validated when using this approach. + - If both `cluster` and `serviceDescriptor` are present, `cluster` will take precedence. + + + Deprecated since v0.9 since `clusterDefinition.spec.connectionCredential` is deprecated, + use `clusterServiceSelector` instead. + This field is maintained for backward compatibility and its use is discouraged. + Existing usage should be updated to the current preferred approach to avoid compatibility issues in future releases. + type: string + clusterServiceSelector: + description: |- + References a service provided by another KubeBlocks Cluster. + It specifies the ClusterService and the account credentials needed for access. + properties: + cluster: + description: The name of the Cluster being referenced. + type: string + credential: + description: |- + Specifies the SystemAccount to authenticate and establish a connection with the referenced Cluster. + The SystemAccount should be defined in `componentDefinition.spec.systemAccounts` + of the Component providing the service in the referenced Cluster. + properties: + component: + description: The name of the Component where the + credential resides in. + type: string + name: + description: The name of the credential (SystemAccount) + to reference. + type: string + required: + - component + - name + type: object + service: + description: Identifies a ClusterService from the + list of Services defined in `cluster.spec.services` + of the referenced Cluster. + properties: + component: + description: |- + The name of the Component where the Service resides in. + + + It is required when referencing a Component's Service. + type: string + port: + description: |- + The port name of the Service to be referenced. + + + If there is a non-zero node-port exist for the matched Service port, the node-port will be selected first. + + + If the referenced Service is of pod-service type (a Service per Pod), there will be multiple Service objects matched, + and the resolved value will be presented in the following format: service1.name:port1,service2.name:port2... + type: string + service: + description: |- + The name of the Service to be referenced. + + + Leave it empty to reference the default Service. Set it to "headless" to reference the default headless Service. + + + If the referenced Service is of pod-service type (a Service per Pod), there will be multiple Service objects matched, + and the resolved value will be presented in the following format: service1.name,service2.name... + type: string + required: + - service + type: object + required: + - cluster + type: object + name: + description: |- + Specifies the identifier of the service reference declaration. + It corresponds to the serviceRefDeclaration name defined in either: + + + - `componentDefinition.spec.serviceRefDeclarations[*].name` + - `clusterDefinition.spec.componentDefs[*].serviceRefDeclarations[*].name` (deprecated) + type: string + namespace: + description: |- + Specifies the namespace of the referenced Cluster or the namespace of the referenced ServiceDescriptor object. + If not provided, the referenced Cluster and ServiceDescriptor will be searched in the namespace of the current + Cluster by default. + type: string + serviceDescriptor: + description: |- + Specifies the name of the ServiceDescriptor object that describes a service provided by external sources. + + + When referencing a service provided by external sources, a ServiceDescriptor object is required to establish + the service binding. + The `serviceDescriptor.spec.serviceKind` and `serviceDescriptor.spec.serviceVersion` should match the serviceKind + and serviceVersion declared in the definition. + + + If both `cluster` and `serviceDescriptor` are specified, the `cluster` takes precedence. + type: string + required: + - name + type: object + type: array + serviceVersion: + description: |- + ServiceVersion specifies the version of the Service expected to be provisioned by this Component. + The version should follow the syntax and semantics of the "Semantic Versioning" specification (http://semver.org/). + If no version is specified, the latest available version will be used. + maxLength: 32 + type: string + services: + description: Overrides services defined in referenced ComponentDefinition + and expose endpoints that can be accessed by clients. + items: + properties: + annotations: + additionalProperties: + type: string + description: |- + If ServiceType is LoadBalancer, cloud provider related parameters can be put here. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#loadbalancer. + type: object + name: + description: References the ComponentService name defined + in the `componentDefinition.spec.services[*].name`. + maxLength: 25 + type: string + podService: + description: |- + Indicates whether to generate individual Services for each Pod. + If set to true, a separate Service will be created for each Pod in the Cluster. + type: boolean + serviceType: + default: ClusterIP + description: |- + Determines how the Service is exposed. Valid options are `ClusterIP`, `NodePort`, and `LoadBalancer`. + + + - `ClusterIP` allocates a Cluster-internal IP address for load-balancing to endpoints. + Endpoints are determined by the selector or if that is not specified, + they are determined by manual construction of an Endpoints object or EndpointSlice objects. + - `NodePort` builds on ClusterIP and allocates a port on every node which routes to the same endpoints as the ClusterIP. + - `LoadBalancer` builds on NodePort and creates an external load-balancer (if supported in the current cloud) + which routes to the same endpoints as the ClusterIP. + + + Note: although K8s Service type allows the 'ExternalName' type, it is not a valid option for ClusterComponentService. + + + For more info, see: + https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types. + enum: + - ClusterIP + - NodePort + - LoadBalancer + type: string + x-kubernetes-preserve-unknown-fields: true + required: + - name + type: object + type: array + stop: + description: |- + Stop the Component. + If set, all the computing resources will be released. + type: boolean + systemAccounts: + description: Overrides system accounts defined in referenced + ComponentDefinition. + items: + properties: + name: + description: The name of the system account. + type: string + passwordConfig: + description: |- + Specifies the policy for generating the account's password. + + + This field is immutable once set. + properties: + length: + default: 16 + description: The length of the password. + format: int32 + maximum: 32 + minimum: 8 + type: integer + letterCase: + default: MixedCases + description: The case of the letters in the password. + enum: + - LowerCases + - UpperCases + - MixedCases + type: string + numDigits: + default: 4 + description: The number of digits in the password. + format: int32 + maximum: 8 + minimum: 0 + type: integer + numSymbols: + default: 0 + description: The number of symbols in the password. + format: int32 + maximum: 8 + minimum: 0 + type: integer + seed: + description: |- + Seed to generate the account's password. + Cannot be updated. + type: string + type: object + secretRef: + description: |- + Refers to the secret from which data will be copied to create the new account. + + + This field is immutable once set. + properties: + name: + description: The unique identifier of the secret. + type: string + namespace: + description: The namespace where the secret is located. + type: string + required: + - name + - namespace + type: object + required: + - name + type: object + type: array + tls: + description: |- + A boolean flag that indicates whether the Component should use Transport Layer Security (TLS) + for secure communication. + When set to true, the Component will be configured to use TLS encryption for its network connections. + This ensures that the data transmitted between the Component and its clients or other Components is encrypted + and protected from unauthorized access. + If TLS is enabled, the Component may require additional configuration, such as specifying TLS certificates and keys, + to properly set up the secure communication channel. + type: boolean + updateStrategy: + description: |- + Defines the update strategy for the Component. + + + Deprecated since v0.9. + This field is maintained for backward compatibility and its use is discouraged. + Existing usage should be updated to the current preferred approach to avoid compatibility issues in future releases. + enum: + - Serial + - BestEffortParallel + - Parallel + type: string + userResourceRefs: + description: |- + Allows users to specify custom ConfigMaps and Secrets to be mounted as volumes + in the Cluster's Pods. + This is useful in scenarios where users need to provide additional resources to the Cluster, such as: + + + - Mounting custom scripts or configuration files during Cluster startup. + - Mounting Secrets as volumes to provide sensitive information, like S3 AK/SK, to the Cluster. + properties: + configMapRefs: + description: ConfigMapRefs defines the user-defined ConfigMaps. + items: + description: ConfigMapRef defines a reference to a ConfigMap. + properties: + asVolumeFrom: + description: AsVolumeFrom lists the names of containers + in which the volume should be mounted. + items: + type: string + type: array + x-kubernetes-list-type: set + configMap: + description: ConfigMap specifies the ConfigMap to + be mounted as a volume. + properties: + defaultMode: + description: |- + defaultMode is optional: mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + items: + description: |- + items if unspecified, each key-value pair in the Data field of the referenced + ConfigMap will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the ConfigMap, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within + a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + 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 + optional: + description: optional specify whether the ConfigMap + or its keys must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + mountPoint: + description: MountPoint is the filesystem path where + the volume will be mounted. + maxLength: 256 + pattern: ^/[a-z]([a-z0-9\-]*[a-z0-9])?$ + type: string + name: + description: Name is the name of the referenced ConfigMap + or Secret object. It must conform to DNS label standards. + maxLength: 63 + pattern: ^[a-z0-9]([a-z0-9\.\-]*[a-z0-9])?$ + type: string + subPath: + description: SubPath specifies a path within the volume + from which to mount. + type: string + required: + - configMap + - mountPoint + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + secretRefs: + description: SecretRefs defines the user-defined Secrets. + items: + description: SecretRef defines a reference to a Secret. + properties: + asVolumeFrom: + description: AsVolumeFrom lists the names of containers + in which the volume should be mounted. + items: + type: string + type: array + x-kubernetes-list-type: set + mountPoint: + description: MountPoint is the filesystem path where + the volume will be mounted. + maxLength: 256 + pattern: ^/[a-z]([a-z0-9\-]*[a-z0-9])?$ + type: string + name: + description: Name is the name of the referenced ConfigMap + or Secret object. It must conform to DNS label standards. + maxLength: 63 + pattern: ^[a-z0-9]([a-z0-9\.\-]*[a-z0-9])?$ + type: string + secret: + description: Secret specifies the Secret to be mounted + as a volume. + properties: + defaultMode: + description: |- + defaultMode is Optional: mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values + for mode bits. Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + items: + description: |- + items If unspecified, each key-value pair in the Data field of the referenced + Secret will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the Secret, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within + a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + optional: + description: optional field specify whether the + Secret or its keys must be defined + type: boolean + secretName: + description: |- + secretName is the name of the secret in the pod's namespace to use. + More info: https://kubernetes.io/docs/concepts/storage/volumes#secret + type: string + type: object + subPath: + description: SubPath specifies a path within the volume + from which to mount. + type: string + required: + - mountPoint + - name + - secret + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + volumeClaimTemplates: + description: |- + Specifies a list of PersistentVolumeClaim templates that represent the storage requirements for the Component. + Each template specifies the desired characteristics of a persistent volume, such as storage class, + size, and access modes. + These templates are used to dynamically provision persistent volumes for the Component. + items: + properties: + name: + description: |- + Refers to the name of a volumeMount defined in either: + + + - `componentDefinition.spec.runtime.containers[*].volumeMounts` + - `clusterDefinition.spec.componentDefs[*].podSpec.containers[*].volumeMounts` (deprecated) + + + The value of `name` must match the `name` field of a volumeMount specified in the corresponding `volumeMounts` array. + type: string + spec: + description: |- + Defines the desired characteristics of a PersistentVolumeClaim that will be created for the volume + with the mount name specified in the `name` field. + + + When a Pod is created for this ClusterComponent, a new PVC will be created based on the specification + defined in the `spec` field. The PVC will be associated with the volume mount specified by the `name` field. + properties: + accessModes: + description: |- + Contains the desired access modes the volume should have. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1. + items: + type: string + type: array + x-kubernetes-preserve-unknown-fields: true + resources: + description: |- + Represents the minimum resources the volume should have. + If the RecoverVolumeExpansionFailure feature is enabled, users are allowed to specify resource requirements that + are lower than the previous value but must still be higher than the capacity recorded in the status field of the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources. + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + x-kubernetes-preserve-unknown-fields: true + storageClassName: + description: |- + The name of the StorageClass required by the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1. + type: string + volumeMode: + description: Defines what type of volume is required + by the claim, either Block or Filesystem. + type: string + type: object + required: + - name + type: object + type: array + volumes: + description: List of volumes to override. + items: + description: Volume represents a named volume in a pod that + may be accessed by any container in the pod. + properties: + awsElasticBlockStore: + description: |- + awsElasticBlockStore represents an AWS Disk resource that is attached to a + kubelet's host machine and then exposed to the pod. + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + properties: + fsType: + description: |- + fsType is the filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + partition: + description: |- + partition is the partition in the volume that you want to mount. + If omitted, the default is to mount by volume name. + Examples: For volume /dev/sda1, you specify the partition as "1". + Similarly, the volume partition for /dev/sda is "0" (or you can leave the property empty). + format: int32 + type: integer + readOnly: + description: |- + readOnly value true will force the readOnly setting in VolumeMounts. + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + type: boolean + volumeID: + description: |- + volumeID is unique ID of the persistent disk resource in AWS (Amazon EBS volume). + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + type: string + required: + - volumeID + type: object + azureDisk: + description: azureDisk represents an Azure Data Disk mount + on the host and bind mount to the pod. + properties: + cachingMode: + description: 'cachingMode is the Host Caching mode: + None, Read Only, Read Write.' + type: string + diskName: + description: diskName is the Name of the data disk + in the blob storage + type: string + diskURI: + description: diskURI is the URI of data disk in the + blob storage + type: string + fsType: + description: |- + fsType is Filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + kind: + description: 'kind expected values are Shared: multiple + blob disks per storage account Dedicated: single + blob disk per storage account Managed: azure managed + data disk (only in managed availability set). defaults + to shared' + type: string + readOnly: + description: |- + readOnly Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + description: azureFile represents an Azure File Service + mount on the host and bind mount to the pod. + properties: + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretName: + description: secretName is the name of secret that + contains Azure Storage Account Name and Key + type: string + shareName: + description: shareName is the azure share Name + type: string + required: + - secretName + - shareName + type: object + cephfs: + description: cephFS represents a Ceph FS mount on the + host that shares a pod's lifetime + properties: + monitors: + description: |- + monitors is Required: Monitors is a collection of Ceph monitors + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + items: + type: string + type: array + path: + description: 'path is Optional: Used as the mounted + root, rather than the full Ceph tree, default is + /' + type: string + readOnly: + description: |- + readOnly is Optional: Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + type: boolean + secretFile: + description: |- + secretFile is Optional: SecretFile is the path to key ring for User, default is /etc/ceph/user.secret + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + type: string + secretRef: + description: |- + secretRef is Optional: SecretRef is reference to the authentication secret for User, default is empty. + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + 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 + user: + description: |- + user is optional: User is the rados user name, default is admin + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + type: string + required: + - monitors + type: object + cinder: + description: |- + cinder represents a cinder volume attached and mounted on kubelets host machine. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + type: string + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + type: boolean + secretRef: + description: |- + secretRef is optional: points to a secret object containing parameters used to connect + to OpenStack. + 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 + volumeID: + description: |- + volumeID used to identify the volume in cinder. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + type: string + required: + - volumeID + type: object + configMap: + description: configMap represents a configMap that should + populate this volume + properties: + defaultMode: + description: |- + defaultMode is optional: mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + items: + description: |- + items if unspecified, each key-value pair in the Data field of the referenced + ConfigMap will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the ConfigMap, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within + a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + 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 + optional: + description: optional specify whether the ConfigMap + or its keys must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + csi: + description: csi (Container Storage Interface) represents + ephemeral storage that is handled by certain external + CSI drivers (Beta feature). + properties: + driver: + description: |- + driver is the name of the CSI driver that handles this volume. + Consult with your admin for the correct name as registered in the cluster. + type: string + fsType: + description: |- + fsType to mount. Ex. "ext4", "xfs", "ntfs". + If not provided, the empty value is passed to the associated CSI driver + which will determine the default filesystem to apply. + type: string + nodePublishSecretRef: + description: |- + nodePublishSecretRef is a reference to the secret object containing + sensitive information to pass to the CSI driver to complete the CSI + NodePublishVolume and NodeUnpublishVolume calls. + This field is optional, and may be empty if no secret is required. If the + secret object contains more than one secret, all secret references are passed. + 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 + readOnly: + description: |- + readOnly specifies a read-only configuration for the volume. + Defaults to false (read/write). + type: boolean + volumeAttributes: + additionalProperties: + type: string + description: |- + volumeAttributes stores driver-specific properties that are passed to the CSI + driver. Consult your driver's documentation for supported values. + type: object + required: + - driver + type: object + downwardAPI: + description: downwardAPI represents downward API about + the pod that should populate this volume + properties: + defaultMode: + description: |- + Optional: mode bits to use on created files by default. Must be a + Optional: mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + items: + description: Items is a list of downward API volume + file + items: + description: DownwardAPIVolumeFile represents information + to create the file containing the pod field + properties: + fieldRef: + description: 'Required: Selects a field of the + pod: only annotations, labels, name and namespace + are supported.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select + in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + description: |- + Optional: mode bits used to set permissions on this file, must be an octal value + between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: 'Required: Path is the relative + path name of the file to be created. Must + not be absolute or contain the ''..'' path. + Must be utf-8 encoded. The first item of the + relative path must not start with ''..''' + type: string + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported. + properties: + containerName: + description: 'Container name: required for + volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format + of the exposed resources, defaults to + "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + type: object + emptyDir: + description: |- + emptyDir represents a temporary directory that shares a pod's lifetime. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir + properties: + medium: + description: |- + medium represents what type of storage medium should back this directory. + The default is "" which means to use the node's default medium. + Must be an empty string (default) or Memory. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + description: |- + sizeLimit is the total amount of local storage required for this EmptyDir volume. + The size limit is also applicable for memory medium. + The maximum usage on memory medium EmptyDir would be the minimum value between + the SizeLimit specified here and the sum of memory limits of all containers in a pod. + The default is nil which means that the limit is undefined. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + description: |- + ephemeral represents a volume that is handled by a cluster storage driver. + The volume's lifecycle is tied to the pod that defines it - it will be created before the pod starts, + and deleted when the pod is removed. + + + Use this if: + a) the volume is only needed while the pod runs, + b) features of normal volumes like restoring from snapshot or capacity + tracking are needed, + c) the storage driver is specified through a storage class, and + d) the storage driver supports dynamic volume provisioning through + a PersistentVolumeClaim (see EphemeralVolumeSource for more + information on the connection between this volume type + and PersistentVolumeClaim). + + + Use PersistentVolumeClaim or one of the vendor-specific + APIs for volumes that persist for longer than the lifecycle + of an individual pod. + + + Use CSI for light-weight local ephemeral volumes if the CSI driver is meant to + be used that way - see the documentation of the driver for + more information. + + + A pod can use both types of ephemeral volumes and + persistent volumes at the same time. + properties: + volumeClaimTemplate: + description: |- + Will be used to create a stand-alone PVC to provision the volume. + The pod in which this EphemeralVolumeSource is embedded will be the + owner of the PVC, i.e. the PVC will be deleted together with the + pod. The name of the PVC will be `-` where + `` is the name from the `PodSpec.Volumes` array + entry. Pod validation will reject the pod if the concatenated name + is not valid for a PVC (for example, too long). + + + An existing PVC with that name that is not owned by the pod + will *not* be used for the pod to avoid using an unrelated + volume by mistake. Starting the pod is then blocked until + the unrelated PVC is removed. If such a pre-created PVC is + meant to be used by the pod, the PVC has to updated with an + owner reference to the pod once the pod exists. Normally + this should not be necessary, but it may be useful when + manually reconstructing a broken cluster. + + + This field is read-only and no changes will be made by Kubernetes + to the PVC after it has been created. + + + Required, must not be nil. + properties: + metadata: + description: |- + May contain labels and annotations that will be copied into the PVC + when creating it. No other fields are allowed and will be rejected during + validation. + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + description: |- + The specification for the PersistentVolumeClaim. The entire content is + copied unchanged into the PVC that gets created from this + template. The same fields as in a PersistentVolumeClaim + are also valid here. + properties: + accessModes: + description: |- + accessModes contains the desired access modes the volume should have. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1 + items: + type: string + type: array + dataSource: + description: |- + dataSource field can be used to specify either: + * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) + * An existing PVC (PersistentVolumeClaim) + If the provisioner or an external controller can support the specified data source, + it will create a new volume based on the contents of the specified data source. + When the AnyVolumeDataSource feature gate is enabled, dataSource contents will be copied to dataSourceRef, + and dataSourceRef contents will be copied to dataSource when dataSourceRef.namespace is not specified. + If the namespace is specified, then dataSourceRef will not be copied to dataSource. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource + being referenced + type: string + name: + description: Name is the name of resource + being referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + description: |- + dataSourceRef specifies the object from which to populate the volume with data, if a non-empty + volume is desired. This may be any object from a non-empty API group (non + core object) or a PersistentVolumeClaim object. + When this field is specified, volume binding will only succeed if the type of + the specified object matches some installed volume populator or dynamic + provisioner. + This field will replace the functionality of the dataSource field and as such + if both fields are non-empty, they must have the same value. For backwards + compatibility, when namespace isn't specified in dataSourceRef, + both fields (dataSource and dataSourceRef) will be set to the same + value automatically if one of them is empty and the other is non-empty. + When namespace is specified in dataSourceRef, + dataSource isn't set to the same value and must be empty. + There are three important differences between dataSource and dataSourceRef: + * While dataSource only allows two specific types of objects, dataSourceRef + allows any non-core object, as well as PersistentVolumeClaim objects. + * While dataSource ignores disallowed values (dropping them), dataSourceRef + preserves all values, and generates an error if a disallowed value is + specified. + * While dataSource only allows local objects, dataSourceRef allows objects + in any namespaces. + (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled. + (Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource + being referenced + type: string + name: + description: Name is the name of resource + being referenced + type: string + namespace: + description: |- + Namespace is the namespace of resource being referenced + Note that when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details. + (Alpha) This field requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + type: string + required: + - kind + - name + type: object + resources: + description: |- + resources represents the minimum resources the volume should have. + If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements + that are lower than previous value but must still be higher than capacity recorded in the + status field of the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + selector: + description: selector is a label query over + volumes to consider for binding. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + description: |- + storageClassName is the name of the StorageClass required by the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1 + type: string + volumeAttributesClassName: + description: |- + volumeAttributesClassName may be used to set the VolumeAttributesClass used by this claim. + If specified, the CSI driver will create or update the volume with the attributes defined + in the corresponding VolumeAttributesClass. This has a different purpose than storageClassName, + it can be changed after the claim is created. An empty string value means that no VolumeAttributesClass + will be applied to the claim but it's not allowed to reset this field to empty string once it is set. + If unspecified and the PersistentVolumeClaim is unbound, the default VolumeAttributesClass + will be set by the persistentvolume controller if it exists. + If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be + set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource + exists. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#volumeattributesclass + (Alpha) Using this field requires the VolumeAttributesClass feature gate to be enabled. + type: string + volumeMode: + description: |- + volumeMode defines what type of volume is required by the claim. + Value of Filesystem is implied when not included in claim spec. + type: string + volumeName: + description: volumeName is the binding reference + to the PersistentVolume backing this claim. + type: string + type: object + required: + - spec + type: object + type: object + fc: + description: fc represents a Fibre Channel resource that + is attached to a kubelet's host machine and then exposed + to the pod. + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + lun: + description: 'lun is Optional: FC target lun number' + format: int32 + type: integer + readOnly: + description: |- + readOnly is Optional: Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + targetWWNs: + description: 'targetWWNs is Optional: FC target worldwide + names (WWNs)' + items: + type: string + type: array + wwids: + description: |- + wwids Optional: FC volume world wide identifiers (wwids) + Either wwids or combination of targetWWNs and lun must be set, but not both simultaneously. + items: + type: string + type: array + type: object + flexVolume: + description: |- + flexVolume represents a generic volume resource that is + provisioned/attached using an exec based plugin. + properties: + driver: + description: driver is the name of the driver to use + for this volume. + type: string + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". The default filesystem depends on FlexVolume script. + type: string + options: + additionalProperties: + type: string + description: 'options is Optional: this field holds + extra command options if any.' + type: object + readOnly: + description: |- + readOnly is Optional: defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: |- + secretRef is Optional: secretRef is reference to the secret object containing + sensitive information to pass to the plugin scripts. This may be + empty if no secret object is specified. If the secret object + contains more than one secret, all secrets are passed to the plugin + scripts. + 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 + required: + - driver + type: object + flocker: + description: flocker represents a Flocker volume attached + to a kubelet's host machine. This depends on the Flocker + control service being running + properties: + datasetName: + description: |- + datasetName is Name of the dataset stored as metadata -> name on the dataset for Flocker + should be considered as deprecated + type: string + datasetUUID: + description: datasetUUID is the UUID of the dataset. + This is unique identifier of a Flocker dataset + type: string + type: object + gcePersistentDisk: + description: |- + gcePersistentDisk represents a GCE Disk resource that is attached to a + kubelet's host machine and then exposed to the pod. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + properties: + fsType: + description: |- + fsType is filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + partition: + description: |- + partition is the partition in the volume that you want to mount. + If omitted, the default is to mount by volume name. + Examples: For volume /dev/sda1, you specify the partition as "1". + Similarly, the volume partition for /dev/sda is "0" (or you can leave the property empty). + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + format: int32 + type: integer + pdName: + description: |- + pdName is unique name of the PD resource in GCE. Used to identify the disk in GCE. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + type: string + readOnly: + description: |- + readOnly here will force the ReadOnly setting in VolumeMounts. + Defaults to false. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + type: boolean + required: + - pdName + type: object + gitRepo: + description: |- + gitRepo represents a git repository at a particular revision. + DEPRECATED: GitRepo is deprecated. To provision a container with a git repo, mount an + EmptyDir into an InitContainer that clones the repo using git, then mount the EmptyDir + into the Pod's container. + properties: + directory: + description: |- + directory is the target directory name. + Must not contain or start with '..'. If '.' is supplied, the volume directory will be the + git repository. Otherwise, if specified, the volume will contain the git repository in + the subdirectory with the given name. + type: string + repository: + description: repository is the URL + type: string + revision: + description: revision is the commit hash for the specified + revision. + type: string + required: + - repository + type: object + glusterfs: + description: |- + glusterfs represents a Glusterfs mount on the host that shares a pod's lifetime. + More info: https://examples.k8s.io/volumes/glusterfs/README.md + properties: + endpoints: + description: |- + endpoints is the endpoint name that details Glusterfs topology. + More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod + type: string + path: + description: |- + path is the Glusterfs volume path. + More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod + type: string + readOnly: + description: |- + readOnly here will force the Glusterfs volume to be mounted with read-only permissions. + Defaults to false. + More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod + type: boolean + required: + - endpoints + - path + type: object + hostPath: + description: |- + hostPath represents a pre-existing file or directory on the host + machine that is directly exposed to the container. This is generally + used for system agents or other privileged things that are allowed + to see the host machine. Most containers will NOT need this. + More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + --- + TODO(jonesdl) We need to restrict who can use host directory mounts and who can/can not + mount host directories as read/write. + properties: + path: + description: |- + path of the directory on the host. + If the path is a symlink, it will follow the link to the real path. + More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + type: string + type: + description: |- + type for HostPath Volume + Defaults to "" + More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + type: string + required: + - path + type: object + iscsi: + description: |- + iscsi represents an ISCSI Disk resource that is attached to a + kubelet's host machine and then exposed to the pod. + More info: https://examples.k8s.io/volumes/iscsi/README.md + properties: + chapAuthDiscovery: + description: chapAuthDiscovery defines whether support + iSCSI Discovery CHAP authentication + type: boolean + chapAuthSession: + description: chapAuthSession defines whether support + iSCSI Session CHAP authentication + type: boolean + fsType: + description: |- + fsType is the filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#iscsi + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + initiatorName: + description: |- + initiatorName is the custom iSCSI Initiator Name. + If initiatorName is specified with iscsiInterface simultaneously, new iSCSI interface + : will be created for the connection. + type: string + iqn: + description: iqn is the target iSCSI Qualified Name. + type: string + iscsiInterface: + description: |- + iscsiInterface is the interface Name that uses an iSCSI transport. + Defaults to 'default' (tcp). + type: string + lun: + description: lun represents iSCSI Target Lun number. + format: int32 + type: integer + portals: + description: |- + portals is the iSCSI Target Portal List. The portal is either an IP or ip_addr:port if the port + is other than default (typically TCP ports 860 and 3260). + items: + type: string + type: array + readOnly: + description: |- + readOnly here will force the ReadOnly setting in VolumeMounts. + Defaults to false. + type: boolean + secretRef: + description: secretRef is the CHAP Secret for iSCSI + target and initiator authentication + 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 + targetPortal: + description: |- + targetPortal is iSCSI Target Portal. The Portal is either an IP or ip_addr:port if the port + is other than default (typically TCP ports 860 and 3260). + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + description: |- + name of the volume. + Must be a DNS_LABEL and unique within the pod. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + nfs: + description: |- + nfs represents an NFS mount on the host that shares a pod's lifetime + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + properties: + path: + description: |- + path that is exported by the NFS server. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + type: string + readOnly: + description: |- + readOnly here will force the NFS export to be mounted with read-only permissions. + Defaults to false. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + type: boolean + server: + description: |- + server is the hostname or IP address of the NFS server. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + description: |- + persistentVolumeClaimVolumeSource represents a reference to a + PersistentVolumeClaim in the same namespace. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims + properties: + claimName: + description: |- + claimName is the name of a PersistentVolumeClaim in the same namespace as the pod using this volume. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims + type: string + readOnly: + description: |- + readOnly Will force the ReadOnly setting in VolumeMounts. + Default false. + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + description: photonPersistentDisk represents a PhotonController + persistent disk attached and mounted on kubelets host + machine + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + pdID: + description: pdID is the ID that identifies Photon + Controller persistent disk + type: string + required: + - pdID + type: object + portworxVolume: + description: portworxVolume represents a portworx volume + attached and mounted on kubelets host machine + properties: + fsType: + description: |- + fSType represents the filesystem type to mount + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs". Implicitly inferred to be "ext4" if unspecified. + type: string + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + volumeID: + description: volumeID uniquely identifies a Portworx + volume + type: string + required: + - volumeID + type: object + projected: + description: projected items for all in one resources + secrets, configmaps, and downward API + properties: + defaultMode: + description: |- + defaultMode are the mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + sources: + description: sources is the list of volume projections + items: + description: Projection that may be projected along + with other supported volume types + properties: + clusterTrustBundle: + description: |- + ClusterTrustBundle allows a pod to access the `.spec.trustBundle` field + of ClusterTrustBundle objects in an auto-updating file. + + + Alpha, gated by the ClusterTrustBundleProjection feature gate. + + + ClusterTrustBundle objects can either be selected by name, or by the + combination of signer name and a label selector. + + + Kubelet performs aggressive normalization of the PEM contents written + into the pod filesystem. Esoteric PEM features such as inter-block + comments and block headers are stripped. Certificates are deduplicated. + The ordering of certificates within the file is arbitrary, and Kubelet + may change the order over time. + properties: + labelSelector: + description: |- + Select all ClusterTrustBundles that match this label selector. Only has + effect if signerName is set. Mutually-exclusive with name. If unset, + interpreted as "match nothing". If set but empty, interpreted as "match + everything". + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + name: + description: |- + Select a single ClusterTrustBundle by object name. Mutually-exclusive + with signerName and labelSelector. + type: string + optional: + description: |- + If true, don't block pod startup if the referenced ClusterTrustBundle(s) + aren't available. If using name, then the named ClusterTrustBundle is + allowed not to exist. If using signerName, then the combination of + signerName and labelSelector is allowed to match zero + ClusterTrustBundles. + type: boolean + path: + description: Relative path from the volume + root to write the bundle. + type: string + signerName: + description: |- + Select all ClusterTrustBundles that match this signer name. + Mutually-exclusive with name. The contents of all selected + ClusterTrustBundles will be unified and deduplicated. + type: string + required: + - path + type: object + configMap: + description: configMap information about the + configMap data to project + properties: + items: + description: |- + items if unspecified, each key-value pair in the Data field of the referenced + ConfigMap will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the ConfigMap, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path + within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + 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 + optional: + description: optional specify whether the + ConfigMap or its keys must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + downwardAPI: + description: downwardAPI information about the + downwardAPI data to project + properties: + items: + description: Items is a list of DownwardAPIVolume + file + items: + description: DownwardAPIVolumeFile represents + information to create the file containing + the pod field + properties: + fieldRef: + description: 'Required: Selects a + field of the pod: only annotations, + labels, name and namespace are supported.' + properties: + apiVersion: + description: Version of the schema + the FieldPath is written in + terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field + to select in the specified API + version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + description: |- + Optional: mode bits used to set permissions on this file, must be an octal value + between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: 'Required: Path is the + relative path name of the file to + be created. Must not be absolute + or contain the ''..'' path. Must + be utf-8 encoded. The first item + of the relative path must not start + with ''..''' + type: string + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported. + properties: + containerName: + description: 'Container name: + required for volumes, optional + for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output + format of the exposed resources, + defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource + to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + type: object + secret: + description: secret information about the secret + data to project + properties: + items: + description: |- + items if unspecified, each key-value pair in the Data field of the referenced + Secret will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the Secret, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path + within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + 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 + optional: + description: optional field specify whether + the Secret or its key must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + serviceAccountToken: + description: serviceAccountToken is information + about the serviceAccountToken data to project + properties: + audience: + description: |- + audience is the intended audience of the token. A recipient of a token + must identify itself with an identifier specified in the audience of the + token, and otherwise should reject the token. The audience defaults to the + identifier of the apiserver. + type: string + expirationSeconds: + description: |- + expirationSeconds is the requested duration of validity of the service + account token. As the token approaches expiration, the kubelet volume + plugin will proactively rotate the service account token. The kubelet will + start trying to rotate the token if the token is older than 80 percent of + its time to live or if the token is older than 24 hours.Defaults to 1 hour + and must be at least 10 minutes. + format: int64 + type: integer + path: + description: |- + path is the path relative to the mount point of the file to project the + token into. + type: string + required: + - path + type: object + type: object + type: array + type: object + quobyte: + description: quobyte represents a Quobyte mount on the + host that shares a pod's lifetime + properties: + group: + description: |- + group to map volume access to + Default is no group + type: string + readOnly: + description: |- + readOnly here will force the Quobyte volume to be mounted with read-only permissions. + Defaults to false. + type: boolean + registry: + description: |- + registry represents a single or multiple Quobyte Registry services + specified as a string as host:port pair (multiple entries are separated with commas) + which acts as the central registry for volumes + type: string + tenant: + description: |- + tenant owning the given Quobyte volume in the Backend + Used with dynamically provisioned Quobyte volumes, value is set by the plugin + type: string + user: + description: |- + user to map volume access to + Defaults to serivceaccount user + type: string + volume: + description: volume is a string that references an + already created Quobyte volume by name. + type: string + required: + - registry + - volume + type: object + rbd: + description: |- + rbd represents a Rados Block Device mount on the host that shares a pod's lifetime. + More info: https://examples.k8s.io/volumes/rbd/README.md + properties: + fsType: + description: |- + fsType is the filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#rbd + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + image: + description: |- + image is the rados image name. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + keyring: + description: |- + keyring is the path to key ring for RBDUser. + Default is /etc/ceph/keyring. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + monitors: + description: |- + monitors is a collection of Ceph monitors. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + items: + type: string + type: array + pool: + description: |- + pool is the rados pool name. + Default is rbd. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + readOnly: + description: |- + readOnly here will force the ReadOnly setting in VolumeMounts. + Defaults to false. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: boolean + secretRef: + description: |- + secretRef is name of the authentication secret for RBDUser. If provided + overrides keyring. + Default is nil. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + 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 + user: + description: |- + user is the rados user name. + Default is admin. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + required: + - image + - monitors + type: object + scaleIO: + description: scaleIO represents a ScaleIO persistent volume + attached and mounted on Kubernetes nodes. + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". + Default is "xfs". + type: string + gateway: + description: gateway is the host address of the ScaleIO + API Gateway. + type: string + protectionDomain: + description: protectionDomain is the name of the ScaleIO + Protection Domain for the configured storage. + type: string + readOnly: + description: |- + readOnly Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: |- + secretRef references to the secret for ScaleIO user and other + sensitive information. If this is not provided, Login operation will fail. + 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 + sslEnabled: + description: sslEnabled Flag enable/disable SSL communication + with Gateway, default false + type: boolean + storageMode: + description: |- + storageMode indicates whether the storage for a volume should be ThickProvisioned or ThinProvisioned. + Default is ThinProvisioned. + type: string + storagePool: + description: storagePool is the ScaleIO Storage Pool + associated with the protection domain. + type: string + system: + description: system is the name of the storage system + as configured in ScaleIO. + type: string + volumeName: + description: |- + volumeName is the name of a volume already created in the ScaleIO system + that is associated with this volume source. + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + description: |- + secret represents a secret that should populate this volume. + More info: https://kubernetes.io/docs/concepts/storage/volumes#secret + properties: + defaultMode: + description: |- + defaultMode is Optional: mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values + for mode bits. Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + items: + description: |- + items If unspecified, each key-value pair in the Data field of the referenced + Secret will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the Secret, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within + a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + optional: + description: optional field specify whether the Secret + or its keys must be defined + type: boolean + secretName: + description: |- + secretName is the name of the secret in the pod's namespace to use. + More info: https://kubernetes.io/docs/concepts/storage/volumes#secret + type: string + type: object + storageos: + description: storageOS represents a StorageOS volume attached + and mounted on Kubernetes nodes. + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: |- + secretRef specifies the secret to use for obtaining the StorageOS API + credentials. If not specified, default values will be attempted. + 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 + volumeName: + description: |- + volumeName is the human-readable name of the StorageOS volume. Volume + names are only unique within a namespace. + type: string + volumeNamespace: + description: |- + volumeNamespace specifies the scope of the volume within StorageOS. If no + namespace is specified then the Pod's namespace will be used. This allows the + Kubernetes name scoping to be mirrored within StorageOS for tighter integration. + Set VolumeName to any name to override the default behaviour. + Set to "default" if you are not using namespaces within StorageOS. + Namespaces that do not pre-exist within StorageOS will be created. + type: string + type: object + vsphereVolume: + description: vsphereVolume represents a vSphere volume + attached and mounted on kubelets host machine + properties: + fsType: + description: |- + fsType is filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + storagePolicyID: + description: storagePolicyID is the storage Policy + Based Management (SPBM) profile ID associated with + the StoragePolicyName. + type: string + storagePolicyName: + description: storagePolicyName is the storage Policy + Based Management (SPBM) profile name. + type: string + volumePath: + description: volumePath is the path that identifies + vSphere volume vmdk + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + required: + - replicas + type: object + maxItems: 128 + minItems: 1 + type: array + x-kubernetes-validations: + - message: duplicated component + rule: self.all(x, size(self.filter(c, c.name == x.name)) == 1) + - message: two kinds of definition API can not be used simultaneously + rule: self.all(x, size(self.filter(c, has(c.componentDef))) == 0) + || self.all(x, size(self.filter(c, has(c.componentDef))) == size(self)) + runtimeClassName: + description: Specifies runtimeClassName for all Pods managed by this + Cluster. + type: string + schedulingPolicy: + description: Specifies the scheduling policy for the Cluster. + properties: + affinity: + description: Specifies a group of affinity scheduling rules of + the Cluster, including NodeAffinity, PodAffinity, and PodAntiAffinity. + properties: + nodeAffinity: + description: Describes node affinity scheduling rules for + the pod. + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node matches the corresponding matchExpressions; the + node(s) with the highest sum are the most preferred. + items: + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). + properties: + preference: + description: A node selector term, associated with + the corresponding weight. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + weight: + description: Weight associated with matching the + corresponding nodeSelectorTerm, in the range 1-100. + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. + properties: + nodeSelectorTerms: + description: Required. A list of node selector terms. + The terms are ORed. + items: + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + type: array + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + description: Describes pod affinity scheduling rules (e.g. + co-locate this pod in the same node, zone, etc. as some + other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred + node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated + with the corresponding weight. + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. + Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: |- + weight associated with matching the corresponding podAffinityTerm, + in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. + items: + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. + Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + description: Describes pod anti-affinity scheduling rules + (e.g. avoid putting this pod in the same node, zone, etc. + as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the anti-affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred + node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated + with the corresponding weight. + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. + Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: |- + weight associated with matching the corresponding podAffinityTerm, + in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the anti-affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the anti-affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. + items: + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. + Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + nodeName: + description: |- + NodeName is a request to schedule this Pod onto a specific node. If it is non-empty, + the scheduler simply schedules this Pod onto that node, assuming that it fits resource + requirements. + type: string + nodeSelector: + additionalProperties: + type: string + description: |- + NodeSelector is a selector which must be true for the Pod to fit on a node. + Selector which must match a node's labels for the Pod to be scheduled on that node. + More info: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ + type: object + x-kubernetes-map-type: atomic + schedulerName: + description: |- + If specified, the Pod will be dispatched by specified scheduler. + If not specified, the Pod will be dispatched by default scheduler. + type: string + tolerations: + description: |- + Allows Pods to be scheduled onto nodes with matching taints. + Each toleration in the array allows the Pod to tolerate node taints based on + specified `key`, `value`, `effect`, and `operator`. + + + - The `key`, `value`, and `effect` identify the taint that the toleration matches. + - The `operator` determines how the toleration matches the taint. + + + Pods with matching tolerations are allowed to be scheduled on tainted nodes, typically reserved for specific purposes. + items: + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . + properties: + effect: + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. + type: string + operator: + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. + type: string + tolerationSeconds: + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. + format: int64 + type: integer + value: + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. + type: string + type: object + type: array + topologySpreadConstraints: + description: |- + TopologySpreadConstraints describes how a group of Pods ought to spread across topology + domains. Scheduler will schedule Pods in a way which abides by the constraints. + All topologySpreadConstraints are ANDed. + items: + description: TopologySpreadConstraint specifies how to spread + matching pods among the given topology. + properties: + labelSelector: + description: |- + LabelSelector is used to find matching pods. + Pods that match this label selector are counted to determine the number of pods + in their corresponding topology domain. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select the pods over which + spreading will be calculated. The keys are used to lookup values from the + incoming pod labels, those key-value labels are ANDed with labelSelector + to select the group of existing pods over which spreading will be calculated + for the incoming pod. The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + MatchLabelKeys cannot be set when LabelSelector isn't set. + Keys that don't exist in the incoming pod labels will + be ignored. A null or empty list means only match against labelSelector. + + + This is a beta field and requires the MatchLabelKeysInPodTopologySpread feature gate to be enabled (enabled by default). + items: + type: string + type: array + x-kubernetes-list-type: atomic + maxSkew: + description: |- + MaxSkew describes the degree to which pods may be unevenly distributed. + When `whenUnsatisfiable=DoNotSchedule`, it is the maximum permitted difference + between the number of matching pods in the target topology and the global minimum. + The global minimum is the minimum number of matching pods in an eligible domain + or zero if the number of eligible domains is less than MinDomains. + For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same + labelSelector spread as 2/2/1: + In this case, the global minimum is 1. + | zone1 | zone2 | zone3 | + | P P | P P | P | + - if MaxSkew is 1, incoming pod can only be scheduled to zone3 to become 2/2/2; + scheduling it onto zone1(zone2) would make the ActualSkew(3-1) on zone1(zone2) + violate MaxSkew(1). + - if MaxSkew is 2, incoming pod can be scheduled onto any zone. + When `whenUnsatisfiable=ScheduleAnyway`, it is used to give higher precedence + to topologies that satisfy it. + It's a required field. Default value is 1 and 0 is not allowed. + format: int32 + type: integer + minDomains: + description: |- + MinDomains indicates a minimum number of eligible domains. + When the number of eligible domains with matching topology keys is less than minDomains, + Pod Topology Spread treats "global minimum" as 0, and then the calculation of Skew is performed. + And when the number of eligible domains with matching topology keys equals or greater than minDomains, + this value has no effect on scheduling. + As a result, when the number of eligible domains is less than minDomains, + scheduler won't schedule more than maxSkew Pods to those domains. + If value is nil, the constraint behaves as if MinDomains is equal to 1. + Valid values are integers greater than 0. + When value is not nil, WhenUnsatisfiable must be DoNotSchedule. + + + For example, in a 3-zone cluster, MaxSkew is set to 2, MinDomains is set to 5 and pods with the same + labelSelector spread as 2/2/2: + | zone1 | zone2 | zone3 | + | P P | P P | P P | + The number of domains is less than 5(MinDomains), so "global minimum" is treated as 0. + In this situation, new pod with the same labelSelector cannot be scheduled, + because computed skew will be 3(3 - 0) if new Pod is scheduled to any of the three zones, + it will violate MaxSkew. + + + This is a beta field and requires the MinDomainsInPodTopologySpread feature gate to be enabled (enabled by default). + format: int32 + type: integer + nodeAffinityPolicy: + description: |- + NodeAffinityPolicy indicates how we will treat Pod's nodeAffinity/nodeSelector + when calculating pod topology spread skew. Options are: + - Honor: only nodes matching nodeAffinity/nodeSelector are included in the calculations. + - Ignore: nodeAffinity/nodeSelector are ignored. All nodes are included in the calculations. + + + If this value is nil, the behavior is equivalent to the Honor policy. + This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag. + type: string + nodeTaintsPolicy: + description: |- + NodeTaintsPolicy indicates how we will treat node taints when calculating + pod topology spread skew. Options are: + - Honor: nodes without taints, along with tainted nodes for which the incoming pod + has a toleration, are included. + - Ignore: node taints are ignored. All nodes are included. + + + If this value is nil, the behavior is equivalent to the Ignore policy. + This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag. + type: string + topologyKey: + description: |- + TopologyKey is the key of node labels. Nodes that have a label with this key + and identical values are considered to be in the same topology. + We consider each as a "bucket", and try to put balanced number + of pods into each bucket. + We define a domain as a particular instance of a topology. + Also, we define an eligible domain as a domain whose nodes meet the requirements of + nodeAffinityPolicy and nodeTaintsPolicy. + e.g. If TopologyKey is "kubernetes.io/hostname", each Node is a domain of that topology. + And, if TopologyKey is "topology.kubernetes.io/zone", each zone is a domain of that topology. + It's a required field. + type: string + whenUnsatisfiable: + description: |- + WhenUnsatisfiable indicates how to deal with a pod if it doesn't satisfy + the spread constraint. + - DoNotSchedule (default) tells the scheduler not to schedule it. + - ScheduleAnyway tells the scheduler to schedule the pod in any location, + but giving higher precedence to topologies that would help reduce the + skew. + A constraint is considered "Unsatisfiable" for an incoming pod + if and only if every possible node assignment for that pod would violate + "MaxSkew" on some topology. + For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same + labelSelector spread as 3/1/1: + | zone1 | zone2 | zone3 | + | P P P | P | P | + If WhenUnsatisfiable is set to DoNotSchedule, incoming pod can only be scheduled + to zone2(zone3) to become 3/2/1(3/1/2) as ActualSkew(2-1) on zone2(zone3) satisfies + MaxSkew(1). In other words, the cluster can still be imbalanced, but scheduler + won't make it *more* imbalanced. + It's a required field. + type: string + required: + - maxSkew + - topologyKey + - whenUnsatisfiable + type: object + type: array + type: object + services: + description: |- + Defines a list of additional Services that are exposed by a Cluster. + This field allows Services of selected Components, either from `componentSpecs` or `shardingSpecs` to be exposed, + alongside Services defined with ComponentService. + + + Services defined here can be referenced by other clusters using the ServiceRefClusterSelector. + items: + description: |- + ClusterService defines a service that is exposed externally, allowing entities outside the cluster to access it. + For example, external applications, or other Clusters. + And another Cluster managed by the same KubeBlocks operator can resolve the address exposed by a ClusterService + using the `serviceRef` field. + + + When a Component needs to access another Cluster's ClusterService using the `serviceRef` field, + it must also define the service type and version information in the `componentDefinition.spec.serviceRefDeclarations` + section. + properties: + annotations: + additionalProperties: + type: string + description: |- + If ServiceType is LoadBalancer, cloud provider related parameters can be put here + More info: https://kubernetes.io/docs/concepts/services-networking/service/#loadbalancer. + type: object + componentSelector: + description: |- + Extends the ServiceSpec.Selector by allowing the specification of a component, to be used as a selector for the service. + Note that this and the `shardingSelector` are mutually exclusive and cannot be set simultaneously. + type: string + name: + description: |- + Name defines the name of the service. + otherwise, it indicates the name of the service. + Others can refer to this service by its name. (e.g., connection credential) + Cannot be updated. + maxLength: 25 + type: string + roleSelector: + description: "Extends the above `serviceSpec.selector` by allowing + you to specify defined role as selector for the service.\nWhen + `roleSelector` is set, it adds a label selector \"kubeblocks.io/role: + {roleSelector}\"\nto the `serviceSpec.selector`.\nExample + usage:\n\n\n\t roleSelector: \"leader\"\n\n\nIn this example, + setting `roleSelector` to \"leader\" will add a label selector\n\"kubeblocks.io/role: + leader\" to the `serviceSpec.selector`.\nThis means that the + service will select and route traffic to Pods with the label\n\"kubeblocks.io/role\" + set to \"leader\".\n\n\nNote that if `podService` sets to + true, RoleSelector will be ignored.\nThe `podService` flag + takes precedence over `roleSelector` and generates a service + for each Pod." + type: string + serviceName: + description: |- + ServiceName defines the name of the underlying service object. + If not specified, the default service name with different patterns will be used: + + + - CLUSTER_NAME: for cluster-level services + - CLUSTER_NAME-COMPONENT_NAME: for component-level services + + + Only one default service name is allowed. + Cannot be updated. + maxLength: 25 + pattern: ^[a-z]([a-z0-9\-]*[a-z0-9])?$ + type: string + shardingSelector: + description: |- + Extends the ServiceSpec.Selector by allowing the specification of a sharding name, which is defined in + `cluster.spec.shardingSpecs[*].name`, to be used as a selector for the service. + Note that this and the `componentSelector` are mutually exclusive and cannot be set simultaneously. + type: string + spec: + description: |- + Spec defines the behavior of a service. + https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status + properties: + allocateLoadBalancerNodePorts: + description: |- + allocateLoadBalancerNodePorts defines if NodePorts will be automatically + allocated for services with type LoadBalancer. Default is "true". It + may be set to "false" if the cluster load-balancer does not rely on + NodePorts. If the caller requests specific NodePorts (by specifying a + value), those requests will be respected, regardless of this field. + This field may only be set for services with type LoadBalancer and will + be cleared if the type is changed to any other type. + type: boolean + clusterIP: + description: |- + clusterIP is the IP address of the service and is usually assigned + randomly. If an address is specified manually, is in-range (as per + system configuration), and is not in use, it will be allocated to the + service; otherwise creation of the service will fail. This field may not + be changed through updates unless the type field is also being changed + to ExternalName (which requires this field to be blank) or the type + field is being changed from ExternalName (in which case this field may + optionally be specified, as describe above). Valid values are "None", + empty string (""), or a valid IP address. Setting this to "None" makes a + "headless service" (no virtual IP), which is useful when direct endpoint + connections are preferred and proxying is not required. Only applies to + types ClusterIP, NodePort, and LoadBalancer. If this field is specified + when creating a Service of type ExternalName, creation will fail. This + field will be wiped when updating a Service to type ExternalName. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + type: string + clusterIPs: + description: |- + ClusterIPs is a list of IP addresses assigned to this service, and are + usually assigned randomly. If an address is specified manually, is + in-range (as per system configuration), and is not in use, it will be + allocated to the service; otherwise creation of the service will fail. + This field may not be changed through updates unless the type field is + also being changed to ExternalName (which requires this field to be + empty) or the type field is being changed from ExternalName (in which + case this field may optionally be specified, as describe above). Valid + values are "None", empty string (""), or a valid IP address. Setting + this to "None" makes a "headless service" (no virtual IP), which is + useful when direct endpoint connections are preferred and proxying is + not required. Only applies to types ClusterIP, NodePort, and + LoadBalancer. If this field is specified when creating a Service of type + ExternalName, creation will fail. This field will be wiped when updating + a Service to type ExternalName. If this field is not specified, it will + be initialized from the clusterIP field. If this field is specified, + clients must ensure that clusterIPs[0] and clusterIP have the same + value. + + + This field may hold a maximum of two entries (dual-stack IPs, in either order). + These IPs must correspond to the values of the ipFamilies field. Both + clusterIPs and ipFamilies are governed by the ipFamilyPolicy field. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalIPs: + description: |- + externalIPs is a list of IP addresses for which nodes in the cluster + will also accept traffic for this service. These IPs are not managed by + Kubernetes. The user is responsible for ensuring that traffic arrives + at a node with this IP. A common example is external load-balancers + that are not part of the Kubernetes system. + items: + type: string + type: array + externalName: + description: |- + externalName is the external reference that discovery mechanisms will + return as an alias for this service (e.g. a DNS CNAME record). No + proxying will be involved. Must be a lowercase RFC-1123 hostname + (https://tools.ietf.org/html/rfc1123) and requires `type` to be "ExternalName". + type: string + externalTrafficPolicy: + description: |- + externalTrafficPolicy describes how nodes distribute service traffic they + receive on one of the Service's "externally-facing" addresses (NodePorts, + ExternalIPs, and LoadBalancer IPs). If set to "Local", the proxy will configure + the service in a way that assumes that external load balancers will take care + of balancing the service traffic between nodes, and so each node will deliver + traffic only to the node-local endpoints of the service, without masquerading + the client source IP. (Traffic mistakenly sent to a node with no endpoints will + be dropped.) The default value, "Cluster", uses the standard behavior of + routing to all endpoints evenly (possibly modified by topology and other + features). Note that traffic sent to an External IP or LoadBalancer IP from + within the cluster will always get "Cluster" semantics, but clients sending to + a NodePort from within the cluster may need to take traffic policy into account + when picking a node. + type: string + healthCheckNodePort: + description: |- + healthCheckNodePort specifies the healthcheck nodePort for the service. + This only applies when type is set to LoadBalancer and + externalTrafficPolicy is set to Local. If a value is specified, is + in-range, and is not in use, it will be used. If not specified, a value + will be automatically allocated. External systems (e.g. load-balancers) + can use this port to determine if a given node holds endpoints for this + service or not. If this field is specified when creating a Service + which does not need it, creation will fail. This field will be wiped + when updating a Service to no longer need it (e.g. changing type). + This field cannot be updated once set. + format: int32 + type: integer + internalTrafficPolicy: + description: |- + InternalTrafficPolicy describes how nodes distribute service traffic they + receive on the ClusterIP. If set to "Local", the proxy will assume that pods + only want to talk to endpoints of the service on the same node as the pod, + dropping the traffic if there are no local endpoints. The default value, + "Cluster", uses the standard behavior of routing to all endpoints evenly + (possibly modified by topology and other features). + type: string + ipFamilies: + description: |- + IPFamilies is a list of IP families (e.g. IPv4, IPv6) assigned to this + service. This field is usually assigned automatically based on cluster + configuration and the ipFamilyPolicy field. If this field is specified + manually, the requested family is available in the cluster, + and ipFamilyPolicy allows it, it will be used; otherwise creation of + the service will fail. This field is conditionally mutable: it allows + for adding or removing a secondary IP family, but it does not allow + changing the primary IP family of the Service. Valid values are "IPv4" + and "IPv6". This field only applies to Services of types ClusterIP, + NodePort, and LoadBalancer, and does apply to "headless" services. + This field will be wiped when updating a Service to type ExternalName. + + + This field may hold a maximum of two entries (dual-stack families, in + either order). These families must correspond to the values of the + clusterIPs field, if specified. Both clusterIPs and ipFamilies are + governed by the ipFamilyPolicy field. + items: + description: |- + IPFamily represents the IP Family (IPv4 or IPv6). This type is used + to express the family of an IP expressed by a type (e.g. service.spec.ipFamilies). + type: string + type: array + x-kubernetes-list-type: atomic + ipFamilyPolicy: + description: |- + IPFamilyPolicy represents the dual-stack-ness requested or required by + this Service. If there is no value provided, then this field will be set + to SingleStack. Services can be "SingleStack" (a single IP family), + "PreferDualStack" (two IP families on dual-stack configured clusters or + a single IP family on single-stack clusters), or "RequireDualStack" + (two IP families on dual-stack configured clusters, otherwise fail). The + ipFamilies and clusterIPs fields depend on the value of this field. This + field will be wiped when updating a service to type ExternalName. + type: string + loadBalancerClass: + description: |- + loadBalancerClass is the class of the load balancer implementation this Service belongs to. + If specified, the value of this field must be a label-style identifier, with an optional prefix, + e.g. "internal-vip" or "example.com/internal-vip". Unprefixed names are reserved for end-users. + This field can only be set when the Service type is 'LoadBalancer'. If not set, the default load + balancer implementation is used, today this is typically done through the cloud provider integration, + but should apply for any default implementation. If set, it is assumed that a load balancer + implementation is watching for Services with a matching class. Any default load balancer + implementation (e.g. cloud providers) should ignore Services that set this field. + This field can only be set when creating or updating a Service to type 'LoadBalancer'. + Once set, it can not be changed. This field will be wiped when a service is updated to a non 'LoadBalancer' type. + type: string + loadBalancerIP: + description: |- + Only applies to Service Type: LoadBalancer. + This feature depends on whether the underlying cloud-provider supports specifying + the loadBalancerIP when a load balancer is created. + This field will be ignored if the cloud-provider does not support the feature. + Deprecated: This field was under-specified and its meaning varies across implementations. + Using it is non-portable and it may not support dual-stack. + Users are encouraged to use implementation-specific annotations when available. + type: string + loadBalancerSourceRanges: + description: |- + If specified and supported by the platform, this will restrict traffic through the cloud-provider + load-balancer will be restricted to the specified client IPs. This field will be ignored if the + cloud-provider does not support the feature." + More info: https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/ + items: + type: string + type: array + ports: + description: |- + The list of ports that are exposed by this service. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + items: + description: ServicePort contains information on service's + port. + properties: + appProtocol: + description: |- + The application protocol for this port. + This is used as a hint for implementations to offer richer behavior for protocols that they understand. + This field follows standard Kubernetes label syntax. + Valid values are either: + + + * Un-prefixed protocol names - reserved for IANA standard service names (as per + RFC-6335 and https://www.iana.org/assignments/service-names). + + + * Kubernetes-defined prefixed names: + * 'kubernetes.io/h2c' - HTTP/2 prior knowledge over cleartext as described in https://www.rfc-editor.org/rfc/rfc9113.html#name-starting-http-2-with-prior- + * 'kubernetes.io/ws' - WebSocket over cleartext as described in https://www.rfc-editor.org/rfc/rfc6455 + * 'kubernetes.io/wss' - WebSocket over TLS as described in https://www.rfc-editor.org/rfc/rfc6455 + + + * Other protocols should use implementation-defined prefixed names such as + mycompany.com/my-custom-protocol. + type: string + name: + description: |- + The name of this port within the service. This must be a DNS_LABEL. + All ports within a ServiceSpec must have unique names. When considering + the endpoints for a Service, this must match the 'name' field in the + EndpointPort. + Optional if only one ServicePort is defined on this service. + type: string + nodePort: + description: |- + The port on each node on which this service is exposed when type is + NodePort or LoadBalancer. Usually assigned by the system. If a value is + specified, in-range, and not in use it will be used, otherwise the + operation will fail. If not specified, a port will be allocated if this + Service requires one. If this field is specified when creating a + Service which does not need it, creation will fail. This field will be + wiped when updating a Service to no longer need it (e.g. changing type + from NodePort to ClusterIP). + More info: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport + format: int32 + type: integer + port: + description: The port that will be exposed by this + service. + format: int32 + type: integer + protocol: + default: TCP + description: |- + The IP protocol for this port. Supports "TCP", "UDP", and "SCTP". + Default is TCP. + type: string + targetPort: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the pods targeted by the service. + Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + If this is a string, it will be looked up as a named port in the + target Pod's container ports. If this is not specified, the value + of the 'port' field is used (an identity map). + This field is ignored for services with clusterIP=None, and should be + omitted or set equal to the 'port' field. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#defining-a-service + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-map-keys: + - port + - protocol + x-kubernetes-list-type: map + publishNotReadyAddresses: + description: |- + publishNotReadyAddresses indicates that any agent which deals with endpoints for this + Service should disregard any indications of ready/not-ready. + The primary use case for setting this field is for a StatefulSet's Headless Service to + propagate SRV DNS records for its Pods for the purpose of peer discovery. + The Kubernetes controllers that generate Endpoints and EndpointSlice resources for + Services interpret this to mean that all endpoints are considered "ready" even if the + Pods themselves are not. Agents which consume only Kubernetes generated endpoints + through the Endpoints or EndpointSlice resources can safely assume this behavior. + type: boolean + selector: + additionalProperties: + type: string + description: |- + Route service traffic to pods with label keys and values matching this + selector. If empty or not present, the service is assumed to have an + external process managing its endpoints, which Kubernetes will not + modify. Only applies to types ClusterIP, NodePort, and LoadBalancer. + Ignored if type is ExternalName. + More info: https://kubernetes.io/docs/concepts/services-networking/service/ + type: object + x-kubernetes-map-type: atomic + sessionAffinity: + description: |- + Supports "ClientIP" and "None". Used to maintain session affinity. + Enable client IP based session affinity. + Must be ClientIP or None. + Defaults to None. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + type: string + sessionAffinityConfig: + description: sessionAffinityConfig contains the configurations + of session affinity. + properties: + clientIP: + description: clientIP contains the configurations of + Client IP based session affinity. + properties: + timeoutSeconds: + description: |- + timeoutSeconds specifies the seconds of ClientIP type session sticky time. + The value must be >0 && <=86400(for 1 day) if ServiceAffinity == "ClientIP". + Default value is 10800(for 3 hours). + format: int32 + type: integer + type: object + type: object + type: + description: |- + type determines how the Service is exposed. Defaults to ClusterIP. Valid + options are ExternalName, ClusterIP, NodePort, and LoadBalancer. + "ClusterIP" allocates a cluster-internal IP address for load-balancing + to endpoints. Endpoints are determined by the selector or if that is not + specified, by manual construction of an Endpoints object or + EndpointSlice objects. If clusterIP is "None", no virtual IP is + allocated and the endpoints are published as a set of endpoints rather + than a virtual IP. + "NodePort" builds on ClusterIP and allocates a port on every node which + routes to the same endpoints as the clusterIP. + "LoadBalancer" builds on NodePort and creates an external load-balancer + (if supported in the current cloud) which routes to the same endpoints + as the clusterIP. + "ExternalName" aliases this service to the specified externalName. + Several other fields do not apply to ExternalName services. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types + type: string + type: object + required: + - name + type: object + type: array + x-kubernetes-preserve-unknown-fields: true + shardingSpecs: + description: |- + Specifies a list of ShardingSpec objects that manage the sharding topology for Cluster Components. + Each ShardingSpec organizes components into shards, with each shard corresponding to a Component. + Components within a shard are all based on a common ClusterComponentSpec template, ensuring uniform configurations. + + + This field supports dynamic resharding by facilitating the addition or removal of shards + through the `shards` field in ShardingSpec. + + + Note: `shardingSpecs` and `componentSpecs` cannot both be empty; at least one must be defined to configure a Cluster. + items: + description: |- + ShardingSpec defines how KubeBlocks manage dynamic provisioned shards. + A typical design pattern for distributed databases is to distribute data across multiple shards, + with each shard consisting of multiple replicas. + Therefore, KubeBlocks supports representing a shard with a Component and dynamically instantiating Components + using a template when shards are added. + When shards are removed, the corresponding Components are also deleted. + properties: + name: + description: |- + Represents the common parent part of all shard names. + This identifier is included as part of the Service DNS name and must comply with IANA service naming rules. + It is used to generate the names of underlying Components following the pattern `$(shardingSpec.name)-$(ShardID)`. + ShardID is a random string that is appended to the Name to generate unique identifiers for each shard. + For example, if the sharding specification name is "my-shard" and the ShardID is "abc", the resulting Component name + would be "my-shard-abc". + + + Note that the name defined in Component template(`shardingSpec.template.name`) will be disregarded + when generating the Component names of the shards. The `shardingSpec.name` field takes precedence. + maxLength: 15 + pattern: ^[a-z0-9]([a-z0-9\.\-]*[a-z0-9])?$ + type: string + x-kubernetes-validations: + - message: name is immutable + rule: self == oldSelf + shards: + description: |- + Specifies the desired number of shards. + Users can declare the desired number of shards through this field. + KubeBlocks dynamically creates and deletes Components based on the difference + between the desired and actual number of shards. + KubeBlocks provides lifecycle management for sharding, including: + + + - Executing the postProvision Action defined in the ComponentDefinition when the number of shards increases. + This allows for custom actions to be performed after a new shard is provisioned. + - Executing the preTerminate Action defined in the ComponentDefinition when the number of shards decreases. + This enables custom cleanup or data migration tasks to be executed before a shard is terminated. + Resources and data associated with the corresponding Component will also be deleted. + format: int32 + maximum: 2048 + minimum: 0 + type: integer + template: + description: |- + The template for generating Components for shards, where each shard consists of one Component. + This field is of type ClusterComponentSpec, which encapsulates all the required details and + definitions for creating and managing the Components. + KubeBlocks uses this template to generate a set of identical Components or shards. + All the generated Components will have the same specifications and definitions as specified in the `template` field. + + + This allows for the creation of multiple Components with consistent configurations, + enabling sharding and distribution of workloads across Components. + properties: + annotations: + additionalProperties: + type: string + description: Specifies Annotations to override or add for + underlying Pods. + type: object + componentDef: + description: |- + References the name of a ComponentDefinition object. + The ComponentDefinition specifies the behavior and characteristics of the Component. + If both `componentDefRef` and `componentDef` are provided, + the `componentDef` will take precedence over `componentDefRef`. + maxLength: 64 + pattern: ^[a-z0-9]([a-z0-9\.\-]*[a-z0-9])?$ + type: string + componentDefRef: + description: |- + References a ClusterComponentDefinition defined in the `clusterDefinition.spec.componentDef` field. + Must comply with the IANA service naming rule. + + + Deprecated since v0.9, + because defining Components in `clusterDefinition.spec.componentDef` field has been deprecated. + This field is replaced by the `componentDef` field, use `componentDef` instead. + This field is maintained for backward compatibility and its use is discouraged. + Existing usage should be updated to the current preferred approach to avoid compatibility issues in future releases. + + + TODO +kubebuilder:validation:XValidation:rule="self == oldSelf",message="componentDefRef is immutable" + maxLength: 22 + pattern: ^[a-z]([a-z0-9\-]*[a-z0-9])?$ + type: string + configs: + description: Specifies the configuration content of a config + template. + items: + description: ClusterComponentConfig represents a config + with its source bound. + properties: + configMap: + description: ConfigMap source for the config. + properties: + defaultMode: + description: |- + defaultMode is optional: mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + items: + description: |- + items if unspecified, each key-value pair in the Data field of the referenced + ConfigMap will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the ConfigMap, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within + a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + 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 + optional: + description: optional specify whether the ConfigMap + or its keys must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + name: + description: The name of the config. + type: string + type: object + type: array + disableExporter: + description: |- + Determines whether metrics exporter information is annotated on the Component's headless Service. + + + If set to true, the following annotations will not be patched into the Service: + + + - "monitor.kubeblocks.io/path" + - "monitor.kubeblocks.io/port" + - "monitor.kubeblocks.io/scheme" + + + These annotations allow the Prometheus installed by KubeBlocks to discover and scrape metrics from the exporter. + type: boolean + enabledLogs: + description: |- + Specifies which types of logs should be collected for the Component. + The log types are defined in the `componentDefinition.spec.logConfigs` field with the LogConfig entries. + + + The elements in the `enabledLogs` array correspond to the names of the LogConfig entries. + For example, if the `componentDefinition.spec.logConfigs` defines LogConfig entries with + names "slow_query_log" and "error_log", + you can enable the collection of these logs by including their names in the `enabledLogs` array: + ```yaml + enabledLogs: + - slow_query_log + - error_log + ``` + items: + type: string + type: array + x-kubernetes-list-type: set + env: + description: |- + List of environment variables to add. + These environment variables will be placed after the environment variables declared in the Pod. + items: + description: EnvVar represents an environment variable + present in a Container. + properties: + name: + description: Name of the environment variable. Must + be a C_IDENTIFIER. + type: string + value: + description: |- + Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in the container and + any service environment variables. If a variable cannot be resolved, + the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless of whether the variable + exists or not. + Defaults to "". + type: string + valueFrom: + description: Source for the environment variable's + value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in + the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required for + volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of + the exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in the + pod's namespace + properties: + key: + description: The key of the secret to select + from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or + its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + instances: + description: |- + Allows for the customization of configuration values for each instance within a Component. + An instance represent a single replica (Pod and associated K8s resources like PVCs, Services, and ConfigMaps). + While instances typically share a common configuration as defined in the ClusterComponentSpec, + they can require unique settings in various scenarios: + + + For example: + - A database Component might require different resource allocations for primary and secondary instances, + with primaries needing more resources. + - During a rolling upgrade, a Component may first update the image for one or a few instances, + and then update the remaining instances after verifying that the updated instances are functioning correctly. + + + InstanceTemplate allows for specifying these unique configurations per instance. + Each instance's name is constructed using the pattern: $(component.name)-$(template.name)-$(ordinal), + starting with an ordinal of 0. + It is crucial to maintain unique names for each InstanceTemplate to avoid conflicts. + + + The sum of replicas across all InstanceTemplates should not exceed the total number of replicas specified for the Component. + Any remaining replicas will be generated using the default template and will follow the default naming rules. + items: + description: InstanceTemplate allows customization of + individual replica configurations in a Component. + properties: + annotations: + additionalProperties: + type: string + description: |- + Specifies a map of key-value pairs to be merged into the Pod's existing annotations. + Existing keys will have their values overwritten, while new keys will be added to the annotations. + type: object + env: + description: |- + Defines Env to override. + Add new or override existing envs. + items: + description: EnvVar represents an environment variable + present in a Container. + properties: + name: + description: Name of the environment variable. + Must be a C_IDENTIFIER. + type: string + value: + description: |- + Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in the container and + any service environment variables. If a variable cannot be resolved, + the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless of whether the variable + exists or not. + Defaults to "". + type: string + valueFrom: + description: Source for the environment variable's + value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the + FieldPath is written in terms of, + defaults to "v1". + type: string + fieldPath: + description: Path of the field to select + in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required + for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format + of the exposed resources, defaults + to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to + select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in + the pod's namespace + properties: + key: + description: The key of the secret to + select from. Must be a valid secret + key. + type: string + 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 + optional: + description: Specify whether the Secret + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + image: + description: Specifies an override for the first container's + image in the Pod. + type: string + labels: + additionalProperties: + type: string + description: |- + Specifies a map of key-value pairs that will be merged into the Pod's existing labels. + Values for existing keys will be overwritten, and new keys will be added. + type: object + name: + description: |- + Name specifies the unique name of the instance Pod created using this InstanceTemplate. + This name is constructed by concatenating the Component's name, the template's name, and the instance's ordinal + using the pattern: $(cluster.name)-$(component.name)-$(template.name)-$(ordinal). Ordinals start from 0. + The specified name overrides any default naming conventions or patterns. + maxLength: 54 + pattern: ^[a-z0-9]([a-z0-9\.\-]*[a-z0-9])?$ + type: string + replicas: + default: 1 + description: |- + Specifies the number of instances (Pods) to create from this InstanceTemplate. + This field allows setting how many replicated instances of the Component, + with the specific overrides in the InstanceTemplate, are created. + The default value is 1. A value of 0 disables instance creation. + format: int32 + minimum: 0 + type: integer + resources: + description: |- + Specifies an override for the resource requirements of the first container in the Pod. + This field allows for customizing resource allocation (CPU, memory, etc.) for the container. + properties: + claims: + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + + + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + + + This field is immutable. It can only be set for containers. + items: + description: ResourceClaim references one entry + in PodSpec.ResourceClaims. + properties: + name: + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + schedulingPolicy: + description: Specifies the scheduling policy for the + Component. + properties: + affinity: + description: Specifies a group of affinity scheduling + rules of the Cluster, including NodeAffinity, + PodAffinity, and PodAntiAffinity. + properties: + nodeAffinity: + description: Describes node affinity scheduling + rules for the pod. + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node matches the corresponding matchExpressions; the + node(s) with the highest sum are the most preferred. + items: + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). + properties: + preference: + description: A node selector term, + associated with the corresponding + weight. + properties: + matchExpressions: + description: A list of node + selector requirements by node's + labels. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label + key that the selector + applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node + selector requirements by node's + fields. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label + key that the selector + applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + weight: + description: Weight associated with + matching the corresponding nodeSelectorTerm, + in the range 1-100. + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. + properties: + nodeSelectorTerms: + description: Required. A list of node + selector terms. The terms are ORed. + items: + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. + properties: + matchExpressions: + description: A list of node + selector requirements by node's + labels. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label + key that the selector + applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node + selector requirements by node's + fields. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label + key that the selector + applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + type: array + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + description: Describes pod affinity scheduling + rules (e.g. co-locate this pod in the same + node, zone, etc. as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the + matched WeightedPodAffinityTerm fields + are added per-node to find the most + preferred node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity + term, associated with the corresponding + weight. + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions + is a list of label selector + requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is + the label key that + the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. + Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions + is a list of label selector + requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is + the label key that + the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: |- + weight associated with matching the corresponding podAffinityTerm, + in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. + items: + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions + is a list of label selector + requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the + label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. + Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions + is a list of label selector + requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the + label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + description: Describes pod anti-affinity scheduling + rules (e.g. avoid putting this pod in the + same node, zone, etc. as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the anti-affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the + matched WeightedPodAffinityTerm fields + are added per-node to find the most + preferred node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity + term, associated with the corresponding + weight. + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions + is a list of label selector + requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is + the label key that + the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. + Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions + is a list of label selector + requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is + the label key that + the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: |- + weight associated with matching the corresponding podAffinityTerm, + in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the anti-affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the anti-affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. + items: + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions + is a list of label selector + requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the + label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. + Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions + is a list of label selector + requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the + label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + nodeName: + description: |- + NodeName is a request to schedule this Pod onto a specific node. If it is non-empty, + the scheduler simply schedules this Pod onto that node, assuming that it fits resource + requirements. + type: string + nodeSelector: + additionalProperties: + type: string + description: |- + NodeSelector is a selector which must be true for the Pod to fit on a node. + Selector which must match a node's labels for the Pod to be scheduled on that node. + More info: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ + type: object + x-kubernetes-map-type: atomic + schedulerName: + description: |- + If specified, the Pod will be dispatched by specified scheduler. + If not specified, the Pod will be dispatched by default scheduler. + type: string + tolerations: + description: |- + Allows Pods to be scheduled onto nodes with matching taints. + Each toleration in the array allows the Pod to tolerate node taints based on + specified `key`, `value`, `effect`, and `operator`. + + + - The `key`, `value`, and `effect` identify the taint that the toleration matches. + - The `operator` determines how the toleration matches the taint. + + + Pods with matching tolerations are allowed to be scheduled on tainted nodes, typically reserved for specific purposes. + items: + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . + properties: + effect: + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. + type: string + operator: + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. + type: string + tolerationSeconds: + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. + format: int64 + type: integer + value: + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. + type: string + type: object + type: array + topologySpreadConstraints: + description: |- + TopologySpreadConstraints describes how a group of Pods ought to spread across topology + domains. Scheduler will schedule Pods in a way which abides by the constraints. + All topologySpreadConstraints are ANDed. + items: + description: TopologySpreadConstraint specifies + how to spread matching pods among the given + topology. + properties: + labelSelector: + description: |- + LabelSelector is used to find matching pods. + Pods that match this label selector are counted to determine the number of pods + in their corresponding topology domain. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select the pods over which + spreading will be calculated. The keys are used to lookup values from the + incoming pod labels, those key-value labels are ANDed with labelSelector + to select the group of existing pods over which spreading will be calculated + for the incoming pod. The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + MatchLabelKeys cannot be set when LabelSelector isn't set. + Keys that don't exist in the incoming pod labels will + be ignored. A null or empty list means only match against labelSelector. + + + This is a beta field and requires the MatchLabelKeysInPodTopologySpread feature gate to be enabled (enabled by default). + items: + type: string + type: array + x-kubernetes-list-type: atomic + maxSkew: + description: |- + MaxSkew describes the degree to which pods may be unevenly distributed. + When `whenUnsatisfiable=DoNotSchedule`, it is the maximum permitted difference + between the number of matching pods in the target topology and the global minimum. + The global minimum is the minimum number of matching pods in an eligible domain + or zero if the number of eligible domains is less than MinDomains. + For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same + labelSelector spread as 2/2/1: + In this case, the global minimum is 1. + | zone1 | zone2 | zone3 | + | P P | P P | P | + - if MaxSkew is 1, incoming pod can only be scheduled to zone3 to become 2/2/2; + scheduling it onto zone1(zone2) would make the ActualSkew(3-1) on zone1(zone2) + violate MaxSkew(1). + - if MaxSkew is 2, incoming pod can be scheduled onto any zone. + When `whenUnsatisfiable=ScheduleAnyway`, it is used to give higher precedence + to topologies that satisfy it. + It's a required field. Default value is 1 and 0 is not allowed. + format: int32 + type: integer + minDomains: + description: |- + MinDomains indicates a minimum number of eligible domains. + When the number of eligible domains with matching topology keys is less than minDomains, + Pod Topology Spread treats "global minimum" as 0, and then the calculation of Skew is performed. + And when the number of eligible domains with matching topology keys equals or greater than minDomains, + this value has no effect on scheduling. + As a result, when the number of eligible domains is less than minDomains, + scheduler won't schedule more than maxSkew Pods to those domains. + If value is nil, the constraint behaves as if MinDomains is equal to 1. + Valid values are integers greater than 0. + When value is not nil, WhenUnsatisfiable must be DoNotSchedule. + + + For example, in a 3-zone cluster, MaxSkew is set to 2, MinDomains is set to 5 and pods with the same + labelSelector spread as 2/2/2: + | zone1 | zone2 | zone3 | + | P P | P P | P P | + The number of domains is less than 5(MinDomains), so "global minimum" is treated as 0. + In this situation, new pod with the same labelSelector cannot be scheduled, + because computed skew will be 3(3 - 0) if new Pod is scheduled to any of the three zones, + it will violate MaxSkew. + + + This is a beta field and requires the MinDomainsInPodTopologySpread feature gate to be enabled (enabled by default). + format: int32 + type: integer + nodeAffinityPolicy: + description: |- + NodeAffinityPolicy indicates how we will treat Pod's nodeAffinity/nodeSelector + when calculating pod topology spread skew. Options are: + - Honor: only nodes matching nodeAffinity/nodeSelector are included in the calculations. + - Ignore: nodeAffinity/nodeSelector are ignored. All nodes are included in the calculations. + + + If this value is nil, the behavior is equivalent to the Honor policy. + This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag. + type: string + nodeTaintsPolicy: + description: |- + NodeTaintsPolicy indicates how we will treat node taints when calculating + pod topology spread skew. Options are: + - Honor: nodes without taints, along with tainted nodes for which the incoming pod + has a toleration, are included. + - Ignore: node taints are ignored. All nodes are included. + + + If this value is nil, the behavior is equivalent to the Ignore policy. + This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag. + type: string + topologyKey: + description: |- + TopologyKey is the key of node labels. Nodes that have a label with this key + and identical values are considered to be in the same topology. + We consider each as a "bucket", and try to put balanced number + of pods into each bucket. + We define a domain as a particular instance of a topology. + Also, we define an eligible domain as a domain whose nodes meet the requirements of + nodeAffinityPolicy and nodeTaintsPolicy. + e.g. If TopologyKey is "kubernetes.io/hostname", each Node is a domain of that topology. + And, if TopologyKey is "topology.kubernetes.io/zone", each zone is a domain of that topology. + It's a required field. + type: string + whenUnsatisfiable: + description: |- + WhenUnsatisfiable indicates how to deal with a pod if it doesn't satisfy + the spread constraint. + - DoNotSchedule (default) tells the scheduler not to schedule it. + - ScheduleAnyway tells the scheduler to schedule the pod in any location, + but giving higher precedence to topologies that would help reduce the + skew. + A constraint is considered "Unsatisfiable" for an incoming pod + if and only if every possible node assignment for that pod would violate + "MaxSkew" on some topology. + For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same + labelSelector spread as 3/1/1: + | zone1 | zone2 | zone3 | + | P P P | P | P | + If WhenUnsatisfiable is set to DoNotSchedule, incoming pod can only be scheduled + to zone2(zone3) to become 3/2/1(3/1/2) as ActualSkew(2-1) on zone2(zone3) satisfies + MaxSkew(1). In other words, the cluster can still be imbalanced, but scheduler + won't make it *more* imbalanced. + It's a required field. + type: string + required: + - maxSkew + - topologyKey + - whenUnsatisfiable + type: object + type: array + type: object + volumeClaimTemplates: + description: |- + Defines VolumeClaimTemplates to override. + Add new or override existing volume claim templates. + items: + properties: + name: + description: |- + Refers to the name of a volumeMount defined in either: + + + - `componentDefinition.spec.runtime.containers[*].volumeMounts` + - `clusterDefinition.spec.componentDefs[*].podSpec.containers[*].volumeMounts` (deprecated) + + + The value of `name` must match the `name` field of a volumeMount specified in the corresponding `volumeMounts` array. + type: string + spec: + description: |- + Defines the desired characteristics of a PersistentVolumeClaim that will be created for the volume + with the mount name specified in the `name` field. + + + When a Pod is created for this ClusterComponent, a new PVC will be created based on the specification + defined in the `spec` field. The PVC will be associated with the volume mount specified by the `name` field. + properties: + accessModes: + description: |- + Contains the desired access modes the volume should have. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1. + items: + type: string + type: array + x-kubernetes-preserve-unknown-fields: true + resources: + description: |- + Represents the minimum resources the volume should have. + If the RecoverVolumeExpansionFailure feature is enabled, users are allowed to specify resource requirements that + are lower than the previous value but must still be higher than the capacity recorded in the status field of the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources. + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + x-kubernetes-preserve-unknown-fields: true + storageClassName: + description: |- + The name of the StorageClass required by the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1. + type: string + volumeMode: + description: Defines what type of volume + is required by the claim, either Block + or Filesystem. + type: string + type: object + required: + - name + type: object + type: array + volumeMounts: + description: |- + Defines VolumeMounts to override. + Add new or override existing volume mounts of the first container in the Pod. + items: + description: VolumeMount describes a mounting of + a Volume within a container. + properties: + mountPath: + description: |- + Path within the container at which the volume should be mounted. Must + not contain ':'. + type: string + mountPropagation: + description: |- + mountPropagation determines how mounts are propagated from the host + to container and the other way around. + When not set, MountPropagationNone is used. + This field is beta in 1.10. + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: |- + Mounted read-only if true, read-write otherwise (false or unspecified). + Defaults to false. + type: boolean + subPath: + description: |- + Path within the volume from which the container's volume should be mounted. + Defaults to "" (volume's root). + type: string + subPathExpr: + description: |- + Expanded path within the volume from which the container's volume should be mounted. + Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment. + Defaults to "" (volume's root). + SubPathExpr and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + volumes: + description: |- + Defines Volumes to override. + Add new or override existing volumes. + items: + description: Volume represents a named volume in + a pod that may be accessed by any container in + the pod. + properties: + awsElasticBlockStore: + description: |- + awsElasticBlockStore represents an AWS Disk resource that is attached to a + kubelet's host machine and then exposed to the pod. + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + properties: + fsType: + description: |- + fsType is the filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + partition: + description: |- + partition is the partition in the volume that you want to mount. + If omitted, the default is to mount by volume name. + Examples: For volume /dev/sda1, you specify the partition as "1". + Similarly, the volume partition for /dev/sda is "0" (or you can leave the property empty). + format: int32 + type: integer + readOnly: + description: |- + readOnly value true will force the readOnly setting in VolumeMounts. + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + type: boolean + volumeID: + description: |- + volumeID is unique ID of the persistent disk resource in AWS (Amazon EBS volume). + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + type: string + required: + - volumeID + type: object + azureDisk: + description: azureDisk represents an Azure Data + Disk mount on the host and bind mount to the + pod. + properties: + cachingMode: + description: 'cachingMode is the Host Caching + mode: None, Read Only, Read Write.' + type: string + diskName: + description: diskName is the Name of the + data disk in the blob storage + type: string + diskURI: + description: diskURI is the URI of data + disk in the blob storage + type: string + fsType: + description: |- + fsType is Filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + kind: + description: 'kind expected values are Shared: + multiple blob disks per storage account Dedicated: + single blob disk per storage account Managed: + azure managed data disk (only in managed + availability set). defaults to shared' + type: string + readOnly: + description: |- + readOnly Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + description: azureFile represents an Azure File + Service mount on the host and bind mount to + the pod. + properties: + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretName: + description: secretName is the name of + secret that contains Azure Storage Account + Name and Key + type: string + shareName: + description: shareName is the azure share + Name + type: string + required: + - secretName + - shareName + type: object + cephfs: + description: cephFS represents a Ceph FS mount + on the host that shares a pod's lifetime + properties: + monitors: + description: |- + monitors is Required: Monitors is a collection of Ceph monitors + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + items: + type: string + type: array + path: + description: 'path is Optional: Used as + the mounted root, rather than the full + Ceph tree, default is /' + type: string + readOnly: + description: |- + readOnly is Optional: Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + type: boolean + secretFile: + description: |- + secretFile is Optional: SecretFile is the path to key ring for User, default is /etc/ceph/user.secret + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + type: string + secretRef: + description: |- + secretRef is Optional: SecretRef is reference to the authentication secret for User, default is empty. + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + 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 + user: + description: |- + user is optional: User is the rados user name, default is admin + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + type: string + required: + - monitors + type: object + cinder: + description: |- + cinder represents a cinder volume attached and mounted on kubelets host machine. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + type: string + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + type: boolean + secretRef: + description: |- + secretRef is optional: points to a secret object containing parameters used to connect + to OpenStack. + 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 + volumeID: + description: |- + volumeID used to identify the volume in cinder. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + type: string + required: + - volumeID + type: object + configMap: + description: configMap represents a configMap + that should populate this volume + properties: + defaultMode: + description: |- + defaultMode is optional: mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + items: + description: |- + items if unspecified, each key-value pair in the Data field of the referenced + ConfigMap will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the ConfigMap, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path + within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + 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 + optional: + description: optional specify whether the + ConfigMap or its keys must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + csi: + description: csi (Container Storage Interface) + represents ephemeral storage that is handled + by certain external CSI drivers (Beta feature). + properties: + driver: + description: |- + driver is the name of the CSI driver that handles this volume. + Consult with your admin for the correct name as registered in the cluster. + type: string + fsType: + description: |- + fsType to mount. Ex. "ext4", "xfs", "ntfs". + If not provided, the empty value is passed to the associated CSI driver + which will determine the default filesystem to apply. + type: string + nodePublishSecretRef: + description: |- + nodePublishSecretRef is a reference to the secret object containing + sensitive information to pass to the CSI driver to complete the CSI + NodePublishVolume and NodeUnpublishVolume calls. + This field is optional, and may be empty if no secret is required. If the + secret object contains more than one secret, all secret references are passed. + 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 + readOnly: + description: |- + readOnly specifies a read-only configuration for the volume. + Defaults to false (read/write). + type: boolean + volumeAttributes: + additionalProperties: + type: string + description: |- + volumeAttributes stores driver-specific properties that are passed to the CSI + driver. Consult your driver's documentation for supported values. + type: object + required: + - driver + type: object + downwardAPI: + description: downwardAPI represents downward + API about the pod that should populate this + volume + properties: + defaultMode: + description: |- + Optional: mode bits to use on created files by default. Must be a + Optional: mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + items: + description: Items is a list of downward + API volume file + items: + description: DownwardAPIVolumeFile represents + information to create the file containing + the pod field + properties: + fieldRef: + description: 'Required: Selects a + field of the pod: only annotations, + labels, name and namespace are supported.' + properties: + apiVersion: + description: Version of the schema + the FieldPath is written in + terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field + to select in the specified API + version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + description: |- + Optional: mode bits used to set permissions on this file, must be an octal value + between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: 'Required: Path is the + relative path name of the file to + be created. Must not be absolute + or contain the ''..'' path. Must + be utf-8 encoded. The first item + of the relative path must not start + with ''..''' + type: string + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported. + properties: + containerName: + description: 'Container name: + required for volumes, optional + for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output + format of the exposed resources, + defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource + to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + type: object + emptyDir: + description: |- + emptyDir represents a temporary directory that shares a pod's lifetime. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir + properties: + medium: + description: |- + medium represents what type of storage medium should back this directory. + The default is "" which means to use the node's default medium. + Must be an empty string (default) or Memory. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + description: |- + sizeLimit is the total amount of local storage required for this EmptyDir volume. + The size limit is also applicable for memory medium. + The maximum usage on memory medium EmptyDir would be the minimum value between + the SizeLimit specified here and the sum of memory limits of all containers in a pod. + The default is nil which means that the limit is undefined. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + description: |- + ephemeral represents a volume that is handled by a cluster storage driver. + The volume's lifecycle is tied to the pod that defines it - it will be created before the pod starts, + and deleted when the pod is removed. + + + Use this if: + a) the volume is only needed while the pod runs, + b) features of normal volumes like restoring from snapshot or capacity + tracking are needed, + c) the storage driver is specified through a storage class, and + d) the storage driver supports dynamic volume provisioning through + a PersistentVolumeClaim (see EphemeralVolumeSource for more + information on the connection between this volume type + and PersistentVolumeClaim). + + + Use PersistentVolumeClaim or one of the vendor-specific + APIs for volumes that persist for longer than the lifecycle + of an individual pod. + + + Use CSI for light-weight local ephemeral volumes if the CSI driver is meant to + be used that way - see the documentation of the driver for + more information. + + + A pod can use both types of ephemeral volumes and + persistent volumes at the same time. + properties: + volumeClaimTemplate: + description: |- + Will be used to create a stand-alone PVC to provision the volume. + The pod in which this EphemeralVolumeSource is embedded will be the + owner of the PVC, i.e. the PVC will be deleted together with the + pod. The name of the PVC will be `-` where + `` is the name from the `PodSpec.Volumes` array + entry. Pod validation will reject the pod if the concatenated name + is not valid for a PVC (for example, too long). + + + An existing PVC with that name that is not owned by the pod + will *not* be used for the pod to avoid using an unrelated + volume by mistake. Starting the pod is then blocked until + the unrelated PVC is removed. If such a pre-created PVC is + meant to be used by the pod, the PVC has to updated with an + owner reference to the pod once the pod exists. Normally + this should not be necessary, but it may be useful when + manually reconstructing a broken cluster. + + + This field is read-only and no changes will be made by Kubernetes + to the PVC after it has been created. + + + Required, must not be nil. + properties: + metadata: + description: |- + May contain labels and annotations that will be copied into the PVC + when creating it. No other fields are allowed and will be rejected during + validation. + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + description: |- + The specification for the PersistentVolumeClaim. The entire content is + copied unchanged into the PVC that gets created from this + template. The same fields as in a PersistentVolumeClaim + are also valid here. + properties: + accessModes: + description: |- + accessModes contains the desired access modes the volume should have. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1 + items: + type: string + type: array + dataSource: + description: |- + dataSource field can be used to specify either: + * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) + * An existing PVC (PersistentVolumeClaim) + If the provisioner or an external controller can support the specified data source, + it will create a new volume based on the contents of the specified data source. + When the AnyVolumeDataSource feature gate is enabled, dataSource contents will be copied to dataSourceRef, + and dataSourceRef contents will be copied to dataSource when dataSourceRef.namespace is not specified. + If the namespace is specified, then dataSourceRef will not be copied to dataSource. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type + of resource being referenced + type: string + name: + description: Name is the name + of resource being referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + description: |- + dataSourceRef specifies the object from which to populate the volume with data, if a non-empty + volume is desired. This may be any object from a non-empty API group (non + core object) or a PersistentVolumeClaim object. + When this field is specified, volume binding will only succeed if the type of + the specified object matches some installed volume populator or dynamic + provisioner. + This field will replace the functionality of the dataSource field and as such + if both fields are non-empty, they must have the same value. For backwards + compatibility, when namespace isn't specified in dataSourceRef, + both fields (dataSource and dataSourceRef) will be set to the same + value automatically if one of them is empty and the other is non-empty. + When namespace is specified in dataSourceRef, + dataSource isn't set to the same value and must be empty. + There are three important differences between dataSource and dataSourceRef: + * While dataSource only allows two specific types of objects, dataSourceRef + allows any non-core object, as well as PersistentVolumeClaim objects. + * While dataSource ignores disallowed values (dropping them), dataSourceRef + preserves all values, and generates an error if a disallowed value is + specified. + * While dataSource only allows local objects, dataSourceRef allows objects + in any namespaces. + (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled. + (Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type + of resource being referenced + type: string + name: + description: Name is the name + of resource being referenced + type: string + namespace: + description: |- + Namespace is the namespace of resource being referenced + Note that when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details. + (Alpha) This field requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + type: string + required: + - kind + - name + type: object + resources: + description: |- + resources represents the minimum resources the volume should have. + If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements + that are lower than previous value but must still be higher than capacity recorded in the + status field of the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + selector: + description: selector is a label + query over volumes to consider + for binding. + properties: + matchExpressions: + description: matchExpressions + is a list of label selector + requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the + label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + description: |- + storageClassName is the name of the StorageClass required by the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1 + type: string + volumeAttributesClassName: + description: |- + volumeAttributesClassName may be used to set the VolumeAttributesClass used by this claim. + If specified, the CSI driver will create or update the volume with the attributes defined + in the corresponding VolumeAttributesClass. This has a different purpose than storageClassName, + it can be changed after the claim is created. An empty string value means that no VolumeAttributesClass + will be applied to the claim but it's not allowed to reset this field to empty string once it is set. + If unspecified and the PersistentVolumeClaim is unbound, the default VolumeAttributesClass + will be set by the persistentvolume controller if it exists. + If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be + set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource + exists. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#volumeattributesclass + (Alpha) Using this field requires the VolumeAttributesClass feature gate to be enabled. + type: string + volumeMode: + description: |- + volumeMode defines what type of volume is required by the claim. + Value of Filesystem is implied when not included in claim spec. + type: string + volumeName: + description: volumeName is the binding + reference to the PersistentVolume + backing this claim. + type: string + type: object + required: + - spec + type: object + type: object + fc: + description: fc represents a Fibre Channel resource + that is attached to a kubelet's host machine + and then exposed to the pod. + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + lun: + description: 'lun is Optional: FC target + lun number' + format: int32 + type: integer + readOnly: + description: |- + readOnly is Optional: Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + targetWWNs: + description: 'targetWWNs is Optional: FC + target worldwide names (WWNs)' + items: + type: string + type: array + wwids: + description: |- + wwids Optional: FC volume world wide identifiers (wwids) + Either wwids or combination of targetWWNs and lun must be set, but not both simultaneously. + items: + type: string + type: array + type: object + flexVolume: + description: |- + flexVolume represents a generic volume resource that is + provisioned/attached using an exec based plugin. + properties: + driver: + description: driver is the name of the driver + to use for this volume. + type: string + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". The default filesystem depends on FlexVolume script. + type: string + options: + additionalProperties: + type: string + description: 'options is Optional: this + field holds extra command options if any.' + type: object + readOnly: + description: |- + readOnly is Optional: defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: |- + secretRef is Optional: secretRef is reference to the secret object containing + sensitive information to pass to the plugin scripts. This may be + empty if no secret object is specified. If the secret object + contains more than one secret, all secrets are passed to the plugin + scripts. + 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 + required: + - driver + type: object + flocker: + description: flocker represents a Flocker volume + attached to a kubelet's host machine. This + depends on the Flocker control service being + running + properties: + datasetName: + description: |- + datasetName is Name of the dataset stored as metadata -> name on the dataset for Flocker + should be considered as deprecated + type: string + datasetUUID: + description: datasetUUID is the UUID of + the dataset. This is unique identifier + of a Flocker dataset + type: string + type: object + gcePersistentDisk: + description: |- + gcePersistentDisk represents a GCE Disk resource that is attached to a + kubelet's host machine and then exposed to the pod. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + properties: + fsType: + description: |- + fsType is filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + partition: + description: |- + partition is the partition in the volume that you want to mount. + If omitted, the default is to mount by volume name. + Examples: For volume /dev/sda1, you specify the partition as "1". + Similarly, the volume partition for /dev/sda is "0" (or you can leave the property empty). + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + format: int32 + type: integer + pdName: + description: |- + pdName is unique name of the PD resource in GCE. Used to identify the disk in GCE. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + type: string + readOnly: + description: |- + readOnly here will force the ReadOnly setting in VolumeMounts. + Defaults to false. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + type: boolean + required: + - pdName + type: object + gitRepo: + description: |- + gitRepo represents a git repository at a particular revision. + DEPRECATED: GitRepo is deprecated. To provision a container with a git repo, mount an + EmptyDir into an InitContainer that clones the repo using git, then mount the EmptyDir + into the Pod's container. + properties: + directory: + description: |- + directory is the target directory name. + Must not contain or start with '..'. If '.' is supplied, the volume directory will be the + git repository. Otherwise, if specified, the volume will contain the git repository in + the subdirectory with the given name. + type: string + repository: + description: repository is the URL + type: string + revision: + description: revision is the commit hash + for the specified revision. + type: string + required: + - repository + type: object + glusterfs: + description: |- + glusterfs represents a Glusterfs mount on the host that shares a pod's lifetime. + More info: https://examples.k8s.io/volumes/glusterfs/README.md + properties: + endpoints: + description: |- + endpoints is the endpoint name that details Glusterfs topology. + More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod + type: string + path: + description: |- + path is the Glusterfs volume path. + More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod + type: string + readOnly: + description: |- + readOnly here will force the Glusterfs volume to be mounted with read-only permissions. + Defaults to false. + More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod + type: boolean + required: + - endpoints + - path + type: object + hostPath: + description: |- + hostPath represents a pre-existing file or directory on the host + machine that is directly exposed to the container. This is generally + used for system agents or other privileged things that are allowed + to see the host machine. Most containers will NOT need this. + More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + --- + TODO(jonesdl) We need to restrict who can use host directory mounts and who can/can not + mount host directories as read/write. + properties: + path: + description: |- + path of the directory on the host. + If the path is a symlink, it will follow the link to the real path. + More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + type: string + type: + description: |- + type for HostPath Volume + Defaults to "" + More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + type: string + required: + - path + type: object + iscsi: + description: |- + iscsi represents an ISCSI Disk resource that is attached to a + kubelet's host machine and then exposed to the pod. + More info: https://examples.k8s.io/volumes/iscsi/README.md + properties: + chapAuthDiscovery: + description: chapAuthDiscovery defines whether + support iSCSI Discovery CHAP authentication + type: boolean + chapAuthSession: + description: chapAuthSession defines whether + support iSCSI Session CHAP authentication + type: boolean + fsType: + description: |- + fsType is the filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#iscsi + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + initiatorName: + description: |- + initiatorName is the custom iSCSI Initiator Name. + If initiatorName is specified with iscsiInterface simultaneously, new iSCSI interface + : will be created for the connection. + type: string + iqn: + description: iqn is the target iSCSI Qualified + Name. + type: string + iscsiInterface: + description: |- + iscsiInterface is the interface Name that uses an iSCSI transport. + Defaults to 'default' (tcp). + type: string + lun: + description: lun represents iSCSI Target + Lun number. + format: int32 + type: integer + portals: + description: |- + portals is the iSCSI Target Portal List. The portal is either an IP or ip_addr:port if the port + is other than default (typically TCP ports 860 and 3260). + items: + type: string + type: array + readOnly: + description: |- + readOnly here will force the ReadOnly setting in VolumeMounts. + Defaults to false. + type: boolean + secretRef: + description: secretRef is the CHAP Secret + for iSCSI target and initiator authentication + 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 + targetPortal: + description: |- + targetPortal is iSCSI Target Portal. The Portal is either an IP or ip_addr:port if the port + is other than default (typically TCP ports 860 and 3260). + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + description: |- + name of the volume. + Must be a DNS_LABEL and unique within the pod. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + nfs: + description: |- + nfs represents an NFS mount on the host that shares a pod's lifetime + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + properties: + path: + description: |- + path that is exported by the NFS server. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + type: string + readOnly: + description: |- + readOnly here will force the NFS export to be mounted with read-only permissions. + Defaults to false. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + type: boolean + server: + description: |- + server is the hostname or IP address of the NFS server. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + description: |- + persistentVolumeClaimVolumeSource represents a reference to a + PersistentVolumeClaim in the same namespace. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims + properties: + claimName: + description: |- + claimName is the name of a PersistentVolumeClaim in the same namespace as the pod using this volume. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims + type: string + readOnly: + description: |- + readOnly Will force the ReadOnly setting in VolumeMounts. + Default false. + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + description: photonPersistentDisk represents + a PhotonController persistent disk attached + and mounted on kubelets host machine + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + pdID: + description: pdID is the ID that identifies + Photon Controller persistent disk + type: string + required: + - pdID + type: object + portworxVolume: + description: portworxVolume represents a portworx + volume attached and mounted on kubelets host + machine + properties: + fsType: + description: |- + fSType represents the filesystem type to mount + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs". Implicitly inferred to be "ext4" if unspecified. + type: string + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + volumeID: + description: volumeID uniquely identifies + a Portworx volume + type: string + required: + - volumeID + type: object + projected: + description: projected items for all in one + resources secrets, configmaps, and downward + API + properties: + defaultMode: + description: |- + defaultMode are the mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + sources: + description: sources is the list of volume + projections + items: + description: Projection that may be projected + along with other supported volume types + properties: + clusterTrustBundle: + description: |- + ClusterTrustBundle allows a pod to access the `.spec.trustBundle` field + of ClusterTrustBundle objects in an auto-updating file. + + + Alpha, gated by the ClusterTrustBundleProjection feature gate. + + + ClusterTrustBundle objects can either be selected by name, or by the + combination of signer name and a label selector. + + + Kubelet performs aggressive normalization of the PEM contents written + into the pod filesystem. Esoteric PEM features such as inter-block + comments and block headers are stripped. Certificates are deduplicated. + The ordering of certificates within the file is arbitrary, and Kubelet + may change the order over time. + properties: + labelSelector: + description: |- + Select all ClusterTrustBundles that match this label selector. Only has + effect if signerName is set. Mutually-exclusive with name. If unset, + interpreted as "match nothing". If set but empty, interpreted as "match + everything". + properties: + matchExpressions: + description: matchExpressions + is a list of label selector + requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is + the label key that + the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + name: + description: |- + Select a single ClusterTrustBundle by object name. Mutually-exclusive + with signerName and labelSelector. + type: string + optional: + description: |- + If true, don't block pod startup if the referenced ClusterTrustBundle(s) + aren't available. If using name, then the named ClusterTrustBundle is + allowed not to exist. If using signerName, then the combination of + signerName and labelSelector is allowed to match zero + ClusterTrustBundles. + type: boolean + path: + description: Relative path from + the volume root to write the + bundle. + type: string + signerName: + description: |- + Select all ClusterTrustBundles that match this signer name. + Mutually-exclusive with name. The contents of all selected + ClusterTrustBundles will be unified and deduplicated. + type: string + required: + - path + type: object + configMap: + description: configMap information + about the configMap data to project + properties: + items: + description: |- + items if unspecified, each key-value pair in the Data field of the referenced + ConfigMap will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the ConfigMap, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key + to a path within a volume. + properties: + key: + description: key is the + key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + 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 + optional: + description: optional specify + whether the ConfigMap or its + keys must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + downwardAPI: + description: downwardAPI information + about the downwardAPI data to project + properties: + items: + description: Items is a list of + DownwardAPIVolume file + items: + description: DownwardAPIVolumeFile + represents information to + create the file containing + the pod field + properties: + fieldRef: + description: 'Required: + Selects a field of the + pod: only annotations, + labels, name and namespace + are supported.' + properties: + apiVersion: + description: Version + of the schema the + FieldPath is written + in terms of, defaults + to "v1". + type: string + fieldPath: + description: Path of + the field to select + in the specified API + version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + description: |- + Optional: mode bits used to set permissions on this file, must be an octal value + between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: 'Required: + Path is the relative + path name of the file + to be created. Must not + be absolute or contain + the ''..'' path. Must + be utf-8 encoded. The + first item of the relative + path must not start with + ''..''' + type: string + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported. + properties: + containerName: + description: 'Container + name: required for + volumes, optional + for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies + the output format + of the exposed resources, + defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: + resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + type: object + secret: + description: secret information about + the secret data to project + properties: + items: + description: |- + items if unspecified, each key-value pair in the Data field of the referenced + Secret will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the Secret, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key + to a path within a volume. + properties: + key: + description: key is the + key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + 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 + optional: + description: optional field specify + whether the Secret or its key + must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + serviceAccountToken: + description: serviceAccountToken is + information about the serviceAccountToken + data to project + properties: + audience: + description: |- + audience is the intended audience of the token. A recipient of a token + must identify itself with an identifier specified in the audience of the + token, and otherwise should reject the token. The audience defaults to the + identifier of the apiserver. + type: string + expirationSeconds: + description: |- + expirationSeconds is the requested duration of validity of the service + account token. As the token approaches expiration, the kubelet volume + plugin will proactively rotate the service account token. The kubelet will + start trying to rotate the token if the token is older than 80 percent of + its time to live or if the token is older than 24 hours.Defaults to 1 hour + and must be at least 10 minutes. + format: int64 + type: integer + path: + description: |- + path is the path relative to the mount point of the file to project the + token into. + type: string + required: + - path + type: object + type: object + type: array + type: object + quobyte: + description: quobyte represents a Quobyte mount + on the host that shares a pod's lifetime + properties: + group: + description: |- + group to map volume access to + Default is no group + type: string + readOnly: + description: |- + readOnly here will force the Quobyte volume to be mounted with read-only permissions. + Defaults to false. + type: boolean + registry: + description: |- + registry represents a single or multiple Quobyte Registry services + specified as a string as host:port pair (multiple entries are separated with commas) + which acts as the central registry for volumes + type: string + tenant: + description: |- + tenant owning the given Quobyte volume in the Backend + Used with dynamically provisioned Quobyte volumes, value is set by the plugin + type: string + user: + description: |- + user to map volume access to + Defaults to serivceaccount user + type: string + volume: + description: volume is a string that references + an already created Quobyte volume by name. + type: string + required: + - registry + - volume + type: object + rbd: + description: |- + rbd represents a Rados Block Device mount on the host that shares a pod's lifetime. + More info: https://examples.k8s.io/volumes/rbd/README.md + properties: + fsType: + description: |- + fsType is the filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#rbd + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + image: + description: |- + image is the rados image name. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + keyring: + description: |- + keyring is the path to key ring for RBDUser. + Default is /etc/ceph/keyring. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + monitors: + description: |- + monitors is a collection of Ceph monitors. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + items: + type: string + type: array + pool: + description: |- + pool is the rados pool name. + Default is rbd. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + readOnly: + description: |- + readOnly here will force the ReadOnly setting in VolumeMounts. + Defaults to false. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: boolean + secretRef: + description: |- + secretRef is name of the authentication secret for RBDUser. If provided + overrides keyring. + Default is nil. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + 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 + user: + description: |- + user is the rados user name. + Default is admin. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + required: + - image + - monitors + type: object + scaleIO: + description: scaleIO represents a ScaleIO persistent + volume attached and mounted on Kubernetes + nodes. + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". + Default is "xfs". + type: string + gateway: + description: gateway is the host address + of the ScaleIO API Gateway. + type: string + protectionDomain: + description: protectionDomain is the name + of the ScaleIO Protection Domain for the + configured storage. + type: string + readOnly: + description: |- + readOnly Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: |- + secretRef references to the secret for ScaleIO user and other + sensitive information. If this is not provided, Login operation will fail. + 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 + sslEnabled: + description: sslEnabled Flag enable/disable + SSL communication with Gateway, default + false + type: boolean + storageMode: + description: |- + storageMode indicates whether the storage for a volume should be ThickProvisioned or ThinProvisioned. + Default is ThinProvisioned. + type: string + storagePool: + description: storagePool is the ScaleIO + Storage Pool associated with the protection + domain. + type: string + system: + description: system is the name of the storage + system as configured in ScaleIO. + type: string + volumeName: + description: |- + volumeName is the name of a volume already created in the ScaleIO system + that is associated with this volume source. + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + description: |- + secret represents a secret that should populate this volume. + More info: https://kubernetes.io/docs/concepts/storage/volumes#secret + properties: + defaultMode: + description: |- + defaultMode is Optional: mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values + for mode bits. Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + items: + description: |- + items If unspecified, each key-value pair in the Data field of the referenced + Secret will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the Secret, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path + within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + optional: + description: optional field specify whether + the Secret or its keys must be defined + type: boolean + secretName: + description: |- + secretName is the name of the secret in the pod's namespace to use. + More info: https://kubernetes.io/docs/concepts/storage/volumes#secret + type: string + type: object + storageos: + description: storageOS represents a StorageOS + volume attached and mounted on Kubernetes + nodes. + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: |- + secretRef specifies the secret to use for obtaining the StorageOS API + credentials. If not specified, default values will be attempted. + 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 + volumeName: + description: |- + volumeName is the human-readable name of the StorageOS volume. Volume + names are only unique within a namespace. + type: string + volumeNamespace: + description: |- + volumeNamespace specifies the scope of the volume within StorageOS. If no + namespace is specified then the Pod's namespace will be used. This allows the + Kubernetes name scoping to be mirrored within StorageOS for tighter integration. + Set VolumeName to any name to override the default behaviour. + Set to "default" if you are not using namespaces within StorageOS. + Namespaces that do not pre-exist within StorageOS will be created. + type: string + type: object + vsphereVolume: + description: vsphereVolume represents a vSphere + volume attached and mounted on kubelets host + machine + properties: + fsType: + description: |- + fsType is filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + storagePolicyID: + description: storagePolicyID is the storage + Policy Based Management (SPBM) profile + ID associated with the StoragePolicyName. + type: string + storagePolicyName: + description: storagePolicyName is the storage + Policy Based Management (SPBM) profile + name. + type: string + volumePath: + description: volumePath is the path that + identifies vSphere volume vmdk + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + issuer: + description: |- + Specifies the configuration for the TLS certificates issuer. + It allows defining the issuer name and the reference to the secret containing the TLS certificates and key. + The secret should contain the CA certificate, TLS certificate, and private key in the specified keys. + Required when TLS is enabled. + properties: + name: + allOf: + - enum: + - KubeBlocks + - UserProvided + - enum: + - KubeBlocks + - UserProvided + default: KubeBlocks + description: |- + The issuer for TLS certificates. + It only allows two enum values: `KubeBlocks` and `UserProvided`. + + + - `KubeBlocks` indicates that the self-signed TLS certificates generated by the KubeBlocks Operator will be used. + - `UserProvided` means that the user is responsible for providing their own CA, Cert, and Key. + In this case, the user-provided CA certificate, server certificate, and private key will be used + for TLS communication. + type: string + secretRef: + description: |- + SecretRef is the reference to the secret that contains user-provided certificates. + It is required when the issuer is set to `UserProvided`. + properties: + ca: + description: Key of CA cert in Secret + type: string + cert: + description: Key of Cert in Secret + type: string + key: + description: Key of TLS private key in Secret + type: string + name: + description: Name of the Secret that contains user-provided + certificates. + type: string + required: + - ca + - cert + - key + - name + type: object + required: + - name + type: object + labels: + additionalProperties: + type: string + description: Specifies Labels to override or add for underlying + Pods. + type: object + monitor: + description: |- + Deprecated since v0.9 + Determines whether metrics exporter information is annotated on the Component's headless Service. + + + If set to true, the following annotations will be patched into the Service: + + + - "monitor.kubeblocks.io/path" + - "monitor.kubeblocks.io/port" + - "monitor.kubeblocks.io/scheme" + + + These annotations allow the Prometheus installed by KubeBlocks to discover and scrape metrics from the exporter. + type: boolean + name: + description: |- + Specifies the Component's name. + It's part of the Service DNS name and must comply with the IANA service naming rule. + The name is optional when ClusterComponentSpec is used as a template (e.g., in `shardingSpec`), + but required otherwise. + + + TODO +kubebuilder:validation:XValidation:rule="self == oldSelf",message="name is immutable" + maxLength: 22 + pattern: ^[a-z]([a-z0-9\-]*[a-z0-9])?$ + type: string + offlineInstances: + description: |- + Specifies the names of instances to be transitioned to offline status. + + + Marking an instance as offline results in the following: + + + 1. The associated Pod is stopped, and its PersistentVolumeClaim (PVC) is retained for potential + future reuse or data recovery, but it is no longer actively used. + 2. The ordinal number assigned to this instance is preserved, ensuring it remains unique + and avoiding conflicts with new instances. + + + Setting instances to offline allows for a controlled scale-in process, preserving their data and maintaining + ordinal consistency within the Cluster. + Note that offline instances and their associated resources, such as PVCs, are not automatically deleted. + The administrator must manually manage the cleanup and removal of these resources when they are no longer needed. + items: + type: string + type: array + parallelPodManagementConcurrency: + anyOf: + - type: integer + - type: string + description: |- + Controls the concurrency of pods during initial scale up, when replacing pods on nodes, + or when scaling down. It only used when `PodManagementPolicy` is set to `Parallel`. + The default Concurrency is 100%. + x-kubernetes-int-or-string: true + podUpdatePolicy: + description: |- + PodUpdatePolicy indicates how pods should be updated + + + - `StrictInPlace` indicates that only allows in-place upgrades. + Any attempt to modify other fields will be rejected. + - `PreferInPlace` indicates that we will first attempt an in-place upgrade of the Pod. + If that fails, it will fall back to the ReCreate, where pod will be recreated. + Default value is "PreferInPlace" + enum: + - StrictInPlace + - PreferInPlace + type: string + replicas: + default: 1 + description: Specifies the desired number of replicas in + the Component for enhancing availability and durability, + or load balancing. + format: int32 + minimum: 0 + type: integer + resources: + description: |- + Specifies the resources required by the Component. + It allows defining the CPU, memory requirements and limits for the Component's containers. + properties: + claims: + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + + + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + + + This field is immutable. It can only be set for containers. + items: + description: ResourceClaim references one entry in + PodSpec.ResourceClaims. + properties: + name: + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + x-kubernetes-preserve-unknown-fields: true + schedulingPolicy: + description: Specifies the scheduling policy for the Component. + properties: + affinity: + description: Specifies a group of affinity scheduling + rules of the Cluster, including NodeAffinity, PodAffinity, + and PodAntiAffinity. + properties: + nodeAffinity: + description: Describes node affinity scheduling + rules for the pod. + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node matches the corresponding matchExpressions; the + node(s) with the highest sum are the most preferred. + items: + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). + properties: + preference: + description: A node selector term, associated + with the corresponding weight. + properties: + matchExpressions: + description: A list of node selector + requirements by node's labels. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that + the selector applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector + requirements by node's fields. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that + the selector applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + weight: + description: Weight associated with matching + the corresponding nodeSelectorTerm, + in the range 1-100. + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. + properties: + nodeSelectorTerms: + description: Required. A list of node selector + terms. The terms are ORed. + items: + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. + properties: + matchExpressions: + description: A list of node selector + requirements by node's labels. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that + the selector applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector + requirements by node's fields. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that + the selector applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + type: array + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + description: Describes pod affinity scheduling rules + (e.g. co-locate this pod in the same node, zone, + etc. as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched + WeightedPodAffinityTerm fields are added + per-node to find the most preferred node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity + term, associated with the corresponding + weight. + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions + is a list of label selector + requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the + label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. + Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions + is a list of label selector + requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the + label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: |- + weight associated with matching the corresponding podAffinityTerm, + in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. + items: + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a + list of label selector requirements. + The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. + Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a + list of label selector requirements. + The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + description: Describes pod anti-affinity scheduling + rules (e.g. avoid putting this pod in the same + node, zone, etc. as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the anti-affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched + WeightedPodAffinityTerm fields are added + per-node to find the most preferred node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity + term, associated with the corresponding + weight. + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions + is a list of label selector + requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the + label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. + Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions + is a list of label selector + requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the + label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: |- + weight associated with matching the corresponding podAffinityTerm, + in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the anti-affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the anti-affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. + items: + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a + list of label selector requirements. + The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. + Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a + list of label selector requirements. + The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + nodeName: + description: |- + NodeName is a request to schedule this Pod onto a specific node. If it is non-empty, + the scheduler simply schedules this Pod onto that node, assuming that it fits resource + requirements. + type: string + nodeSelector: + additionalProperties: + type: string + description: |- + NodeSelector is a selector which must be true for the Pod to fit on a node. + Selector which must match a node's labels for the Pod to be scheduled on that node. + More info: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ + type: object + x-kubernetes-map-type: atomic + schedulerName: + description: |- + If specified, the Pod will be dispatched by specified scheduler. + If not specified, the Pod will be dispatched by default scheduler. + type: string + tolerations: + description: |- + Allows Pods to be scheduled onto nodes with matching taints. + Each toleration in the array allows the Pod to tolerate node taints based on + specified `key`, `value`, `effect`, and `operator`. + + + - The `key`, `value`, and `effect` identify the taint that the toleration matches. + - The `operator` determines how the toleration matches the taint. + + + Pods with matching tolerations are allowed to be scheduled on tainted nodes, typically reserved for specific purposes. + items: + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . + properties: + effect: + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. + type: string + operator: + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. + type: string + tolerationSeconds: + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. + format: int64 + type: integer + value: + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. + type: string + type: object + type: array + topologySpreadConstraints: + description: |- + TopologySpreadConstraints describes how a group of Pods ought to spread across topology + domains. Scheduler will schedule Pods in a way which abides by the constraints. + All topologySpreadConstraints are ANDed. + items: + description: TopologySpreadConstraint specifies how + to spread matching pods among the given topology. + properties: + labelSelector: + description: |- + LabelSelector is used to find matching pods. + Pods that match this label selector are counted to determine the number of pods + in their corresponding topology domain. + properties: + matchExpressions: + description: matchExpressions is a list of + label selector requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select the pods over which + spreading will be calculated. The keys are used to lookup values from the + incoming pod labels, those key-value labels are ANDed with labelSelector + to select the group of existing pods over which spreading will be calculated + for the incoming pod. The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + MatchLabelKeys cannot be set when LabelSelector isn't set. + Keys that don't exist in the incoming pod labels will + be ignored. A null or empty list means only match against labelSelector. + + + This is a beta field and requires the MatchLabelKeysInPodTopologySpread feature gate to be enabled (enabled by default). + items: + type: string + type: array + x-kubernetes-list-type: atomic + maxSkew: + description: |- + MaxSkew describes the degree to which pods may be unevenly distributed. + When `whenUnsatisfiable=DoNotSchedule`, it is the maximum permitted difference + between the number of matching pods in the target topology and the global minimum. + The global minimum is the minimum number of matching pods in an eligible domain + or zero if the number of eligible domains is less than MinDomains. + For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same + labelSelector spread as 2/2/1: + In this case, the global minimum is 1. + | zone1 | zone2 | zone3 | + | P P | P P | P | + - if MaxSkew is 1, incoming pod can only be scheduled to zone3 to become 2/2/2; + scheduling it onto zone1(zone2) would make the ActualSkew(3-1) on zone1(zone2) + violate MaxSkew(1). + - if MaxSkew is 2, incoming pod can be scheduled onto any zone. + When `whenUnsatisfiable=ScheduleAnyway`, it is used to give higher precedence + to topologies that satisfy it. + It's a required field. Default value is 1 and 0 is not allowed. + format: int32 + type: integer + minDomains: + description: |- + MinDomains indicates a minimum number of eligible domains. + When the number of eligible domains with matching topology keys is less than minDomains, + Pod Topology Spread treats "global minimum" as 0, and then the calculation of Skew is performed. + And when the number of eligible domains with matching topology keys equals or greater than minDomains, + this value has no effect on scheduling. + As a result, when the number of eligible domains is less than minDomains, + scheduler won't schedule more than maxSkew Pods to those domains. + If value is nil, the constraint behaves as if MinDomains is equal to 1. + Valid values are integers greater than 0. + When value is not nil, WhenUnsatisfiable must be DoNotSchedule. + + + For example, in a 3-zone cluster, MaxSkew is set to 2, MinDomains is set to 5 and pods with the same + labelSelector spread as 2/2/2: + | zone1 | zone2 | zone3 | + | P P | P P | P P | + The number of domains is less than 5(MinDomains), so "global minimum" is treated as 0. + In this situation, new pod with the same labelSelector cannot be scheduled, + because computed skew will be 3(3 - 0) if new Pod is scheduled to any of the three zones, + it will violate MaxSkew. + + + This is a beta field and requires the MinDomainsInPodTopologySpread feature gate to be enabled (enabled by default). + format: int32 + type: integer + nodeAffinityPolicy: + description: |- + NodeAffinityPolicy indicates how we will treat Pod's nodeAffinity/nodeSelector + when calculating pod topology spread skew. Options are: + - Honor: only nodes matching nodeAffinity/nodeSelector are included in the calculations. + - Ignore: nodeAffinity/nodeSelector are ignored. All nodes are included in the calculations. + + + If this value is nil, the behavior is equivalent to the Honor policy. + This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag. + type: string + nodeTaintsPolicy: + description: |- + NodeTaintsPolicy indicates how we will treat node taints when calculating + pod topology spread skew. Options are: + - Honor: nodes without taints, along with tainted nodes for which the incoming pod + has a toleration, are included. + - Ignore: node taints are ignored. All nodes are included. + + + If this value is nil, the behavior is equivalent to the Ignore policy. + This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag. + type: string + topologyKey: + description: |- + TopologyKey is the key of node labels. Nodes that have a label with this key + and identical values are considered to be in the same topology. + We consider each as a "bucket", and try to put balanced number + of pods into each bucket. + We define a domain as a particular instance of a topology. + Also, we define an eligible domain as a domain whose nodes meet the requirements of + nodeAffinityPolicy and nodeTaintsPolicy. + e.g. If TopologyKey is "kubernetes.io/hostname", each Node is a domain of that topology. + And, if TopologyKey is "topology.kubernetes.io/zone", each zone is a domain of that topology. + It's a required field. + type: string + whenUnsatisfiable: + description: |- + WhenUnsatisfiable indicates how to deal with a pod if it doesn't satisfy + the spread constraint. + - DoNotSchedule (default) tells the scheduler not to schedule it. + - ScheduleAnyway tells the scheduler to schedule the pod in any location, + but giving higher precedence to topologies that would help reduce the + skew. + A constraint is considered "Unsatisfiable" for an incoming pod + if and only if every possible node assignment for that pod would violate + "MaxSkew" on some topology. + For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same + labelSelector spread as 3/1/1: + | zone1 | zone2 | zone3 | + | P P P | P | P | + If WhenUnsatisfiable is set to DoNotSchedule, incoming pod can only be scheduled + to zone2(zone3) to become 3/2/1(3/1/2) as ActualSkew(2-1) on zone2(zone3) satisfies + MaxSkew(1). In other words, the cluster can still be imbalanced, but scheduler + won't make it *more* imbalanced. + It's a required field. + type: string + required: + - maxSkew + - topologyKey + - whenUnsatisfiable + type: object + type: array + type: object + serviceAccountName: + description: |- + Specifies the name of the ServiceAccount required by the running Component. + This ServiceAccount is used to grant necessary permissions for the Component's Pods to interact + with other Kubernetes resources, such as modifying Pod labels or sending events. + + + Defaults: + To perform certain operational tasks, agent sidecars running in Pods require specific RBAC permissions. + The service account will be bound to a default role named "kubeblocks-cluster-pod-role" which is installed together with KubeBlocks. + If not specified, KubeBlocks automatically assigns a default ServiceAccount named "kb-{cluster.name}" + + + Future Changes: + Future versions might change the default ServiceAccount creation strategy to one per Component, + potentially revising the naming to "kb-{cluster.name}-{component.name}". + + + Users can override the automatic ServiceAccount assignment by explicitly setting the name of + an existed ServiceAccount in this field. + type: string + serviceRefs: + description: |- + Defines a list of ServiceRef for a Component, enabling access to both external services and + Services provided by other Clusters. + + + Types of services: + + + - External services: Not managed by KubeBlocks or managed by a different KubeBlocks operator; + Require a ServiceDescriptor for connection details. + - Services provided by a Cluster: Managed by the same KubeBlocks operator; + identified using Cluster, Component and Service names. + + + ServiceRefs with identical `serviceRef.name` in the same Cluster are considered the same. + + + Example: + ```yaml + serviceRefs: + - name: "redis-sentinel" + serviceDescriptor: + name: "external-redis-sentinel" + - name: "postgres-cluster" + clusterServiceSelector: + cluster: "my-postgres-cluster" + service: + component: "postgresql" + ``` + The example above includes ServiceRefs to an external Redis Sentinel service and a PostgreSQL Cluster. + items: + properties: + cluster: + description: |- + Specifies the name of the KubeBlocks Cluster being referenced. + This is used when services from another KubeBlocks Cluster are consumed. + + + By default, the referenced KubeBlocks Cluster's `clusterDefinition.spec.connectionCredential` + will be utilized to bind to the current Component. This credential should include: + `endpoint`, `port`, `username`, and `password`. + + + Note: + + + - The `ServiceKind` and `ServiceVersion` specified in the service reference within the + ClusterDefinition are not validated when using this approach. + - If both `cluster` and `serviceDescriptor` are present, `cluster` will take precedence. + + + Deprecated since v0.9 since `clusterDefinition.spec.connectionCredential` is deprecated, + use `clusterServiceSelector` instead. + This field is maintained for backward compatibility and its use is discouraged. + Existing usage should be updated to the current preferred approach to avoid compatibility issues in future releases. + type: string + clusterServiceSelector: + description: |- + References a service provided by another KubeBlocks Cluster. + It specifies the ClusterService and the account credentials needed for access. + properties: + cluster: + description: The name of the Cluster being referenced. + type: string + credential: + description: |- + Specifies the SystemAccount to authenticate and establish a connection with the referenced Cluster. + The SystemAccount should be defined in `componentDefinition.spec.systemAccounts` + of the Component providing the service in the referenced Cluster. + properties: + component: + description: The name of the Component where + the credential resides in. + type: string + name: + description: The name of the credential (SystemAccount) + to reference. + type: string + required: + - component + - name + type: object + service: + description: Identifies a ClusterService from + the list of Services defined in `cluster.spec.services` + of the referenced Cluster. + properties: + component: + description: |- + The name of the Component where the Service resides in. + + + It is required when referencing a Component's Service. + type: string + port: + description: |- + The port name of the Service to be referenced. + + + If there is a non-zero node-port exist for the matched Service port, the node-port will be selected first. + + + If the referenced Service is of pod-service type (a Service per Pod), there will be multiple Service objects matched, + and the resolved value will be presented in the following format: service1.name:port1,service2.name:port2... + type: string + service: + description: |- + The name of the Service to be referenced. + + + Leave it empty to reference the default Service. Set it to "headless" to reference the default headless Service. + + + If the referenced Service is of pod-service type (a Service per Pod), there will be multiple Service objects matched, + and the resolved value will be presented in the following format: service1.name,service2.name... + type: string + required: + - service + type: object + required: + - cluster + type: object + name: + description: |- + Specifies the identifier of the service reference declaration. + It corresponds to the serviceRefDeclaration name defined in either: + + + - `componentDefinition.spec.serviceRefDeclarations[*].name` + - `clusterDefinition.spec.componentDefs[*].serviceRefDeclarations[*].name` (deprecated) + type: string + namespace: + description: |- + Specifies the namespace of the referenced Cluster or the namespace of the referenced ServiceDescriptor object. + If not provided, the referenced Cluster and ServiceDescriptor will be searched in the namespace of the current + Cluster by default. + type: string + serviceDescriptor: + description: |- + Specifies the name of the ServiceDescriptor object that describes a service provided by external sources. + + + When referencing a service provided by external sources, a ServiceDescriptor object is required to establish + the service binding. + The `serviceDescriptor.spec.serviceKind` and `serviceDescriptor.spec.serviceVersion` should match the serviceKind + and serviceVersion declared in the definition. + + + If both `cluster` and `serviceDescriptor` are specified, the `cluster` takes precedence. + type: string + required: + - name + type: object + type: array + serviceVersion: + description: |- + ServiceVersion specifies the version of the Service expected to be provisioned by this Component. + The version should follow the syntax and semantics of the "Semantic Versioning" specification (http://semver.org/). + If no version is specified, the latest available version will be used. + maxLength: 32 + type: string + services: + description: Overrides services defined in referenced ComponentDefinition + and expose endpoints that can be accessed by clients. + items: + properties: + annotations: + additionalProperties: + type: string + description: |- + If ServiceType is LoadBalancer, cloud provider related parameters can be put here. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#loadbalancer. + type: object + name: + description: References the ComponentService name + defined in the `componentDefinition.spec.services[*].name`. + maxLength: 25 + type: string + podService: + description: |- + Indicates whether to generate individual Services for each Pod. + If set to true, a separate Service will be created for each Pod in the Cluster. + type: boolean + serviceType: + default: ClusterIP + description: |- + Determines how the Service is exposed. Valid options are `ClusterIP`, `NodePort`, and `LoadBalancer`. + + + - `ClusterIP` allocates a Cluster-internal IP address for load-balancing to endpoints. + Endpoints are determined by the selector or if that is not specified, + they are determined by manual construction of an Endpoints object or EndpointSlice objects. + - `NodePort` builds on ClusterIP and allocates a port on every node which routes to the same endpoints as the ClusterIP. + - `LoadBalancer` builds on NodePort and creates an external load-balancer (if supported in the current cloud) + which routes to the same endpoints as the ClusterIP. + + + Note: although K8s Service type allows the 'ExternalName' type, it is not a valid option for ClusterComponentService. + + + For more info, see: + https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types. + enum: + - ClusterIP + - NodePort + - LoadBalancer + type: string + x-kubernetes-preserve-unknown-fields: true + required: + - name + type: object + type: array + stop: + description: |- + Stop the Component. + If set, all the computing resources will be released. + type: boolean + systemAccounts: + description: Overrides system accounts defined in referenced + ComponentDefinition. + items: + properties: + name: + description: The name of the system account. + type: string + passwordConfig: + description: |- + Specifies the policy for generating the account's password. + + + This field is immutable once set. + properties: + length: + default: 16 + description: The length of the password. + format: int32 + maximum: 32 + minimum: 8 + type: integer + letterCase: + default: MixedCases + description: The case of the letters in the password. + enum: + - LowerCases + - UpperCases + - MixedCases + type: string + numDigits: + default: 4 + description: The number of digits in the password. + format: int32 + maximum: 8 + minimum: 0 + type: integer + numSymbols: + default: 0 + description: The number of symbols in the password. + format: int32 + maximum: 8 + minimum: 0 + type: integer + seed: + description: |- + Seed to generate the account's password. + Cannot be updated. + type: string + type: object + secretRef: + description: |- + Refers to the secret from which data will be copied to create the new account. + + + This field is immutable once set. + properties: + name: + description: The unique identifier of the secret. + type: string + namespace: + description: The namespace where the secret is + located. + type: string + required: + - name + - namespace + type: object + required: + - name + type: object + type: array + tls: + description: |- + A boolean flag that indicates whether the Component should use Transport Layer Security (TLS) + for secure communication. + When set to true, the Component will be configured to use TLS encryption for its network connections. + This ensures that the data transmitted between the Component and its clients or other Components is encrypted + and protected from unauthorized access. + If TLS is enabled, the Component may require additional configuration, such as specifying TLS certificates and keys, + to properly set up the secure communication channel. + type: boolean + updateStrategy: + description: |- + Defines the update strategy for the Component. + + + Deprecated since v0.9. + This field is maintained for backward compatibility and its use is discouraged. + Existing usage should be updated to the current preferred approach to avoid compatibility issues in future releases. + enum: + - Serial + - BestEffortParallel + - Parallel + type: string + userResourceRefs: + description: |- + Allows users to specify custom ConfigMaps and Secrets to be mounted as volumes + in the Cluster's Pods. + This is useful in scenarios where users need to provide additional resources to the Cluster, such as: + + + - Mounting custom scripts or configuration files during Cluster startup. + - Mounting Secrets as volumes to provide sensitive information, like S3 AK/SK, to the Cluster. + properties: + configMapRefs: + description: ConfigMapRefs defines the user-defined + ConfigMaps. + items: + description: ConfigMapRef defines a reference to a + ConfigMap. + properties: + asVolumeFrom: + description: AsVolumeFrom lists the names of containers + in which the volume should be mounted. + items: + type: string + type: array + x-kubernetes-list-type: set + configMap: + description: ConfigMap specifies the ConfigMap + to be mounted as a volume. + properties: + defaultMode: + description: |- + defaultMode is optional: mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + items: + description: |- + items if unspecified, each key-value pair in the Data field of the referenced + ConfigMap will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the ConfigMap, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path + within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + 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 + optional: + description: optional specify whether the + ConfigMap or its keys must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + mountPoint: + description: MountPoint is the filesystem path + where the volume will be mounted. + maxLength: 256 + pattern: ^/[a-z]([a-z0-9\-]*[a-z0-9])?$ + type: string + name: + description: Name is the name of the referenced + ConfigMap or Secret object. It must conform + to DNS label standards. + maxLength: 63 + pattern: ^[a-z0-9]([a-z0-9\.\-]*[a-z0-9])?$ + type: string + subPath: + description: SubPath specifies a path within the + volume from which to mount. + type: string + required: + - configMap + - mountPoint + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + secretRefs: + description: SecretRefs defines the user-defined Secrets. + items: + description: SecretRef defines a reference to a Secret. + properties: + asVolumeFrom: + description: AsVolumeFrom lists the names of containers + in which the volume should be mounted. + items: + type: string + type: array + x-kubernetes-list-type: set + mountPoint: + description: MountPoint is the filesystem path + where the volume will be mounted. + maxLength: 256 + pattern: ^/[a-z]([a-z0-9\-]*[a-z0-9])?$ + type: string + name: + description: Name is the name of the referenced + ConfigMap or Secret object. It must conform + to DNS label standards. + maxLength: 63 + pattern: ^[a-z0-9]([a-z0-9\.\-]*[a-z0-9])?$ + type: string + secret: + description: Secret specifies the Secret to be + mounted as a volume. + properties: + defaultMode: + description: |- + defaultMode is Optional: mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values + for mode bits. Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + items: + description: |- + items If unspecified, each key-value pair in the Data field of the referenced + Secret will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the Secret, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path + within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + optional: + description: optional field specify whether + the Secret or its keys must be defined + type: boolean + secretName: + description: |- + secretName is the name of the secret in the pod's namespace to use. + More info: https://kubernetes.io/docs/concepts/storage/volumes#secret + type: string + type: object + subPath: + description: SubPath specifies a path within the + volume from which to mount. + type: string + required: + - mountPoint + - name + - secret + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + volumeClaimTemplates: + description: |- + Specifies a list of PersistentVolumeClaim templates that represent the storage requirements for the Component. + Each template specifies the desired characteristics of a persistent volume, such as storage class, + size, and access modes. + These templates are used to dynamically provision persistent volumes for the Component. + items: + properties: + name: + description: |- + Refers to the name of a volumeMount defined in either: + + + - `componentDefinition.spec.runtime.containers[*].volumeMounts` + - `clusterDefinition.spec.componentDefs[*].podSpec.containers[*].volumeMounts` (deprecated) + + + The value of `name` must match the `name` field of a volumeMount specified in the corresponding `volumeMounts` array. + type: string + spec: + description: |- + Defines the desired characteristics of a PersistentVolumeClaim that will be created for the volume + with the mount name specified in the `name` field. + + + When a Pod is created for this ClusterComponent, a new PVC will be created based on the specification + defined in the `spec` field. The PVC will be associated with the volume mount specified by the `name` field. + properties: + accessModes: + description: |- + Contains the desired access modes the volume should have. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1. + items: + type: string + type: array + x-kubernetes-preserve-unknown-fields: true + resources: + description: |- + Represents the minimum resources the volume should have. + If the RecoverVolumeExpansionFailure feature is enabled, users are allowed to specify resource requirements that + are lower than the previous value but must still be higher than the capacity recorded in the status field of the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources. + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + x-kubernetes-preserve-unknown-fields: true + storageClassName: + description: |- + The name of the StorageClass required by the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1. + type: string + volumeMode: + description: Defines what type of volume is required + by the claim, either Block or Filesystem. + type: string + type: object + required: + - name + type: object + type: array + volumes: + description: List of volumes to override. + items: + description: Volume represents a named volume in a pod + that may be accessed by any container in the pod. + properties: + awsElasticBlockStore: + description: |- + awsElasticBlockStore represents an AWS Disk resource that is attached to a + kubelet's host machine and then exposed to the pod. + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + properties: + fsType: + description: |- + fsType is the filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + partition: + description: |- + partition is the partition in the volume that you want to mount. + If omitted, the default is to mount by volume name. + Examples: For volume /dev/sda1, you specify the partition as "1". + Similarly, the volume partition for /dev/sda is "0" (or you can leave the property empty). + format: int32 + type: integer + readOnly: + description: |- + readOnly value true will force the readOnly setting in VolumeMounts. + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + type: boolean + volumeID: + description: |- + volumeID is unique ID of the persistent disk resource in AWS (Amazon EBS volume). + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + type: string + required: + - volumeID + type: object + azureDisk: + description: azureDisk represents an Azure Data Disk + mount on the host and bind mount to the pod. + properties: + cachingMode: + description: 'cachingMode is the Host Caching + mode: None, Read Only, Read Write.' + type: string + diskName: + description: diskName is the Name of the data + disk in the blob storage + type: string + diskURI: + description: diskURI is the URI of data disk in + the blob storage + type: string + fsType: + description: |- + fsType is Filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + kind: + description: 'kind expected values are Shared: + multiple blob disks per storage account Dedicated: + single blob disk per storage account Managed: + azure managed data disk (only in managed availability + set). defaults to shared' + type: string + readOnly: + description: |- + readOnly Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + description: azureFile represents an Azure File Service + mount on the host and bind mount to the pod. + properties: + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretName: + description: secretName is the name of secret + that contains Azure Storage Account Name and + Key + type: string + shareName: + description: shareName is the azure share Name + type: string + required: + - secretName + - shareName + type: object + cephfs: + description: cephFS represents a Ceph FS mount on + the host that shares a pod's lifetime + properties: + monitors: + description: |- + monitors is Required: Monitors is a collection of Ceph monitors + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + items: + type: string + type: array + path: + description: 'path is Optional: Used as the mounted + root, rather than the full Ceph tree, default + is /' + type: string + readOnly: + description: |- + readOnly is Optional: Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + type: boolean + secretFile: + description: |- + secretFile is Optional: SecretFile is the path to key ring for User, default is /etc/ceph/user.secret + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + type: string + secretRef: + description: |- + secretRef is Optional: SecretRef is reference to the authentication secret for User, default is empty. + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + 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 + user: + description: |- + user is optional: User is the rados user name, default is admin + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + type: string + required: + - monitors + type: object + cinder: + description: |- + cinder represents a cinder volume attached and mounted on kubelets host machine. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + type: string + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + type: boolean + secretRef: + description: |- + secretRef is optional: points to a secret object containing parameters used to connect + to OpenStack. + 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 + volumeID: + description: |- + volumeID used to identify the volume in cinder. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + type: string + required: + - volumeID + type: object + configMap: + description: configMap represents a configMap that + should populate this volume + properties: + defaultMode: + description: |- + defaultMode is optional: mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + items: + description: |- + items if unspecified, each key-value pair in the Data field of the referenced + ConfigMap will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the ConfigMap, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within + a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + 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 + optional: + description: optional specify whether the ConfigMap + or its keys must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + csi: + description: csi (Container Storage Interface) represents + ephemeral storage that is handled by certain external + CSI drivers (Beta feature). + properties: + driver: + description: |- + driver is the name of the CSI driver that handles this volume. + Consult with your admin for the correct name as registered in the cluster. + type: string + fsType: + description: |- + fsType to mount. Ex. "ext4", "xfs", "ntfs". + If not provided, the empty value is passed to the associated CSI driver + which will determine the default filesystem to apply. + type: string + nodePublishSecretRef: + description: |- + nodePublishSecretRef is a reference to the secret object containing + sensitive information to pass to the CSI driver to complete the CSI + NodePublishVolume and NodeUnpublishVolume calls. + This field is optional, and may be empty if no secret is required. If the + secret object contains more than one secret, all secret references are passed. + 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 + readOnly: + description: |- + readOnly specifies a read-only configuration for the volume. + Defaults to false (read/write). + type: boolean + volumeAttributes: + additionalProperties: + type: string + description: |- + volumeAttributes stores driver-specific properties that are passed to the CSI + driver. Consult your driver's documentation for supported values. + type: object + required: + - driver + type: object + downwardAPI: + description: downwardAPI represents downward API about + the pod that should populate this volume + properties: + defaultMode: + description: |- + Optional: mode bits to use on created files by default. Must be a + Optional: mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + items: + description: Items is a list of downward API volume + file + items: + description: DownwardAPIVolumeFile represents + information to create the file containing + the pod field + properties: + fieldRef: + description: 'Required: Selects a field + of the pod: only annotations, labels, + name and namespace are supported.' + properties: + apiVersion: + description: Version of the schema the + FieldPath is written in terms of, + defaults to "v1". + type: string + fieldPath: + description: Path of the field to select + in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + description: |- + Optional: mode bits used to set permissions on this file, must be an octal value + between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: 'Required: Path is the relative + path name of the file to be created. Must + not be absolute or contain the ''..'' + path. Must be utf-8 encoded. The first + item of the relative path must not start + with ''..''' + type: string + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported. + properties: + containerName: + description: 'Container name: required + for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format + of the exposed resources, defaults + to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to + select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + type: object + emptyDir: + description: |- + emptyDir represents a temporary directory that shares a pod's lifetime. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir + properties: + medium: + description: |- + medium represents what type of storage medium should back this directory. + The default is "" which means to use the node's default medium. + Must be an empty string (default) or Memory. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + description: |- + sizeLimit is the total amount of local storage required for this EmptyDir volume. + The size limit is also applicable for memory medium. + The maximum usage on memory medium EmptyDir would be the minimum value between + the SizeLimit specified here and the sum of memory limits of all containers in a pod. + The default is nil which means that the limit is undefined. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + description: |- + ephemeral represents a volume that is handled by a cluster storage driver. + The volume's lifecycle is tied to the pod that defines it - it will be created before the pod starts, + and deleted when the pod is removed. + + + Use this if: + a) the volume is only needed while the pod runs, + b) features of normal volumes like restoring from snapshot or capacity + tracking are needed, + c) the storage driver is specified through a storage class, and + d) the storage driver supports dynamic volume provisioning through + a PersistentVolumeClaim (see EphemeralVolumeSource for more + information on the connection between this volume type + and PersistentVolumeClaim). + + + Use PersistentVolumeClaim or one of the vendor-specific + APIs for volumes that persist for longer than the lifecycle + of an individual pod. + + + Use CSI for light-weight local ephemeral volumes if the CSI driver is meant to + be used that way - see the documentation of the driver for + more information. + + + A pod can use both types of ephemeral volumes and + persistent volumes at the same time. + properties: + volumeClaimTemplate: + description: |- + Will be used to create a stand-alone PVC to provision the volume. + The pod in which this EphemeralVolumeSource is embedded will be the + owner of the PVC, i.e. the PVC will be deleted together with the + pod. The name of the PVC will be `-` where + `` is the name from the `PodSpec.Volumes` array + entry. Pod validation will reject the pod if the concatenated name + is not valid for a PVC (for example, too long). + + + An existing PVC with that name that is not owned by the pod + will *not* be used for the pod to avoid using an unrelated + volume by mistake. Starting the pod is then blocked until + the unrelated PVC is removed. If such a pre-created PVC is + meant to be used by the pod, the PVC has to updated with an + owner reference to the pod once the pod exists. Normally + this should not be necessary, but it may be useful when + manually reconstructing a broken cluster. + + + This field is read-only and no changes will be made by Kubernetes + to the PVC after it has been created. + + + Required, must not be nil. + properties: + metadata: + description: |- + May contain labels and annotations that will be copied into the PVC + when creating it. No other fields are allowed and will be rejected during + validation. + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + description: |- + The specification for the PersistentVolumeClaim. The entire content is + copied unchanged into the PVC that gets created from this + template. The same fields as in a PersistentVolumeClaim + are also valid here. + properties: + accessModes: + description: |- + accessModes contains the desired access modes the volume should have. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1 + items: + type: string + type: array + dataSource: + description: |- + dataSource field can be used to specify either: + * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) + * An existing PVC (PersistentVolumeClaim) + If the provisioner or an external controller can support the specified data source, + it will create a new volume based on the contents of the specified data source. + When the AnyVolumeDataSource feature gate is enabled, dataSource contents will be copied to dataSourceRef, + and dataSourceRef contents will be copied to dataSource when dataSourceRef.namespace is not specified. + If the namespace is specified, then dataSourceRef will not be copied to dataSource. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource + being referenced + type: string + name: + description: Name is the name of resource + being referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + description: |- + dataSourceRef specifies the object from which to populate the volume with data, if a non-empty + volume is desired. This may be any object from a non-empty API group (non + core object) or a PersistentVolumeClaim object. + When this field is specified, volume binding will only succeed if the type of + the specified object matches some installed volume populator or dynamic + provisioner. + This field will replace the functionality of the dataSource field and as such + if both fields are non-empty, they must have the same value. For backwards + compatibility, when namespace isn't specified in dataSourceRef, + both fields (dataSource and dataSourceRef) will be set to the same + value automatically if one of them is empty and the other is non-empty. + When namespace is specified in dataSourceRef, + dataSource isn't set to the same value and must be empty. + There are three important differences between dataSource and dataSourceRef: + * While dataSource only allows two specific types of objects, dataSourceRef + allows any non-core object, as well as PersistentVolumeClaim objects. + * While dataSource ignores disallowed values (dropping them), dataSourceRef + preserves all values, and generates an error if a disallowed value is + specified. + * While dataSource only allows local objects, dataSourceRef allows objects + in any namespaces. + (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled. + (Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource + being referenced + type: string + name: + description: Name is the name of resource + being referenced + type: string + namespace: + description: |- + Namespace is the namespace of resource being referenced + Note that when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details. + (Alpha) This field requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + type: string + required: + - kind + - name + type: object + resources: + description: |- + resources represents the minimum resources the volume should have. + If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements + that are lower than previous value but must still be higher than capacity recorded in the + status field of the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + selector: + description: selector is a label query + over volumes to consider for binding. + properties: + matchExpressions: + description: matchExpressions is a + list of label selector requirements. + The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + description: |- + storageClassName is the name of the StorageClass required by the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1 + type: string + volumeAttributesClassName: + description: |- + volumeAttributesClassName may be used to set the VolumeAttributesClass used by this claim. + If specified, the CSI driver will create or update the volume with the attributes defined + in the corresponding VolumeAttributesClass. This has a different purpose than storageClassName, + it can be changed after the claim is created. An empty string value means that no VolumeAttributesClass + will be applied to the claim but it's not allowed to reset this field to empty string once it is set. + If unspecified and the PersistentVolumeClaim is unbound, the default VolumeAttributesClass + will be set by the persistentvolume controller if it exists. + If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be + set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource + exists. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#volumeattributesclass + (Alpha) Using this field requires the VolumeAttributesClass feature gate to be enabled. + type: string + volumeMode: + description: |- + volumeMode defines what type of volume is required by the claim. + Value of Filesystem is implied when not included in claim spec. + type: string + volumeName: + description: volumeName is the binding + reference to the PersistentVolume backing + this claim. + type: string + type: object + required: + - spec + type: object + type: object + fc: + description: fc represents a Fibre Channel resource + that is attached to a kubelet's host machine and + then exposed to the pod. + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + lun: + description: 'lun is Optional: FC target lun number' + format: int32 + type: integer + readOnly: + description: |- + readOnly is Optional: Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + targetWWNs: + description: 'targetWWNs is Optional: FC target + worldwide names (WWNs)' + items: + type: string + type: array + wwids: + description: |- + wwids Optional: FC volume world wide identifiers (wwids) + Either wwids or combination of targetWWNs and lun must be set, but not both simultaneously. + items: + type: string + type: array + type: object + flexVolume: + description: |- + flexVolume represents a generic volume resource that is + provisioned/attached using an exec based plugin. + properties: + driver: + description: driver is the name of the driver + to use for this volume. + type: string + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". The default filesystem depends on FlexVolume script. + type: string + options: + additionalProperties: + type: string + description: 'options is Optional: this field + holds extra command options if any.' + type: object + readOnly: + description: |- + readOnly is Optional: defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: |- + secretRef is Optional: secretRef is reference to the secret object containing + sensitive information to pass to the plugin scripts. This may be + empty if no secret object is specified. If the secret object + contains more than one secret, all secrets are passed to the plugin + scripts. + 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 + required: + - driver + type: object + flocker: + description: flocker represents a Flocker volume attached + to a kubelet's host machine. This depends on the + Flocker control service being running + properties: + datasetName: + description: |- + datasetName is Name of the dataset stored as metadata -> name on the dataset for Flocker + should be considered as deprecated + type: string + datasetUUID: + description: datasetUUID is the UUID of the dataset. + This is unique identifier of a Flocker dataset + type: string + type: object + gcePersistentDisk: + description: |- + gcePersistentDisk represents a GCE Disk resource that is attached to a + kubelet's host machine and then exposed to the pod. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + properties: + fsType: + description: |- + fsType is filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + partition: + description: |- + partition is the partition in the volume that you want to mount. + If omitted, the default is to mount by volume name. + Examples: For volume /dev/sda1, you specify the partition as "1". + Similarly, the volume partition for /dev/sda is "0" (or you can leave the property empty). + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + format: int32 + type: integer + pdName: + description: |- + pdName is unique name of the PD resource in GCE. Used to identify the disk in GCE. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + type: string + readOnly: + description: |- + readOnly here will force the ReadOnly setting in VolumeMounts. + Defaults to false. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + type: boolean + required: + - pdName + type: object + gitRepo: + description: |- + gitRepo represents a git repository at a particular revision. + DEPRECATED: GitRepo is deprecated. To provision a container with a git repo, mount an + EmptyDir into an InitContainer that clones the repo using git, then mount the EmptyDir + into the Pod's container. + properties: + directory: + description: |- + directory is the target directory name. + Must not contain or start with '..'. If '.' is supplied, the volume directory will be the + git repository. Otherwise, if specified, the volume will contain the git repository in + the subdirectory with the given name. + type: string + repository: + description: repository is the URL + type: string + revision: + description: revision is the commit hash for the + specified revision. + type: string + required: + - repository + type: object + glusterfs: + description: |- + glusterfs represents a Glusterfs mount on the host that shares a pod's lifetime. + More info: https://examples.k8s.io/volumes/glusterfs/README.md + properties: + endpoints: + description: |- + endpoints is the endpoint name that details Glusterfs topology. + More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod + type: string + path: + description: |- + path is the Glusterfs volume path. + More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod + type: string + readOnly: + description: |- + readOnly here will force the Glusterfs volume to be mounted with read-only permissions. + Defaults to false. + More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod + type: boolean + required: + - endpoints + - path + type: object + hostPath: + description: |- + hostPath represents a pre-existing file or directory on the host + machine that is directly exposed to the container. This is generally + used for system agents or other privileged things that are allowed + to see the host machine. Most containers will NOT need this. + More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + --- + TODO(jonesdl) We need to restrict who can use host directory mounts and who can/can not + mount host directories as read/write. + properties: + path: + description: |- + path of the directory on the host. + If the path is a symlink, it will follow the link to the real path. + More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + type: string + type: + description: |- + type for HostPath Volume + Defaults to "" + More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + type: string + required: + - path + type: object + iscsi: + description: |- + iscsi represents an ISCSI Disk resource that is attached to a + kubelet's host machine and then exposed to the pod. + More info: https://examples.k8s.io/volumes/iscsi/README.md + properties: + chapAuthDiscovery: + description: chapAuthDiscovery defines whether + support iSCSI Discovery CHAP authentication + type: boolean + chapAuthSession: + description: chapAuthSession defines whether support + iSCSI Session CHAP authentication + type: boolean + fsType: + description: |- + fsType is the filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#iscsi + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + initiatorName: + description: |- + initiatorName is the custom iSCSI Initiator Name. + If initiatorName is specified with iscsiInterface simultaneously, new iSCSI interface + : will be created for the connection. + type: string + iqn: + description: iqn is the target iSCSI Qualified + Name. + type: string + iscsiInterface: + description: |- + iscsiInterface is the interface Name that uses an iSCSI transport. + Defaults to 'default' (tcp). + type: string + lun: + description: lun represents iSCSI Target Lun number. + format: int32 + type: integer + portals: + description: |- + portals is the iSCSI Target Portal List. The portal is either an IP or ip_addr:port if the port + is other than default (typically TCP ports 860 and 3260). + items: + type: string + type: array + readOnly: + description: |- + readOnly here will force the ReadOnly setting in VolumeMounts. + Defaults to false. + type: boolean + secretRef: + description: secretRef is the CHAP Secret for + iSCSI target and initiator authentication + 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 + targetPortal: + description: |- + targetPortal is iSCSI Target Portal. The Portal is either an IP or ip_addr:port if the port + is other than default (typically TCP ports 860 and 3260). + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + description: |- + name of the volume. + Must be a DNS_LABEL and unique within the pod. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + nfs: + description: |- + nfs represents an NFS mount on the host that shares a pod's lifetime + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + properties: + path: + description: |- + path that is exported by the NFS server. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + type: string + readOnly: + description: |- + readOnly here will force the NFS export to be mounted with read-only permissions. + Defaults to false. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + type: boolean + server: + description: |- + server is the hostname or IP address of the NFS server. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + description: |- + persistentVolumeClaimVolumeSource represents a reference to a + PersistentVolumeClaim in the same namespace. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims + properties: + claimName: + description: |- + claimName is the name of a PersistentVolumeClaim in the same namespace as the pod using this volume. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims + type: string + readOnly: + description: |- + readOnly Will force the ReadOnly setting in VolumeMounts. + Default false. + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + description: photonPersistentDisk represents a PhotonController + persistent disk attached and mounted on kubelets + host machine + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + pdID: + description: pdID is the ID that identifies Photon + Controller persistent disk + type: string + required: + - pdID + type: object + portworxVolume: + description: portworxVolume represents a portworx + volume attached and mounted on kubelets host machine + properties: + fsType: + description: |- + fSType represents the filesystem type to mount + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs". Implicitly inferred to be "ext4" if unspecified. + type: string + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + volumeID: + description: volumeID uniquely identifies a Portworx + volume + type: string + required: + - volumeID + type: object + projected: + description: projected items for all in one resources + secrets, configmaps, and downward API + properties: + defaultMode: + description: |- + defaultMode are the mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + sources: + description: sources is the list of volume projections + items: + description: Projection that may be projected + along with other supported volume types + properties: + clusterTrustBundle: + description: |- + ClusterTrustBundle allows a pod to access the `.spec.trustBundle` field + of ClusterTrustBundle objects in an auto-updating file. + + + Alpha, gated by the ClusterTrustBundleProjection feature gate. + + + ClusterTrustBundle objects can either be selected by name, or by the + combination of signer name and a label selector. + + + Kubelet performs aggressive normalization of the PEM contents written + into the pod filesystem. Esoteric PEM features such as inter-block + comments and block headers are stripped. Certificates are deduplicated. + The ordering of certificates within the file is arbitrary, and Kubelet + may change the order over time. + properties: + labelSelector: + description: |- + Select all ClusterTrustBundles that match this label selector. Only has + effect if signerName is set. Mutually-exclusive with name. If unset, + interpreted as "match nothing". If set but empty, interpreted as "match + everything". + properties: + matchExpressions: + description: matchExpressions is + a list of label selector requirements. + The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + name: + description: |- + Select a single ClusterTrustBundle by object name. Mutually-exclusive + with signerName and labelSelector. + type: string + optional: + description: |- + If true, don't block pod startup if the referenced ClusterTrustBundle(s) + aren't available. If using name, then the named ClusterTrustBundle is + allowed not to exist. If using signerName, then the combination of + signerName and labelSelector is allowed to match zero + ClusterTrustBundles. + type: boolean + path: + description: Relative path from the + volume root to write the bundle. + type: string + signerName: + description: |- + Select all ClusterTrustBundles that match this signer name. + Mutually-exclusive with name. The contents of all selected + ClusterTrustBundles will be unified and deduplicated. + type: string + required: + - path + type: object + configMap: + description: configMap information about + the configMap data to project + properties: + items: + description: |- + items if unspecified, each key-value pair in the Data field of the referenced + ConfigMap will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the ConfigMap, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to + a path within a volume. + properties: + key: + description: key is the key to + project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + 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 + optional: + description: optional specify whether + the ConfigMap or its keys must be + defined + type: boolean + type: object + x-kubernetes-map-type: atomic + downwardAPI: + description: downwardAPI information about + the downwardAPI data to project + properties: + items: + description: Items is a list of DownwardAPIVolume + file + items: + description: DownwardAPIVolumeFile + represents information to create + the file containing the pod field + properties: + fieldRef: + description: 'Required: Selects + a field of the pod: only annotations, + labels, name and namespace are + supported.' + properties: + apiVersion: + description: Version of the + schema the FieldPath is + written in terms of, defaults + to "v1". + type: string + fieldPath: + description: Path of the field + to select in the specified + API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + description: |- + Optional: mode bits used to set permissions on this file, must be an octal value + between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: 'Required: Path is the + relative path name of the file + to be created. Must not be absolute + or contain the ''..'' path. + Must be utf-8 encoded. The first + item of the relative path must + not start with ''..''' + type: string + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported. + properties: + containerName: + description: 'Container name: + required for volumes, optional + for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the + output format of the exposed + resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource + to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + type: object + secret: + description: secret information about the + secret data to project + properties: + items: + description: |- + items if unspecified, each key-value pair in the Data field of the referenced + Secret will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the Secret, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to + a path within a volume. + properties: + key: + description: key is the key to + project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + 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 + optional: + description: optional field specify + whether the Secret or its key must + be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + serviceAccountToken: + description: serviceAccountToken is information + about the serviceAccountToken data to + project + properties: + audience: + description: |- + audience is the intended audience of the token. A recipient of a token + must identify itself with an identifier specified in the audience of the + token, and otherwise should reject the token. The audience defaults to the + identifier of the apiserver. + type: string + expirationSeconds: + description: |- + expirationSeconds is the requested duration of validity of the service + account token. As the token approaches expiration, the kubelet volume + plugin will proactively rotate the service account token. The kubelet will + start trying to rotate the token if the token is older than 80 percent of + its time to live or if the token is older than 24 hours.Defaults to 1 hour + and must be at least 10 minutes. + format: int64 + type: integer + path: + description: |- + path is the path relative to the mount point of the file to project the + token into. + type: string + required: + - path + type: object + type: object + type: array + type: object + quobyte: + description: quobyte represents a Quobyte mount on + the host that shares a pod's lifetime + properties: + group: + description: |- + group to map volume access to + Default is no group + type: string + readOnly: + description: |- + readOnly here will force the Quobyte volume to be mounted with read-only permissions. + Defaults to false. + type: boolean + registry: + description: |- + registry represents a single or multiple Quobyte Registry services + specified as a string as host:port pair (multiple entries are separated with commas) + which acts as the central registry for volumes + type: string + tenant: + description: |- + tenant owning the given Quobyte volume in the Backend + Used with dynamically provisioned Quobyte volumes, value is set by the plugin + type: string + user: + description: |- + user to map volume access to + Defaults to serivceaccount user + type: string + volume: + description: volume is a string that references + an already created Quobyte volume by name. + type: string + required: + - registry + - volume + type: object + rbd: + description: |- + rbd represents a Rados Block Device mount on the host that shares a pod's lifetime. + More info: https://examples.k8s.io/volumes/rbd/README.md + properties: + fsType: + description: |- + fsType is the filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#rbd + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + image: + description: |- + image is the rados image name. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + keyring: + description: |- + keyring is the path to key ring for RBDUser. + Default is /etc/ceph/keyring. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + monitors: + description: |- + monitors is a collection of Ceph monitors. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + items: + type: string + type: array + pool: + description: |- + pool is the rados pool name. + Default is rbd. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + readOnly: + description: |- + readOnly here will force the ReadOnly setting in VolumeMounts. + Defaults to false. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: boolean + secretRef: + description: |- + secretRef is name of the authentication secret for RBDUser. If provided + overrides keyring. + Default is nil. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + 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 + user: + description: |- + user is the rados user name. + Default is admin. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + required: + - image + - monitors + type: object + scaleIO: + description: scaleIO represents a ScaleIO persistent + volume attached and mounted on Kubernetes nodes. + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". + Default is "xfs". + type: string + gateway: + description: gateway is the host address of the + ScaleIO API Gateway. + type: string + protectionDomain: + description: protectionDomain is the name of the + ScaleIO Protection Domain for the configured + storage. + type: string + readOnly: + description: |- + readOnly Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: |- + secretRef references to the secret for ScaleIO user and other + sensitive information. If this is not provided, Login operation will fail. + 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 + sslEnabled: + description: sslEnabled Flag enable/disable SSL + communication with Gateway, default false + type: boolean + storageMode: + description: |- + storageMode indicates whether the storage for a volume should be ThickProvisioned or ThinProvisioned. + Default is ThinProvisioned. + type: string + storagePool: + description: storagePool is the ScaleIO Storage + Pool associated with the protection domain. + type: string + system: + description: system is the name of the storage + system as configured in ScaleIO. + type: string + volumeName: + description: |- + volumeName is the name of a volume already created in the ScaleIO system + that is associated with this volume source. + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + description: |- + secret represents a secret that should populate this volume. + More info: https://kubernetes.io/docs/concepts/storage/volumes#secret + properties: + defaultMode: + description: |- + defaultMode is Optional: mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values + for mode bits. Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + items: + description: |- + items If unspecified, each key-value pair in the Data field of the referenced + Secret will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the Secret, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within + a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + optional: + description: optional field specify whether the + Secret or its keys must be defined + type: boolean + secretName: + description: |- + secretName is the name of the secret in the pod's namespace to use. + More info: https://kubernetes.io/docs/concepts/storage/volumes#secret + type: string + type: object + storageos: + description: storageOS represents a StorageOS volume + attached and mounted on Kubernetes nodes. + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: |- + secretRef specifies the secret to use for obtaining the StorageOS API + credentials. If not specified, default values will be attempted. + 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 + volumeName: + description: |- + volumeName is the human-readable name of the StorageOS volume. Volume + names are only unique within a namespace. + type: string + volumeNamespace: + description: |- + volumeNamespace specifies the scope of the volume within StorageOS. If no + namespace is specified then the Pod's namespace will be used. This allows the + Kubernetes name scoping to be mirrored within StorageOS for tighter integration. + Set VolumeName to any name to override the default behaviour. + Set to "default" if you are not using namespaces within StorageOS. + Namespaces that do not pre-exist within StorageOS will be created. + type: string + type: object + vsphereVolume: + description: vsphereVolume represents a vSphere volume + attached and mounted on kubelets host machine + properties: + fsType: + description: |- + fsType is filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + storagePolicyID: + description: storagePolicyID is the storage Policy + Based Management (SPBM) profile ID associated + with the StoragePolicyName. + type: string + storagePolicyName: + description: storagePolicyName is the storage + Policy Based Management (SPBM) profile name. + type: string + volumePath: + description: volumePath is the path that identifies + vSphere volume vmdk + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + required: + - replicas + type: object + required: + - name + - template + type: object + maxItems: 128 + minItems: 1 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + terminationPolicy: + description: |- + Specifies the behavior when a Cluster is deleted. + It defines how resources, data, and backups associated with a Cluster are managed during termination. + Choose a policy based on the desired level of resource cleanup and data preservation: + + + - `DoNotTerminate`: Prevents deletion of the Cluster. This policy ensures that all resources remain intact. + - `Halt`: Deletes Cluster resources like Pods and Services but retains Persistent Volume Claims (PVCs), + allowing for data preservation while stopping other operations. + - `Delete`: Extends the `Halt` policy by also removing PVCs, leading to a thorough cleanup while + removing all persistent data. + - `WipeOut`: An aggressive policy that deletes all Cluster resources, including volume snapshots and + backups in external storage. + This results in complete data removal and should be used cautiously, primarily in non-production environments + to avoid irreversible data loss. + + + Warning: Choosing an inappropriate termination policy can result in data loss. + The `WipeOut` policy is particularly risky in production environments due to its irreversible nature. + enum: + - DoNotTerminate + - Halt + - Delete + - WipeOut + type: string + topology: + description: |- + Specifies the name of the ClusterTopology to be used when creating the Cluster. + + + This field defines which set of Components, as outlined in the ClusterDefinition, will be used to + construct the Cluster based on the named topology. + The ClusterDefinition may list multiple topologies under `clusterdefinition.spec.topologies[*]`, + each tailored to different use cases or environments. + + + If `topology` is not specified, the Cluster will use the default topology defined in the ClusterDefinition. + + + Note: Once set during the Cluster creation, the `topology` field cannot be modified. + It establishes the initial composition and structure of the Cluster and is intended for one-time configuration. + maxLength: 32 type: string + required: + - terminationPolicy type: object status: - description: ClusterStatus defines the observed state of Cluster + description: ClusterStatus defines the observed state of the Cluster. + properties: + clusterDefGeneration: + description: Represents the generation number of the referenced ClusterDefinition. + format: int64 + type: integer + components: + additionalProperties: + description: ClusterComponentStatus records Component status. + properties: + message: + additionalProperties: + type: string + description: |- + Records detailed information about the Component in its current phase. + The keys are either podName, deployName, or statefulSetName, formatted as 'ObjectKind/Name'. + type: object + phase: + description: Specifies the current state of the Component. + enum: + - Creating + - Running + - Updating + - Stopping + - Stopped + - Deleting + - Failed + - Abnormal + type: string + type: object + description: Records the current status information of all Components + within the Cluster. + type: object + conditions: + description: |- + Represents a list of detailed status of the Cluster object. + Each condition in the list provides real-time information about certain aspect of the Cluster object. + + + This field is crucial for administrators and developers to monitor and respond to changes within the Cluster. + It provides a history of state transitions and a snapshot of the current state that can be used for + automated logic or direct inspection. + items: + description: "Condition contains details for one aspect of the current + state of this API Resource.\n---\nThis struct is intended for + direct use as an array at the field path .status.conditions. For + example,\n\n\n\ttype FooStatus struct{\n\t // Represents the + observations of a foo's current state.\n\t // Known .status.conditions.type + are: \"Available\", \"Progressing\", and \"Degraded\"\n\t // + +patchMergeKey=type\n\t // +patchStrategy=merge\n\t // +listType=map\n\t + \ // +listMapKey=type\n\t Conditions []metav1.Condition `json:\"conditions,omitempty\" + patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t + \ // other fields\n\t}" + 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 + message: + description: Provides additional information about the current phase. + type: string + observedGeneration: + description: The most recent generation number of the Cluster object + that has been observed by the controller. + format: int64 + type: integer + phase: + description: |- + The current phase of the Cluster includes: + `Creating`, `Running`, `Updating`, `Stopping`, `Stopped`, `Deleting`, `Failed`, `Abnormal`. + enum: + - Creating + - Running + - Updating + - Stopping + - Stopped + - Deleting + - Failed + - Abnormal + type: string type: object type: object served: true diff --git a/docs/developer_docs/api-reference/cluster.md b/docs/developer_docs/api-reference/cluster.md index bf7da55424e..cfaccb53995 100644 --- a/docs/developer_docs/api-reference/cluster.md +++ b/docs/developer_docs/api-reference/cluster.md @@ -116,13 +116,180 @@ ClusterSpec
FieldDescription
-observedGeneration
+serviceRefVarRef
-int64 + +ServiceRefVarSelector +
(Optional) -

Represents the generation number that has been processed by the controller.

+

Selects a defined var of a ServiceRef.

-phase
+componentVarRef
- -Phase + +ComponentVarSelector
(Optional) -

Indicates the current lifecycle phase of the ServiceDescriptor. This can be either ‘Available’ or ‘Unavailable’.

+

Selects a defined var of a Component.

-message
+clusterVarRef
-string + +ClusterVarSelector +
(Optional) -

Provides a human-readable explanation detailing the reason for the current phase of the ServiceConnectionCredential.

+

Selects a defined var of a Cluster.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
-foo
+clusterDefinitionRef
+ +string + +
+(Optional) +

Specifies the name of the ClusterDefinition to use when creating a Cluster.

+

This field enables users to create a Cluster based on a specific ClusterDefinition. +Which, in conjunction with the topology field, determine:

+
    +
  • The Components to be included in the Cluster.
  • +
  • The sequences in which the Components are created, updated, and terminate.
  • +
+

This facilitates multiple-components management with predefined ClusterDefinition.

+

Users with advanced requirements can bypass this general setting and specify more precise control over +the composition of the Cluster by directly referencing specific ComponentDefinitions for each component +within componentSpecs[*].componentDef.

+

If this field is not provided, each component must be explicitly defined in componentSpecs[*].componentDef.

+

Note: Once set, this field cannot be modified; it is immutable.

+
+clusterVersionRef
+ +string + +
+(Optional) +

Refers to the ClusterVersion name.

+

Deprecated since v0.9, use ComponentVersion instead. +This field is maintained for backward compatibility and its use is discouraged. +Existing usage should be updated to the current preferred approach to avoid compatibility issues in future releases.

+
+topology
+ +string + +
+(Optional) +

Specifies the name of the ClusterTopology to be used when creating the Cluster.

+

This field defines which set of Components, as outlined in the ClusterDefinition, will be used to +construct the Cluster based on the named topology. +The ClusterDefinition may list multiple topologies under clusterdefinition.spec.topologies[*], +each tailored to different use cases or environments.

+

If topology is not specified, the Cluster will use the default topology defined in the ClusterDefinition.

+

Note: Once set during the Cluster creation, the topology field cannot be modified. +It establishes the initial composition and structure of the Cluster and is intended for one-time configuration.

+
+terminationPolicy
+ + +TerminationPolicyType + + +
+

Specifies the behavior when a Cluster is deleted. +It defines how resources, data, and backups associated with a Cluster are managed during termination. +Choose a policy based on the desired level of resource cleanup and data preservation:

+
    +
  • DoNotTerminate: Prevents deletion of the Cluster. This policy ensures that all resources remain intact.
  • +
  • Halt: Deletes Cluster resources like Pods and Services but retains Persistent Volume Claims (PVCs), +allowing for data preservation while stopping other operations.
  • +
  • Delete: Extends the Halt policy by also removing PVCs, leading to a thorough cleanup while +removing all persistent data.
  • +
  • WipeOut: An aggressive policy that deletes all Cluster resources, including volume snapshots and +backups in external storage. +This results in complete data removal and should be used cautiously, primarily in non-production environments +to avoid irreversible data loss.
  • +
+

Warning: Choosing an inappropriate termination policy can result in data loss. +The WipeOut policy is particularly risky in production environments due to its irreversible nature.

+
+componentSpecs
+ + +[]ClusterComponentSpec + + +
+(Optional) +

Specifies a list of ClusterComponentSpec objects used to define the individual Components that make up a Cluster. +This field allows for detailed configuration of each Component within the Cluster.

+

Note: shardingSpecs and componentSpecs cannot both be empty; at least one must be defined to configure a Cluster.

+
+shardingSpecs
+ + +[]ShardingSpec + + +
+(Optional) +

Specifies a list of ShardingSpec objects that manage the sharding topology for Cluster Components. +Each ShardingSpec organizes components into shards, with each shard corresponding to a Component. +Components within a shard are all based on a common ClusterComponentSpec template, ensuring uniform configurations.

+

This field supports dynamic resharding by facilitating the addition or removal of shards +through the shards field in ShardingSpec.

+

Note: shardingSpecs and componentSpecs cannot both be empty; at least one must be defined to configure a Cluster.

+
+runtimeClassName
string
-

Foo is an example field of Cluster. Edit cluster_types.go to remove/update

+(Optional) +

Specifies runtimeClassName for all Pods managed by this Cluster.

+
+schedulingPolicy
+ + +SchedulingPolicy + + +
+(Optional) +

Specifies the scheduling policy for the Cluster.

+
+services
+ + +[]ClusterService + + +
+(Optional) +

Defines a list of additional Services that are exposed by a Cluster. +This field allows Services of selected Components, either from componentSpecs or shardingSpecs to be exposed, +alongside Services defined with ComponentService.

+

Services defined here can be referenced by other clusters using the ServiceRefClusterSelector.

+
+backup
+ + +ClusterBackup + + +
+(Optional) +

Specifies the backup configuration of the Cluster.

@@ -1782,13 +1949,12 @@ This execution does not alter the Component or the Cluster’s state of read -

ClusterComponentConfig +

ClusterBackup

-(Appears on:ComponentSpec) +(Appears on:ClusterSpec)

-

ClusterComponentConfig represents a config with its source bound.

@@ -1800,89 +1966,203 @@ This execution does not alter the Component or the Cluster’s state of read - -
-name
+enabled
-string +bool
(Optional) -

The name of the config.

+

Specifies whether automated backup is enabled for the Cluster.

-ClusterComponentConfigSource
+retentionPeriod
- -ClusterComponentConfigSource - +github.com/apecloud/kubeblocks/apis/dataprotection/v1alpha1.RetentionPeriod
-

-(Members of ClusterComponentConfigSource are embedded into this type.) -

-

The source of the config.

+(Optional) +

Determines the duration to retain backups. Backups older than this period are automatically removed.

+

For example, RetentionPeriod of 30d will keep only the backups of last 30 days. +Sample duration format:

+
    +
  • years: 2y
  • +
  • months: 6mo
  • +
  • days: 30d
  • +
  • hours: 12h
  • +
  • minutes: 30m
  • +
+

You can also combine the above durations. For example: 30d12h30m. +Default value is 7d.

-

ClusterComponentConfigSource -

-

-(Appears on:ClusterComponentConfig) -

-
-

ClusterComponentConfigSource represents the source of a config.

-
- - - - + + - - - -
FieldDescription +method
+ +string + +
+

Specifies the backup method to use, as defined in backupPolicy.

+
-configMap
+cronExpression
- -Kubernetes core/v1.ConfigMapVolumeSource - +string
(Optional) -

ConfigMap source for the config.

+

The cron expression for the schedule. The timezone is in UTC. See https://en.wikipedia.org/wiki/Cron.

-

ClusterComponentPhase -(string alias)

-

-(Appears on:ComponentStatus) -

-
-

ClusterComponentPhase defines the phase of a cluster component as represented in cluster.status.components.phase field.

-
- - - - - - - - - - - + + + + + + + + + + + +
ValueDescription

"Abnormal"

AbnormalClusterCompPhase indicates the component has more than zero replicas, but there are some failed pods. -The component is functioning, but it is in a fragile state.

-

"Creating"

CreatingClusterCompPhase indicates the component is being created.

+
+startingDeadlineMinutes
+ +int64 +

"Deleting"

+(Optional) +

Specifies the maximum time in minutes that the system will wait to start a missed backup job. +If the scheduled backup time is missed for any reason, the backup job must start within this deadline. +Values must be between 0 (immediate execution) and 1440 (one day).

+
+repoName
+ +string + +
+(Optional) +

Specifies the name of the backupRepo. If not set, the default backupRepo will be used.

+
+pitrEnabled
+ +bool + +
+(Optional) +

Specifies whether to enable point-in-time recovery.

+
+

ClusterComponentConfig +

+

+(Appears on:ClusterComponentSpec, ComponentSpec) +

+
+

ClusterComponentConfig represents a config with its source bound.

+
+ + + + + + + + + + + + + + + + + +
FieldDescription
+name
+ +string + +
+(Optional) +

The name of the config.

+
+ClusterComponentConfigSource
+ + +ClusterComponentConfigSource + + +
+

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

+

The source of the config.

+
+

ClusterComponentConfigSource +

+

+(Appears on:ClusterComponentConfig) +

+
+

ClusterComponentConfigSource represents the source of a config.

+
+ + + + + + + + + + + + + +
FieldDescription
+configMap
+ + +Kubernetes core/v1.ConfigMapVolumeSource + + +
+(Optional) +

ConfigMap source for the config.

+
+

ClusterComponentPhase +(string alias)

+

+(Appears on:ClusterComponentStatus, ComponentStatus, OpsRequestComponentStatus) +

+
+

ClusterComponentPhase defines the phase of a cluster component as represented in cluster.status.components.phase field.

+
+ + + + + + + + + + + + @@ -1905,10 +2185,10 @@ it is currently being updated.

ValueDescription

"Abnormal"

AbnormalClusterCompPhase indicates the component has more than zero replicas, but there are some failed pods. +The component is functioning, but it is in a fragile state.

+

"Creating"

CreatingClusterCompPhase indicates the component is being created.

+

"Deleting"

DeletingClusterCompPhase indicates the component is currently being deleted.

"Failed"

-

ClusterComponentVolumeClaimTemplate +

ClusterComponentService

-(Appears on:ComponentSpec, InstanceTemplate) +(Appears on:ClusterComponentSpec, LastComponentConfiguration)

@@ -1928,203 +2208,1226 @@ string -

Refers to the name of a volumeMount defined in either:

-
    -
  • componentDefinition.spec.runtime.containers[*].volumeMounts
  • -
  • clusterDefinition.spec.componentDefs[*].podSpec.containers[*].volumeMounts (deprecated)
  • -
-

The value of name must match the name field of a volumeMount specified in the corresponding volumeMounts array.

+

References the ComponentService name defined in the componentDefinition.spec.services[*].name.

-spec
+serviceType
- -PersistentVolumeClaimSpec + +Kubernetes core/v1.ServiceType (Optional) -

Defines the desired characteristics of a PersistentVolumeClaim that will be created for the volume -with the mount name specified in the name field.

-

When a Pod is created for this ClusterComponent, a new PVC will be created based on the specification -defined in the spec field. The PVC will be associated with the volume mount specified by the name field.

-
-
- +

Determines how the Service is exposed. Valid options are ClusterIP, NodePort, and LoadBalancer.

+
    +
  • ClusterIP allocates a Cluster-internal IP address for load-balancing to endpoints. +Endpoints are determined by the selector or if that is not specified, +they are determined by manual construction of an Endpoints object or EndpointSlice objects.
  • +
  • NodePort builds on ClusterIP and allocates a port on every node which routes to the same endpoints as the ClusterIP.
  • +
  • LoadBalancer builds on NodePort and creates an external load-balancer (if supported in the current cloud) +which routes to the same endpoints as the ClusterIP.
  • +
+

Note: although K8s Service type allows the ‘ExternalName’ type, it is not a valid option for ClusterComponentService.

+

For more info, see: +https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types.

+ + + +
-accessModes
+annotations
- -[]Kubernetes core/v1.PersistentVolumeAccessMode - +map[string]string
(Optional) -

Contains the desired access modes the volume should have. -More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1.

+

If ServiceType is LoadBalancer, cloud provider related parameters can be put here. +More info: https://kubernetes.io/docs/concepts/services-networking/service/#loadbalancer.

-resources
+podService
- -Kubernetes core/v1.VolumeResourceRequirements - +bool
(Optional) -

Represents the minimum resources the volume should have. -If the RecoverVolumeExpansionFailure feature is enabled, users are allowed to specify resource requirements that -are lower than the previous value but must still be higher than the capacity recorded in the status field of the claim. -More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources.

+

Indicates whether to generate individual Services for each Pod. +If set to true, a separate Service will be created for each Pod in the Cluster.

+

ClusterComponentSpec +

+

+(Appears on:ClusterSpec, ShardingSpec) +

+
+

ClusterComponentSpec defines the specification of a Component within a Cluster.

+
+ + + + + + + + -
FieldDescription
-storageClassName
+name
string
(Optional) -

The name of the StorageClass required by the claim. -More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1.

+

Specifies the Component’s name. +It’s part of the Service DNS name and must comply with the IANA service naming rule. +The name is optional when ClusterComponentSpec is used as a template (e.g., in shardingSpec), +but required otherwise.

-volumeMode
+componentDefRef
- -Kubernetes core/v1.PersistentVolumeMode - +string
(Optional) -

Defines what type of volume is required by the claim, either Block or Filesystem.

+

References a ClusterComponentDefinition defined in the clusterDefinition.spec.componentDef field. +Must comply with the IANA service naming rule.

+

Deprecated since v0.9, +because defining Components in clusterDefinition.spec.componentDef field has been deprecated. +This field is replaced by the componentDef field, use componentDef instead. +This field is maintained for backward compatibility and its use is discouraged. +Existing usage should be updated to the current preferred approach to avoid compatibility issues in future releases.

+ + +componentDef
+ +string + + + +(Optional) +

References the name of a ComponentDefinition object. +The ComponentDefinition specifies the behavior and characteristics of the Component. +If both componentDefRef and componentDef are provided, +the componentDef will take precedence over componentDefRef.

- - -

ClusterDefinitionSpec -

-

-(Appears on:ClusterDefinition) -

-
-

ClusterDefinitionSpec defines the desired state of ClusterDefinition.

-
- - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription +serviceVersion
+ +string + +
+(Optional) +

ServiceVersion specifies the version of the Service expected to be provisioned by this Component. +The version should follow the syntax and semantics of the “Semantic Versioning” specification (http://semver.org/). +If no version is specified, the latest available version will be used.

+
+serviceRefs
+ + +[]ServiceRef + + +
+(Optional) +

Defines a list of ServiceRef for a Component, enabling access to both external services and +Services provided by other Clusters.

+

Types of services:

+
    +
  • External services: Not managed by KubeBlocks or managed by a different KubeBlocks operator; +Require a ServiceDescriptor for connection details.
  • +
  • Services provided by a Cluster: Managed by the same KubeBlocks operator; +identified using Cluster, Component and Service names.
  • +
+

ServiceRefs with identical serviceRef.name in the same Cluster are considered the same.

+

Example:

+
serviceRefs:
+  - name: "redis-sentinel"
+    serviceDescriptor:
+      name: "external-redis-sentinel"
+  - name: "postgres-cluster"
+    clusterServiceSelector:
+      cluster: "my-postgres-cluster"
+      service:
+        component: "postgresql"
+
+

The example above includes ServiceRefs to an external Redis Sentinel service and a PostgreSQL Cluster.

+
+enabledLogs
+ +[]string + +
+(Optional) +

Specifies which types of logs should be collected for the Component. +The log types are defined in the componentDefinition.spec.logConfigs field with the LogConfig entries.

+

The elements in the enabledLogs array correspond to the names of the LogConfig entries. +For example, if the componentDefinition.spec.logConfigs defines LogConfig entries with +names “slow_query_log” and “error_log”, +you can enable the collection of these logs by including their names in the enabledLogs array:

+
enabledLogs:
+- slow_query_log
+- error_log
+
+
+labels
+ +map[string]string + +
+(Optional) +

Specifies Labels to override or add for underlying Pods.

+
+annotations
+ +map[string]string + +
+(Optional) +

Specifies Annotations to override or add for underlying Pods.

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

List of environment variables to add. +These environment variables will be placed after the environment variables declared in the Pod.

+
+replicas
+ +int32 + +
+

Specifies the desired number of replicas in the Component for enhancing availability and durability, or load balancing.

+
+schedulingPolicy
+ + +SchedulingPolicy + + +
+(Optional) +

Specifies the scheduling policy for the Component.

+
+resources
+ + +Kubernetes core/v1.ResourceRequirements + + +
+(Optional) +

Specifies the resources required by the Component. +It allows defining the CPU, memory requirements and limits for the Component’s containers.

+
+volumeClaimTemplates
+ + +[]ClusterComponentVolumeClaimTemplate + + +
+(Optional) +

Specifies a list of PersistentVolumeClaim templates that represent the storage requirements for the Component. +Each template specifies the desired characteristics of a persistent volume, such as storage class, +size, and access modes. +These templates are used to dynamically provision persistent volumes for the Component.

+
+volumes
+ + +[]Kubernetes core/v1.Volume + + +
+(Optional) +

List of volumes to override.

+
+services
+ + +[]ClusterComponentService + + +
+(Optional) +

Overrides services defined in referenced ComponentDefinition and expose endpoints that can be accessed by clients.

+
+systemAccounts
+ + +[]ComponentSystemAccount + + +
+(Optional) +

Overrides system accounts defined in referenced ComponentDefinition.

+
+configs
+ + +[]ClusterComponentConfig + + +
+(Optional) +

Specifies the configuration content of a config template.

+
+tls
+ +bool + +
+(Optional) +

A boolean flag that indicates whether the Component should use Transport Layer Security (TLS) +for secure communication. +When set to true, the Component will be configured to use TLS encryption for its network connections. +This ensures that the data transmitted between the Component and its clients or other Components is encrypted +and protected from unauthorized access. +If TLS is enabled, the Component may require additional configuration, such as specifying TLS certificates and keys, +to properly set up the secure communication channel.

+
+issuer
+ + +Issuer + + +
+(Optional) +

Specifies the configuration for the TLS certificates issuer. +It allows defining the issuer name and the reference to the secret containing the TLS certificates and key. +The secret should contain the CA certificate, TLS certificate, and private key in the specified keys. +Required when TLS is enabled.

+
+serviceAccountName
+ +string + +
+(Optional) +

Specifies the name of the ServiceAccount required by the running Component. +This ServiceAccount is used to grant necessary permissions for the Component’s Pods to interact +with other Kubernetes resources, such as modifying Pod labels or sending events.

+

Defaults: +To perform certain operational tasks, agent sidecars running in Pods require specific RBAC permissions. +The service account will be bound to a default role named “kubeblocks-cluster-pod-role” which is installed together with KubeBlocks. +If not specified, KubeBlocks automatically assigns a default ServiceAccount named “kb-{cluster.name}”

+

Future Changes: +Future versions might change the default ServiceAccount creation strategy to one per Component, +potentially revising the naming to “kb-{cluster.name}-{component.name}”.

+

Users can override the automatic ServiceAccount assignment by explicitly setting the name of +an existed ServiceAccount in this field.

+
+updateStrategy
+ + +UpdateStrategy + + +
+(Optional) +

Defines the update strategy for the Component.

+

Deprecated since v0.9. +This field is maintained for backward compatibility and its use is discouraged. +Existing usage should be updated to the current preferred approach to avoid compatibility issues in future releases.

+
+parallelPodManagementConcurrency
+ + +Kubernetes api utils intstr.IntOrString + + +
+(Optional) +

Controls the concurrency of pods during initial scale up, when replacing pods on nodes, +or when scaling down. It only used when PodManagementPolicy is set to Parallel. +The default Concurrency is 100%.

+
+podUpdatePolicy
+ + +PodUpdatePolicyType + + +
+(Optional) +

PodUpdatePolicy indicates how pods should be updated

+
    +
  • StrictInPlace indicates that only allows in-place upgrades. +Any attempt to modify other fields will be rejected.
  • +
  • PreferInPlace indicates that we will first attempt an in-place upgrade of the Pod. +If that fails, it will fall back to the ReCreate, where pod will be recreated. +Default value is “PreferInPlace”
  • +
+
+userResourceRefs
+ + +UserResourceRefs + + +
+(Optional) +

Allows users to specify custom ConfigMaps and Secrets to be mounted as volumes +in the Cluster’s Pods. +This is useful in scenarios where users need to provide additional resources to the Cluster, such as:

+
    +
  • Mounting custom scripts or configuration files during Cluster startup.
  • +
  • Mounting Secrets as volumes to provide sensitive information, like S3 AK/SK, to the Cluster.
  • +
+
+instances
+ + +[]InstanceTemplate + + +
+(Optional) +

Allows for the customization of configuration values for each instance within a Component. +An instance represent a single replica (Pod and associated K8s resources like PVCs, Services, and ConfigMaps). +While instances typically share a common configuration as defined in the ClusterComponentSpec, +they can require unique settings in various scenarios:

+

For example: +- A database Component might require different resource allocations for primary and secondary instances, + with primaries needing more resources. +- During a rolling upgrade, a Component may first update the image for one or a few instances, +and then update the remaining instances after verifying that the updated instances are functioning correctly.

+

InstanceTemplate allows for specifying these unique configurations per instance. +Each instance’s name is constructed using the pattern: $(component.name)-$(template.name)-$(ordinal), +starting with an ordinal of 0. +It is crucial to maintain unique names for each InstanceTemplate to avoid conflicts.

+

The sum of replicas across all InstanceTemplates should not exceed the total number of replicas specified for the Component. +Any remaining replicas will be generated using the default template and will follow the default naming rules.

+
+offlineInstances
+ +[]string + +
+(Optional) +

Specifies the names of instances to be transitioned to offline status.

+

Marking an instance as offline results in the following:

+
    +
  1. The associated Pod is stopped, and its PersistentVolumeClaim (PVC) is retained for potential +future reuse or data recovery, but it is no longer actively used.
  2. +
  3. The ordinal number assigned to this instance is preserved, ensuring it remains unique +and avoiding conflicts with new instances.
  4. +
+

Setting instances to offline allows for a controlled scale-in process, preserving their data and maintaining +ordinal consistency within the Cluster. +Note that offline instances and their associated resources, such as PVCs, are not automatically deleted. +The administrator must manually manage the cleanup and removal of these resources when they are no longer needed.

+
+disableExporter
+ +bool + +
+(Optional) +

Determines whether metrics exporter information is annotated on the Component’s headless Service.

+

If set to true, the following annotations will not be patched into the Service:

+
    +
  • “monitor.kubeblocks.io/path”
  • +
  • “monitor.kubeblocks.io/port”
  • +
  • “monitor.kubeblocks.io/scheme”
  • +
+

These annotations allow the Prometheus installed by KubeBlocks to discover and scrape metrics from the exporter.

+
+monitor
+ +bool + +
+(Optional) +

Deprecated since v0.9 +Determines whether metrics exporter information is annotated on the Component’s headless Service.

+

If set to true, the following annotations will be patched into the Service:

+
    +
  • “monitor.kubeblocks.io/path”
  • +
  • “monitor.kubeblocks.io/port”
  • +
  • “monitor.kubeblocks.io/scheme”
  • +
+

These annotations allow the Prometheus installed by KubeBlocks to discover and scrape metrics from the exporter.

+
+stop
+ +bool + +
+(Optional) +

Stop the Component. +If set, all the computing resources will be released.

+
+

ClusterComponentStatus +

+

+(Appears on:ClusterStatus) +

+
+

ClusterComponentStatus records Component status.

+
+ + + + + + + + + + + + + + + + + +
FieldDescription
+phase
+ + +ClusterComponentPhase + + +
+

Specifies the current state of the Component.

+
+message
+ +map[string]string + +
+(Optional) +

Records detailed information about the Component in its current phase. +The keys are either podName, deployName, or statefulSetName, formatted as ‘ObjectKind/Name’.

+
+

ClusterComponentVolumeClaimTemplate +

+

+(Appears on:ClusterComponentSpec, ComponentSpec, InstanceTemplate) +

+
+
+ + + + + + + + + + + + + + + + + +
FieldDescription
+name
+ +string + +
+

Refers to the name of a volumeMount defined in either:

+
    +
  • componentDefinition.spec.runtime.containers[*].volumeMounts
  • +
  • clusterDefinition.spec.componentDefs[*].podSpec.containers[*].volumeMounts (deprecated)
  • +
+

The value of name must match the name field of a volumeMount specified in the corresponding volumeMounts array.

+
+spec
+ + +PersistentVolumeClaimSpec + + +
+(Optional) +

Defines the desired characteristics of a PersistentVolumeClaim that will be created for the volume +with the mount name specified in the name field.

+

When a Pod is created for this ClusterComponent, a new PVC will be created based on the specification +defined in the spec field. The PVC will be associated with the volume mount specified by the name field.

+
+
+ + + + + + + + + + + + + + + + + +
+accessModes
+ + +[]Kubernetes core/v1.PersistentVolumeAccessMode + + +
+(Optional) +

Contains the desired access modes the volume should have. +More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1.

+
+resources
+ + +Kubernetes core/v1.VolumeResourceRequirements + + +
+(Optional) +

Represents the minimum resources the volume should have. +If the RecoverVolumeExpansionFailure feature is enabled, users are allowed to specify resource requirements that +are lower than the previous value but must still be higher than the capacity recorded in the status field of the claim. +More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources.

+
+storageClassName
+ +string + +
+(Optional) +

The name of the StorageClass required by the claim. +More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1.

+
+volumeMode
+ + +Kubernetes core/v1.PersistentVolumeMode + + +
+(Optional) +

Defines what type of volume is required by the claim, either Block or Filesystem.

+
+
+

ClusterDefinitionSpec +

+

+(Appears on:ClusterDefinition) +

+
+

ClusterDefinitionSpec defines the desired state of ClusterDefinition.

+
+ + + + + + + + + + + + + +
FieldDescription
+topologies
+ + +[]ClusterTopology + + +
+(Optional) +

Topologies defines all possible topologies within the cluster.

+
+

ClusterDefinitionStatus +

+

+(Appears on:ClusterDefinition) +

+
+

ClusterDefinitionStatus defines the observed state of ClusterDefinition

+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+observedGeneration
+ +int64 + +
+(Optional) +

Represents the most recent generation observed for this ClusterDefinition.

+
+phase
+ + +Phase + + +
+

Specifies the current phase of the ClusterDefinition. Valid values are empty, Available, Unavailable. +When Available, the ClusterDefinition is ready and can be referenced by related objects.

+
+message
+ +string + +
+(Optional) +

Provides additional information about the current phase.

+
+topologies
+ +string + +
+(Optional) +

Topologies this ClusterDefinition supported.

+
+

ClusterObjectReference +

+

+(Appears on:ComponentVarSelector, CredentialVarSelector, HostNetworkVarSelector, ServiceRefVarSelector, ServiceVarSelector) +

+
+

ClusterObjectReference defines information to let you locate the referenced object inside the same Cluster.

+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+compDef
+ +string + +
+(Optional) +

CompDef specifies the definition used by the component that the referent object resident in. +If not specified, the component itself will be used.

+
+name
+ +string + +
+(Optional) +

Name of the referent object.

+
+optional
+ +bool + +
+(Optional) +

Specify whether the object must be defined.

+
+multipleClusterObjectOption
+ + +MultipleClusterObjectOption + + +
+(Optional) +

This option defines the behavior when multiple component objects match the specified @CompDef. +If not provided, an error will be raised when handling multiple matches.

+
+

ClusterPhase +(string alias)

+

+(Appears on:ClusterStatus, OpsRequestBehaviour) +

+
+

ClusterPhase defines the phase of the Cluster within the .status.phase field.

+
+ + + + + + + + + + + + + + + + + + + + + + + + +
ValueDescription

"Abnormal"

AbnormalClusterPhase represents some components are in Failed or Abnormal phase, indicates that the cluster +is in a fragile state and troubleshooting is required.

+

"Creating"

CreatingClusterPhase represents all components are in Creating phase.

+

"Deleting"

DeletingClusterPhase indicates the cluster is being deleted.

+

"Failed"

FailedClusterPhase represents all components are in Failed phase, indicates that the cluster is unavailable.

+

"Running"

RunningClusterPhase represents all components are in Running phase, indicates that the cluster is functioning properly.

+

"Stopped"

StoppedClusterPhase represents all components are in Stopped phase, indicates that the cluster has stopped and +is not providing any functionality.

+

"Stopping"

StoppingClusterPhase represents at least one component is in Stopping phase, indicates that the cluster is in +the process of stopping.

+

"Updating"

UpdatingClusterPhase represents all components are in Creating, Running or Updating phase, and at least one +component is in Creating or Updating phase, indicates that the cluster is undergoing an update.

+
+

ClusterService +

+

+(Appears on:ClusterSpec) +

+
+

ClusterService defines a service that is exposed externally, allowing entities outside the cluster to access it. +For example, external applications, or other Clusters. +And another Cluster managed by the same KubeBlocks operator can resolve the address exposed by a ClusterService +using the serviceRef field.

+

When a Component needs to access another Cluster’s ClusterService using the serviceRef field, +it must also define the service type and version information in the componentDefinition.spec.serviceRefDeclarations +section.

+
+ + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+Service
+ + +Service + + +
+

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

+
+shardingSelector
+ +string + +
+(Optional) +

Extends the ServiceSpec.Selector by allowing the specification of a sharding name, which is defined in +cluster.spec.shardingSpecs[*].name, to be used as a selector for the service. +Note that this and the componentSelector are mutually exclusive and cannot be set simultaneously.

+
+componentSelector
+ +string + +
+(Optional) +

Extends the ServiceSpec.Selector by allowing the specification of a component, to be used as a selector for the service. +Note that this and the shardingSelector are mutually exclusive and cannot be set simultaneously.

+
+

ClusterSpec +

+

+(Appears on:Cluster) +

+
+

ClusterSpec defines the desired state of Cluster.

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + - - - -
FieldDescription
+clusterDefinitionRef
+ +string + +
+(Optional) +

Specifies the name of the ClusterDefinition to use when creating a Cluster.

+

This field enables users to create a Cluster based on a specific ClusterDefinition. +Which, in conjunction with the topology field, determine:

+
    +
  • The Components to be included in the Cluster.
  • +
  • The sequences in which the Components are created, updated, and terminate.
  • +
+

This facilitates multiple-components management with predefined ClusterDefinition.

+

Users with advanced requirements can bypass this general setting and specify more precise control over +the composition of the Cluster by directly referencing specific ComponentDefinitions for each component +within componentSpecs[*].componentDef.

+

If this field is not provided, each component must be explicitly defined in componentSpecs[*].componentDef.

+

Note: Once set, this field cannot be modified; it is immutable.

+
+clusterVersionRef
+ +string + +
+(Optional) +

Refers to the ClusterVersion name.

+

Deprecated since v0.9, use ComponentVersion instead. +This field is maintained for backward compatibility and its use is discouraged. +Existing usage should be updated to the current preferred approach to avoid compatibility issues in future releases.

+
+topology
+ +string + +
+(Optional) +

Specifies the name of the ClusterTopology to be used when creating the Cluster.

+

This field defines which set of Components, as outlined in the ClusterDefinition, will be used to +construct the Cluster based on the named topology. +The ClusterDefinition may list multiple topologies under clusterdefinition.spec.topologies[*], +each tailored to different use cases or environments.

+

If topology is not specified, the Cluster will use the default topology defined in the ClusterDefinition.

+

Note: Once set during the Cluster creation, the topology field cannot be modified. +It establishes the initial composition and structure of the Cluster and is intended for one-time configuration.

+
+terminationPolicy
+ + +TerminationPolicyType + + +
+

Specifies the behavior when a Cluster is deleted. +It defines how resources, data, and backups associated with a Cluster are managed during termination. +Choose a policy based on the desired level of resource cleanup and data preservation:

+
    +
  • DoNotTerminate: Prevents deletion of the Cluster. This policy ensures that all resources remain intact.
  • +
  • Halt: Deletes Cluster resources like Pods and Services but retains Persistent Volume Claims (PVCs), +allowing for data preservation while stopping other operations.
  • +
  • Delete: Extends the Halt policy by also removing PVCs, leading to a thorough cleanup while +removing all persistent data.
  • +
  • WipeOut: An aggressive policy that deletes all Cluster resources, including volume snapshots and +backups in external storage. +This results in complete data removal and should be used cautiously, primarily in non-production environments +to avoid irreversible data loss.
  • +
+

Warning: Choosing an inappropriate termination policy can result in data loss. +The WipeOut policy is particularly risky in production environments due to its irreversible nature.

+
+componentSpecs
+ + +[]ClusterComponentSpec + + +
+(Optional) +

Specifies a list of ClusterComponentSpec objects used to define the individual Components that make up a Cluster. +This field allows for detailed configuration of each Component within the Cluster.

+

Note: shardingSpecs and componentSpecs cannot both be empty; at least one must be defined to configure a Cluster.

+
-topologies
+shardingSpecs
- -[]ClusterTopology + +[]ShardingSpec
(Optional) -

Topologies defines all possible topologies within the cluster.

+

Specifies a list of ShardingSpec objects that manage the sharding topology for Cluster Components. +Each ShardingSpec organizes components into shards, with each shard corresponding to a Component. +Components within a shard are all based on a common ClusterComponentSpec template, ensuring uniform configurations.

+

This field supports dynamic resharding by facilitating the addition or removal of shards +through the shards field in ShardingSpec.

+

Note: shardingSpecs and componentSpecs cannot both be empty; at least one must be defined to configure a Cluster.

-

ClusterDefinitionStatus -

-

-(Appears on:ClusterDefinition) -

-
-

ClusterDefinitionStatus defines the observed state of ClusterDefinition

-
- - - - - - - -
FieldDescription
-observedGeneration
+runtimeClassName
-int64 +string
(Optional) -

Represents the most recent generation observed for this ClusterDefinition.

+

Specifies runtimeClassName for all Pods managed by this Cluster.

-phase
+schedulingPolicy
- -Phase + +SchedulingPolicy
-

Specifies the current phase of the ClusterDefinition. Valid values are empty, Available, Unavailable. -When Available, the ClusterDefinition is ready and can be referenced by related objects.

+(Optional) +

Specifies the scheduling policy for the Cluster.

-message
+services
-string + +[]ClusterService +
(Optional) -

Provides additional information about the current phase.

+

Defines a list of additional Services that are exposed by a Cluster. +This field allows Services of selected Components, either from componentSpecs or shardingSpecs to be exposed, +alongside Services defined with ComponentService.

+

Services defined here can be referenced by other clusters using the ServiceRefClusterSelector.

-topologies
+backup
-string + +ClusterBackup +
(Optional) -

Topologies this ClusterDefinition supported.

+

Specifies the backup configuration of the Cluster.

-

ClusterObjectReference +

ClusterStatus

-(Appears on:ComponentVarSelector, CredentialVarSelector, HostNetworkVarSelector, ServiceRefVarSelector, ServiceVarSelector) +(Appears on:Cluster)

-

ClusterObjectReference defines information to let you locate the referenced object inside the same Cluster.

+

ClusterStatus defines the observed state of the Cluster.

@@ -2136,95 +3439,89 @@ string - -
-compDef
+observedGeneration
-string +int64
(Optional) -

CompDef specifies the definition used by the component that the referent object resident in. -If not specified, the component itself will be used.

+

The most recent generation number of the Cluster object that has been observed by the controller.

-name
+phase
-string + +ClusterPhase +
(Optional) -

Name of the referent object.

+

The current phase of the Cluster includes: +Creating, Running, Updating, Stopping, Stopped, Deleting, Failed, Abnormal.

-optional
+message
-bool +string
(Optional) -

Specify whether the object must be defined.

+

Provides additional information about the current phase.

-multipleClusterObjectOption
+components
- -MultipleClusterObjectOption + +map[string]github.com/apecloud/kubeblocks/apis/apps/v1.ClusterComponentStatus
(Optional) -

This option defines the behavior when multiple component objects match the specified @CompDef. -If not provided, an error will be raised when handling multiple matches.

+

Records the current status information of all Components within the Cluster.

-

ClusterSpec -

-

-(Appears on:Cluster) -

-
-

ClusterSpec defines the desired state of Cluster

-
- - - - + + - -
FieldDescription +clusterDefGeneration
+ +int64 + +
+(Optional) +

Represents the generation number of the referenced ClusterDefinition.

+
-foo
+conditions
-string + +[]Kubernetes meta/v1.Condition +
-

Foo is an example field of Cluster. Edit cluster_types.go to remove/update

+(Optional) +

Represents a list of detailed status of the Cluster object. +Each condition in the list provides real-time information about certain aspect of the Cluster object.

+

This field is crucial for administrators and developers to monitor and respond to changes within the Cluster. +It provides a history of state transitions and a snapshot of the current state that can be used for +automated logic or direct inspection.

-

ClusterStatus -

-

-(Appears on:Cluster) -

-
-

ClusterStatus defines the observed state of Cluster

-

ClusterTopology

@@ -4207,7 +5504,7 @@ and Name is the specific name of the object.

ComponentSystemAccount

-(Appears on:ComponentSpec) +(Appears on:ClusterComponentSpec, ComponentSpec)

@@ -4807,6 +6104,52 @@ as defined in componentDefinition.spec.lifecycleActions.readWrite, +

ConfigMapRef +

+

+(Appears on:UserResourceRefs) +

+
+

ConfigMapRef defines a reference to a ConfigMap.

+
+ + + + + + + + + + + + + + + + + +
FieldDescription
+ResourceMeta
+ + +ResourceMeta + + +
+

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

+
+configMap
+ + +Kubernetes core/v1.ConfigMapVolumeSource + + +
+

ConfigMap specifies the ConfigMap to be mounted as a volume.

+

ConfigTemplateExtension

@@ -5543,7 +6886,7 @@ ContainerVars

InstanceTemplate

-(Appears on:ComponentSpec) +(Appears on:ClusterComponentSpec, ComponentSpec, LastComponentConfiguration, ScaleOut)

InstanceTemplate allows customization of individual replica configurations in a Component.

@@ -5717,7 +7060,7 @@ Add new or override existing volume claim templates.

Issuer

-(Appears on:TLSConfig) +(Appears on:ClusterComponentSpec, TLSConfig)

Issuer defines the TLS certificates issuer for the Cluster.

@@ -6338,7 +7681,7 @@ Kubernetes core/v1.PersistentVolumeMode

PodUpdatePolicyType (string alias)

-(Appears on:ComponentSpec) +(Appears on:ClusterComponentSpec, ComponentSpec)

@@ -6616,52 +7959,116 @@ configuration changes, or other processes that require a quorum.

Field Description - - + + + + +minReplicas
+ +int32 + + + +

The minimum limit of replicas.

+ + + + +maxReplicas
+ +int32 + + + +

The maximum limit of replicas.

+ + + + +

RerenderResourceType +(string alias)

+

+(Appears on:ComponentConfigSpec) +

+
+

RerenderResourceType defines the resource requirements for a component.

+
+ + + + + + + + + + + + +
ValueDescription

"hscale"

"vscale"

+

ResourceMeta +

+

+(Appears on:ConfigMapRef, SecretRef) +

+
+

ResourceMeta encapsulates metadata and configuration for referencing ConfigMaps and Secrets as volumes.

+
+ + + + + + + + + + + + - -
FieldDescription
+name
+ +string + +
+

Name is the name of the referenced ConfigMap or Secret object. It must conform to DNS label standards.

+
-minReplicas
+mountPoint
-int32 +string
-

The minimum limit of replicas.

+

MountPoint is the filesystem path where the volume will be mounted.

-maxReplicas
+subPath
-int32 +string
-

The maximum limit of replicas.

+(Optional) +

SubPath specifies a path within the volume from which to mount.

-

RerenderResourceType -(string alias)

-

-(Appears on:ComponentConfigSpec) -

-
-

RerenderResourceType defines the resource requirements for a component.

-
- - - - + + - - - - - - +
ValueDescription +asVolumeFrom
+ +[]string + +
+(Optional) +

AsVolumeFrom lists the names of containers in which the volume should be mounted.

+

"hscale"

"vscale"

RetryPolicy

@@ -6750,7 +8157,7 @@ VarOption

SchedulingPolicy

-(Appears on:ComponentSpec, InstanceTemplate) +(Appears on:ClusterComponentSpec, ClusterSpec, ComponentSpec, InstanceTemplate)

@@ -6856,10 +8263,56 @@ All topologySpreadConstraints are ANDed.

+

SecretRef +

+

+(Appears on:UserResourceRefs) +

+
+

SecretRef defines a reference to a Secret.

+
+ + + + + + + + + + + + + + + + + +
FieldDescription
+ResourceMeta
+ + +ResourceMeta + + +
+

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

+
+secret
+ + +Kubernetes core/v1.SecretVolumeSource + + +
+

Secret specifies the Secret to be mounted as a volume.

+

Service

-(Appears on:ComponentService) +(Appears on:ClusterService, ComponentService)

@@ -7517,7 +8970,7 @@ string

ServiceRef

-(Appears on:ComponentSpec) +(Appears on:ClusterComponentSpec, ComponentSpec)

@@ -8136,6 +9589,88 @@ and the value will be presented in the following format: service1.name:port1,ser +

ShardingSpec +

+

+(Appears on:ClusterSpec) +

+
+

ShardingSpec defines how KubeBlocks manage dynamic provisioned shards. +A typical design pattern for distributed databases is to distribute data across multiple shards, +with each shard consisting of multiple replicas. +Therefore, KubeBlocks supports representing a shard with a Component and dynamically instantiating Components +using a template when shards are added. +When shards are removed, the corresponding Components are also deleted.

+
+ + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+name
+ +string + +
+

Represents the common parent part of all shard names. +This identifier is included as part of the Service DNS name and must comply with IANA service naming rules. +It is used to generate the names of underlying Components following the pattern $(shardingSpec.name)-$(ShardID). +ShardID is a random string that is appended to the Name to generate unique identifiers for each shard. +For example, if the sharding specification name is “my-shard” and the ShardID is “abc”, the resulting Component name +would be “my-shard-abc”.

+

Note that the name defined in Component template(shardingSpec.template.name) will be disregarded +when generating the Component names of the shards. The shardingSpec.name field takes precedence.

+
+template
+ + +ClusterComponentSpec + + +
+

The template for generating Components for shards, where each shard consists of one Component. +This field is of type ClusterComponentSpec, which encapsulates all the required details and +definitions for creating and managing the Components. +KubeBlocks uses this template to generate a set of identical Components or shards. +All the generated Components will have the same specifications and definitions as specified in the template field.

+

This allows for the creation of multiple Components with consistent configurations, +enabling sharding and distribution of workloads across Components.

+
+shards
+ +int32 + +
+

Specifies the desired number of shards. +Users can declare the desired number of shards through this field. +KubeBlocks dynamically creates and deletes Components based on the difference +between the desired and actual number of shards. +KubeBlocks provides lifecycle management for sharding, including:

+
    +
  • Executing the postProvision Action defined in the ComponentDefinition when the number of shards increases. +This allows for custom actions to be performed after a new shard is provisioned.
  • +
  • Executing the preTerminate Action defined in the ComponentDefinition when the number of shards decreases. +This enables custom cleanup or data migration tasks to be executed before a shard is terminated. +Resources and data associated with the corresponding Component will also be deleted.
  • +
+

SystemAccount

@@ -8360,10 +9895,39 @@ string +

TerminationPolicyType +(string alias)

+

+(Appears on:ClusterSpec) +

+
+

TerminationPolicyType defines termination policy types.

+
+ + + + + + + + + + + + + + + + +
ValueDescription

"Delete"

Delete is based on Halt and deletes PVCs.

+

"DoNotTerminate"

DoNotTerminate will block delete operation.

+

"Halt"

Halt will delete workload resources such as statefulset, deployment workloads but keep PVCs.

+

"WipeOut"

WipeOut is based on Delete and wipe out all volume snapshots and snapshot data from backup storage location.

+

UpdateStrategy (string alias)

-(Appears on:ComponentDefinitionSpec) +(Appears on:ClusterComponentSpec, ComponentDefinitionSpec)

UpdateStrategy defines the update strategy for cluster components. This strategy determines how updates are applied @@ -8401,6 +9965,52 @@ This ensures that only one replica is unavailable at a time during the update pr +

UserResourceRefs +

+

+(Appears on:ClusterComponentSpec) +

+
+

UserResourceRefs defines references to user-defined Secrets and ConfigMaps.

+
+ + + + + + + + + + + + + + + + + +
FieldDescription
+secretRefs
+ + +[]SecretRef + + +
+(Optional) +

SecretRefs defines the user-defined Secrets.

+
+configMapRefs
+ + +[]ConfigMapRef + + +
+(Optional) +

ConfigMapRefs defines the user-defined ConfigMaps.

+

VarOption (string alias)

@@ -12372,7 +13982,7 @@ Kubernetes core/v1.ConfigMapVolumeSource

ClusterComponentPhase (string alias)

-(Appears on:ClusterComponentStatus, ComponentStatus, OpsRequestComponentStatus) +(Appears on:ClusterComponentStatus, ComponentStatus)

ClusterComponentPhase defines the phase of a cluster component as represented in cluster.status.components.phase field.

@@ -12417,7 +14027,7 @@ it is currently being updated.

ClusterComponentService

-(Appears on:ClusterComponentSpec, LastComponentConfiguration) +(Appears on:ClusterComponentSpec)

@@ -13498,7 +15108,7 @@ If not provided, an error will be raised when handling multiple matches.

ClusterPhase (string alias)

-(Appears on:ClusterStatus, OpsRequestBehaviour) +(Appears on:ClusterStatus)

ClusterPhase defines the phase of the Cluster within the .status.phase field.

@@ -19224,7 +20834,7 @@ Kubernetes core/v1.ResourceRequirements

InstanceTemplate

-(Appears on:ClusterComponentSpec, ComponentSpec, LastComponentConfiguration, ScaleOut) +(Appears on:ClusterComponentSpec, ComponentSpec)

InstanceTemplate allows customization of individual replica configurations in a Component.

@@ -19625,7 +21235,7 @@ Kubernetes core/v1.ResourceRequirements services
- + []ClusterComponentService @@ -19653,7 +21263,7 @@ The “pods” key maps to a list of names of all Pods of the Component. instances
- + []InstanceTemplate @@ -20646,7 +22256,7 @@ bool FromClusterPhases
- + []ClusterPhase @@ -20658,7 +22268,7 @@ bool ToClusterPhase
- + ClusterPhase @@ -20687,7 +22297,7 @@ ClusterPhase phase
- + ClusterComponentPhase @@ -23618,7 +25228,7 @@ ReplicaChanger newInstances
- + []InstanceTemplate diff --git a/pkg/configuration/config_manager/builder.go b/pkg/configuration/config_manager/builder.go index 6ee738d1f19..d2ce3147d43 100644 --- a/pkg/configuration/config_manager/builder.go +++ b/pkg/configuration/config_manager/builder.go @@ -38,7 +38,6 @@ import ( "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" appsv1beta1 "github.com/apecloud/kubeblocks/apis/apps/v1beta1" "github.com/apecloud/kubeblocks/pkg/configuration/core" cfgutil "github.com/apecloud/kubeblocks/pkg/configuration/util" @@ -202,7 +201,7 @@ func buildCMForConfig(manager *CfgManagerBuildParams, cmKey client.ObjectKey, co func createOrUpdateConfigMap(configInfo []ConfigSpecInfo, manager *CfgManagerBuildParams, cli client.Client, ctx context.Context) error { createConfigCM := func(configKey client.ObjectKey, config string) error { - scheme, err := appsv1alpha1.SchemeBuilder.Build() + scheme, err := appsv1.SchemeBuilder.Build() if err != nil { return err } @@ -351,7 +350,7 @@ func buildLazyRenderedConfigVolume(cmName string, manager *CfgManagerBuildParams manager.ConfigLazyRenderedVolumes[configSpec.VolumeName] = manager.Volumes[n] } -func checkOrCreateConfigMap(referenceCM client.ObjectKey, scriptCMKey client.ObjectKey, cli client.Client, ctx context.Context, cluster *appsv1alpha1.Cluster, fn func(cm *corev1.ConfigMap) error) error { +func checkOrCreateConfigMap(referenceCM client.ObjectKey, scriptCMKey client.ObjectKey, cli client.Client, ctx context.Context, cluster *appsv1.Cluster, fn func(cm *corev1.ConfigMap) error) error { var ( err error op controllerutil.OperationResult @@ -390,7 +389,7 @@ func checkOrCreateConfigMap(referenceCM client.ObjectKey, scriptCMKey client.Obj func createScripts(refCM *corev1.ConfigMap, key client.ObjectKey, owner client.Object, fn func(cm *corev1.ConfigMap) error) (*corev1.ConfigMap, error) { expected := &corev1.ConfigMap{} - scheme, _ := appsv1alpha1.SchemeBuilder.Build() + scheme, _ := appsv1.SchemeBuilder.Build() expected.Data = refCM.Data if fn != nil { if err := fn(expected); err != nil { diff --git a/pkg/configuration/config_manager/builder_test.go b/pkg/configuration/config_manager/builder_test.go index b1e4d24a1fc..e815911607c 100644 --- a/pkg/configuration/config_manager/builder_test.go +++ b/pkg/configuration/config_manager/builder_test.go @@ -34,7 +34,6 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" appsv1beta1 "github.com/apecloud/kubeblocks/apis/apps/v1beta1" testutil "github.com/apecloud/kubeblocks/pkg/testutil/k8s" ) @@ -132,7 +131,7 @@ var _ = Describe("Config Builder Test", func() { newCMBuildParams := func(hasScripts bool) *CfgManagerBuildParams { param := &CfgManagerBuildParams{ - Cluster: &appsv1alpha1.Cluster{ + Cluster: &appsv1.Cluster{ ObjectMeta: metav1.ObjectMeta{ Name: "abcd", Namespace: "default", diff --git a/pkg/configuration/config_manager/handler_util.go b/pkg/configuration/config_manager/handler_util.go index b396bb0e44d..5fe21f070fb 100644 --- a/pkg/configuration/config_manager/handler_util.go +++ b/pkg/configuration/config_manager/handler_util.go @@ -29,7 +29,6 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" appsv1beta1 "github.com/apecloud/kubeblocks/apis/apps/v1beta1" "github.com/apecloud/kubeblocks/pkg/configuration/core" ) @@ -49,7 +48,7 @@ type CfgManagerBuildParams struct { // add volume to pod ScriptVolume []corev1.Volume - Cluster *appsv1alpha1.Cluster + Cluster *appsv1.Cluster ConfigSpecsBuildParams []ConfigSpecMeta // init tools container diff --git a/pkg/configuration/core/config_query.go b/pkg/configuration/core/config_query.go index 459dc125175..46f3369c9a6 100644 --- a/pkg/configuration/core/config_query.go +++ b/pkg/configuration/core/config_query.go @@ -31,7 +31,7 @@ import ( // GetParameterFromConfiguration gets configure parameter // ctx: apiserver context // cli: apiserver client -// cluster: appsv1alpha1.Cluster +// cluster: appsv1.Cluster // component: component name func GetParameterFromConfiguration(configMap *corev1.ConfigMap, allFiles bool, fieldPath ...string) ([]string, error) { if configMap == nil || len(configMap.Data) == 0 { diff --git a/pkg/configuration/core/type_test.go b/pkg/configuration/core/type_test.go index 9f6e91a6b1f..6a84c588df5 100644 --- a/pkg/configuration/core/type_test.go +++ b/pkg/configuration/core/type_test.go @@ -26,7 +26,6 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" ) func TestGetInstanceName(t *testing.T) { @@ -36,7 +35,7 @@ func TestGetInstanceName(t *testing.T) { require.Equal(t, "mytest-envfrom", GenerateEnvFromName("mytest")) require.Equal(t, "mytest-mysql", GenerateComponentConfigurationName("mytest", "mysql")) require.Equal(t, "config.kubeblocks.io/revision-reconcile-phase-100", GenerateRevisionPhaseKey("100")) - require.Equal(t, "mycluster-mysql-config", GetInstanceCMName(&appsv1alpha1.Cluster{ + require.Equal(t, "mycluster-mysql-config", GetInstanceCMName(&appsv1.Cluster{ ObjectMeta: metav1.ObjectMeta{ Name: "mycluster", }}, diff --git a/pkg/controller/builder/builder_cluster.go b/pkg/controller/builder/builder_cluster.go index c73597dc80b..e820a1c7c01 100644 --- a/pkg/controller/builder/builder_cluster.go +++ b/pkg/controller/builder/builder_cluster.go @@ -20,20 +20,20 @@ along with this program. If not, see . package builder import ( - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" ) type ClusterBuilder struct { - BaseBuilder[appsv1alpha1.Cluster, *appsv1alpha1.Cluster, ClusterBuilder] + BaseBuilder[appsv1.Cluster, *appsv1.Cluster, ClusterBuilder] } func NewClusterBuilder(namespace, name string) *ClusterBuilder { builder := &ClusterBuilder{} - builder.init(namespace, name, &appsv1alpha1.Cluster{}, builder) + builder.init(namespace, name, &appsv1.Cluster{}, builder) return builder } -func (builder *ClusterBuilder) SetComponentSpecs(specs []appsv1alpha1.ClusterComponentSpec) *ClusterBuilder { +func (builder *ClusterBuilder) SetComponentSpecs(specs []appsv1.ClusterComponentSpec) *ClusterBuilder { builder.get().Spec.ComponentSpecs = specs return builder } diff --git a/pkg/controller/builder/builder_cluster_test.go b/pkg/controller/builder/builder_cluster_test.go index b41f6d70e7b..1ef9410b593 100644 --- a/pkg/controller/builder/builder_cluster_test.go +++ b/pkg/controller/builder/builder_cluster_test.go @@ -23,7 +23,7 @@ import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" ) var _ = Describe("cluster builder", func() { @@ -32,7 +32,7 @@ var _ = Describe("cluster builder", func() { name = "foo" ns = "default" ) - specs := []appsv1alpha1.ClusterComponentSpec{ + specs := []appsv1.ClusterComponentSpec{ { Name: "foo-0", }, diff --git a/pkg/controller/builder/builder_component.go b/pkg/controller/builder/builder_component.go index 8db54ff76e6..d5fa4cf7d1d 100644 --- a/pkg/controller/builder/builder_component.go +++ b/pkg/controller/builder/builder_component.go @@ -23,8 +23,6 @@ import ( appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/util/intstr" - - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" ) type ComponentBuilder struct { @@ -135,8 +133,8 @@ func (builder *ComponentBuilder) SetVolumes(volumes []corev1.Volume) *ComponentB return builder } -func (builder *ComponentBuilder) SetServices(services []appsv1alpha1.ClusterComponentService) *ComponentBuilder { - toCompService := func(svc appsv1alpha1.ClusterComponentService) appsv1.ComponentService { +func (builder *ComponentBuilder) SetServices(services []appsv1.ClusterComponentService) *ComponentBuilder { + toCompService := func(svc appsv1.ClusterComponentService) appsv1.ComponentService { return appsv1.ComponentService{ Service: appsv1.Service{ Name: svc.Name, diff --git a/pkg/controller/component/component.go b/pkg/controller/component/component.go index 6965cc9d44d..1e2b13d7b89 100644 --- a/pkg/controller/component/component.go +++ b/pkg/controller/component/component.go @@ -30,7 +30,6 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" "github.com/apecloud/kubeblocks/pkg/common" "github.com/apecloud/kubeblocks/pkg/constant" "github.com/apecloud/kubeblocks/pkg/controller/builder" @@ -64,7 +63,7 @@ func IsGenerated(comp *appsv1.Component) bool { } // BuildComponent builds a new Component object from cluster component spec and definition. -func BuildComponent(cluster *appsv1alpha1.Cluster, compSpec *appsv1alpha1.ClusterComponentSpec, +func BuildComponent(cluster *appsv1.Cluster, compSpec *appsv1.ClusterComponentSpec, labels, annotations map[string]string) (*appsv1.Component, error) { compName := FullName(cluster.Name, compSpec.Name) compDefName := func() string { @@ -122,8 +121,8 @@ func BuildComponent(cluster *appsv1alpha1.Cluster, compSpec *appsv1alpha1.Cluste } func getOrBuildComponentDefinition(ctx context.Context, cli client.Reader, - cluster *appsv1alpha1.Cluster, - clusterCompSpec *appsv1alpha1.ClusterComponentSpec) (*appsv1.ComponentDefinition, error) { + cluster *appsv1.Cluster, + clusterCompSpec *appsv1.ClusterComponentSpec) (*appsv1.ComponentDefinition, error) { if len(cluster.Spec.ClusterDefRef) > 0 && len(clusterCompSpec.ComponentDefRef) > 0 && len(clusterCompSpec.ComponentDef) == 0 { return nil, fmt.Errorf("legacy cluster component definition is not supported any more") } @@ -137,7 +136,7 @@ func getOrBuildComponentDefinition(ctx context.Context, cli client.Reader, return nil, fmt.Errorf("the component definition is not provided") } -func getClusterCompSpec4Component(ctx context.Context, cli client.Reader, cluster *appsv1alpha1.Cluster, comp *appsv1.Component) (*appsv1alpha1.ClusterComponentSpec, error) { +func getClusterCompSpec4Component(ctx context.Context, cli client.Reader, cluster *appsv1.Cluster, comp *appsv1.Component) (*appsv1.ClusterComponentSpec, error) { compName, err := ShortName(cluster.Name, comp.Name) if err != nil { return nil, err @@ -193,7 +192,7 @@ func GetCompNCompDefByName(ctx context.Context, cli client.Reader, namespace, fu } // ListClusterComponents lists the components of the cluster. -func ListClusterComponents(ctx context.Context, cli client.Reader, cluster *appsv1alpha1.Cluster) ([]appsv1.Component, error) { +func ListClusterComponents(ctx context.Context, cli client.Reader, cluster *appsv1.Cluster) ([]appsv1.Component, error) { compList := &appsv1.ComponentList{} if err := cli.List(ctx, compList, client.InNamespace(cluster.Namespace), client.MatchingLabels{constant.AppInstanceLabelKey: cluster.Name}); err != nil { return nil, err @@ -202,7 +201,7 @@ func ListClusterComponents(ctx context.Context, cli client.Reader, cluster *apps } // GetClusterComponentShortNameSet gets the component short name set of the cluster. -func GetClusterComponentShortNameSet(ctx context.Context, cli client.Reader, cluster *appsv1alpha1.Cluster) (sets.Set[string], error) { +func GetClusterComponentShortNameSet(ctx context.Context, cli client.Reader, cluster *appsv1.Cluster) (sets.Set[string], error) { compList, err := ListClusterComponents(ctx, cli, cluster) if err != nil { return nil, err diff --git a/pkg/controller/component/component_test.go b/pkg/controller/component/component_test.go index fbd33713681..6e4edb0473a 100644 --- a/pkg/controller/component/component_test.go +++ b/pkg/controller/component/component_test.go @@ -31,7 +31,6 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" intctrlutil "github.com/apecloud/kubeblocks/pkg/controllerutil" testapps "github.com/apecloud/kubeblocks/pkg/testutil/apps" ) @@ -47,7 +46,7 @@ var _ = Describe("Component", func() { var ( compDef *appsv1.ComponentDefinition - cluster *appsv1alpha1.Cluster + cluster *appsv1.Cluster ) BeforeEach(func() { diff --git a/pkg/controller/component/lifecycle/kbagent.go b/pkg/controller/component/lifecycle/kbagent.go index 5603fbb94f0..0204a2a650e 100644 --- a/pkg/controller/component/lifecycle/kbagent.go +++ b/pkg/controller/component/lifecycle/kbagent.go @@ -30,7 +30,6 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" "github.com/apecloud/kubeblocks/pkg/constant" "github.com/apecloud/kubeblocks/pkg/controller/component" @@ -170,10 +169,10 @@ func (a *kbagent) precondition(ctx context.Context, cli client.Reader, spec *app func (a *kbagent) clusterReadyCheck(ctx context.Context, cli client.Reader) error { ready := func(object client.Object) bool { - cluster := object.(*appsv1alpha1.Cluster) - return cluster.Status.Phase == appsv1alpha1.RunningClusterPhase + cluster := object.(*appsv1.Cluster) + return cluster.Status.Phase == appsv1.RunningClusterPhase } - return a.readyCheck(ctx, cli, a.synthesizedComp.ClusterName, "cluster", &appsv1alpha1.Cluster{}, ready) + return a.readyCheck(ctx, cli, a.synthesizedComp.ClusterName, "cluster", &appsv1.Cluster{}, ready) } func (a *kbagent) compReadyCheck(ctx context.Context, cli client.Reader) error { diff --git a/pkg/controller/component/lifecycle/lifecycle_test.go b/pkg/controller/component/lifecycle/lifecycle_test.go index 5b9e74142e4..7ad5323b33e 100644 --- a/pkg/controller/component/lifecycle/lifecycle_test.go +++ b/pkg/controller/component/lifecycle/lifecycle_test.go @@ -23,7 +23,6 @@ import ( "context" "errors" "fmt" - appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" "reflect" "strings" @@ -36,7 +35,7 @@ import ( "k8s.io/apimachinery/pkg/labels" "sigs.k8s.io/controller-runtime/pkg/client" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" "github.com/apecloud/kubeblocks/pkg/constant" "github.com/apecloud/kubeblocks/pkg/controller/component" kbacli "github.com/apecloud/kubeblocks/pkg/kbagent/client" @@ -363,7 +362,7 @@ var _ = Describe("lifecycle", func() { reader := &mockReader{ cli: k8sClient, objs: []client.Object{ - &appsv1alpha1.Component{ + &appsv1.Component{ ObjectMeta: metav1.ObjectMeta{ Namespace: synthesizedComp.Namespace, Name: constant.GenerateClusterComponentName(synthesizedComp.ClusterName, synthesizedComp.Name), @@ -372,7 +371,7 @@ var _ = Describe("lifecycle", func() { }, }, }, - &appsv1alpha1.Component{ + &appsv1.Component{ ObjectMeta: metav1.ObjectMeta{ Namespace: synthesizedComp.Namespace, Name: constant.GenerateClusterComponentName(synthesizedComp.ClusterName, "another"), @@ -433,13 +432,13 @@ var _ = Describe("lifecycle", func() { reader := &mockReader{ cli: k8sClient, objs: []client.Object{ - &appsv1alpha1.Cluster{ + &appsv1.Cluster{ ObjectMeta: metav1.ObjectMeta{ Namespace: synthesizedComp.Namespace, Name: synthesizedComp.ClusterName, }, - Status: appsv1alpha1.ClusterStatus{ - Phase: appsv1alpha1.RunningClusterPhase, + Status: appsv1.ClusterStatus{ + Phase: appsv1.RunningClusterPhase, }, }, }, @@ -466,13 +465,13 @@ var _ = Describe("lifecycle", func() { reader := &mockReader{ cli: k8sClient, objs: []client.Object{ - &appsv1alpha1.Cluster{ + &appsv1.Cluster{ ObjectMeta: metav1.ObjectMeta{ Namespace: synthesizedComp.Namespace, Name: synthesizedComp.ClusterName, }, - Status: appsv1alpha1.ClusterStatus{ - Phase: appsv1alpha1.FailedClusterPhase, + Status: appsv1.ClusterStatus{ + Phase: appsv1.FailedClusterPhase, }, }, }, diff --git a/pkg/controller/component/synthesize_component.go b/pkg/controller/component/synthesize_component.go index bff94fe5956..db00699cd94 100644 --- a/pkg/controller/component/synthesize_component.go +++ b/pkg/controller/component/synthesize_component.go @@ -32,7 +32,6 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" "github.com/apecloud/kubeblocks/pkg/constant" intctrlutil "github.com/apecloud/kubeblocks/pkg/controllerutil" viper "github.com/apecloud/kubeblocks/pkg/viperx" @@ -45,7 +44,7 @@ var ( // BuildSynthesizedComponent builds a new SynthesizedComponent object, which is a mixture of component-related configs from ComponentDefinition and Component. func BuildSynthesizedComponent(reqCtx intctrlutil.RequestCtx, cli client.Reader, - cluster *appsv1alpha1.Cluster, + cluster *appsv1.Cluster, compDef *appsv1.ComponentDefinition, comp *appsv1.Component) (*SynthesizedComponent, error) { return buildSynthesizedComponent(reqCtx, cli, compDef, comp, cluster, nil) @@ -54,7 +53,7 @@ func BuildSynthesizedComponent(reqCtx intctrlutil.RequestCtx, // BuildSynthesizedComponent4Generated builds SynthesizedComponent for generated Component which w/o ComponentDefinition. func BuildSynthesizedComponent4Generated(reqCtx intctrlutil.RequestCtx, cli client.Reader, - cluster *appsv1alpha1.Cluster, + cluster *appsv1.Cluster, comp *appsv1.Component) (*appsv1.ComponentDefinition, *SynthesizedComponent, error) { clusterCompSpec, err := getClusterCompSpec4Component(reqCtx.Ctx, cli, cluster, comp) if err != nil { @@ -78,8 +77,8 @@ func BuildSynthesizedComponent4Generated(reqCtx intctrlutil.RequestCtx, // TODO: remove this func BuildSynthesizedComponentWrapper(reqCtx intctrlutil.RequestCtx, cli client.Reader, - cluster *appsv1alpha1.Cluster, - clusterCompSpec *appsv1alpha1.ClusterComponentSpec) (*SynthesizedComponent, error) { + cluster *appsv1.Cluster, + clusterCompSpec *appsv1.ClusterComponentSpec) (*SynthesizedComponent, error) { if clusterCompSpec == nil { return nil, fmt.Errorf("cluster component spec is not provided") } @@ -101,8 +100,8 @@ func buildSynthesizedComponent(reqCtx intctrlutil.RequestCtx, cli client.Reader, compDef *appsv1.ComponentDefinition, comp *appsv1.Component, - cluster *appsv1alpha1.Cluster, - clusterCompSpec *appsv1alpha1.ClusterComponentSpec) (*SynthesizedComponent, error) { + cluster *appsv1.Cluster, + clusterCompSpec *appsv1.ClusterComponentSpec) (*SynthesizedComponent, error) { if compDef == nil || comp == nil { return nil, nil } @@ -212,7 +211,7 @@ func buildSynthesizedComponent(reqCtx intctrlutil.RequestCtx, return synthesizeComp, nil } -func clusterGeneration(cluster *appsv1alpha1.Cluster, comp *appsv1.Component) string { +func clusterGeneration(cluster *appsv1.Cluster, comp *appsv1.Component) string { if comp != nil && comp.Annotations != nil { if generation, ok := comp.Annotations[constant.KubeBlocksGenerationKey]; ok { return generation @@ -222,7 +221,7 @@ func clusterGeneration(cluster *appsv1alpha1.Cluster, comp *appsv1.Component) st return strconv.FormatInt(cluster.Generation, 10) } -func buildComp2CompDefs(ctx context.Context, cli client.Reader, cluster *appsv1alpha1.Cluster, clusterCompSpec *appsv1alpha1.ClusterComponentSpec) (map[string]string, error) { +func buildComp2CompDefs(ctx context.Context, cli client.Reader, cluster *appsv1.Cluster, clusterCompSpec *appsv1.ClusterComponentSpec) (map[string]string, error) { if cluster == nil { return nil, nil } diff --git a/pkg/controller/component/vars_test.go b/pkg/controller/component/vars_test.go index 66468f3f8b1..9469c82c89e 100644 --- a/pkg/controller/component/vars_test.go +++ b/pkg/controller/component/vars_test.go @@ -34,7 +34,6 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" "github.com/apecloud/kubeblocks/pkg/constant" ) @@ -221,10 +220,10 @@ var _ = Describe("vars", func() { It("configmap vars", func() { By("non-exist configmap with optional") - vars := []appsv1alpha1.EnvVar{ + vars := []appsv1.EnvVar{ { Name: "non-exist-cm-var", - ValueFrom: &appsv1alpha1.VarSource{ + ValueFrom: &appsv1.VarSource{ ConfigMapKeyRef: &corev1.ConfigMapKeySelector{ LocalObjectReference: corev1.LocalObjectReference{ Name: "non-exist", @@ -241,10 +240,10 @@ var _ = Describe("vars", func() { checkEnvVarNotExist(envVars, "non-exist-cm-var") By("non-exist configmap with required") - vars = []appsv1alpha1.EnvVar{ + vars = []appsv1.EnvVar{ { Name: "non-exist-cm-var", - ValueFrom: &appsv1alpha1.VarSource{ + ValueFrom: &appsv1.VarSource{ ConfigMapKeyRef: &corev1.ConfigMapKeySelector{ LocalObjectReference: corev1.LocalObjectReference{ Name: "non-exist", @@ -259,10 +258,10 @@ var _ = Describe("vars", func() { Expect(err).ShouldNot(Succeed()) By("ok") - vars = []appsv1alpha1.EnvVar{ + vars = []appsv1.EnvVar{ { Name: "cm-var", - ValueFrom: &appsv1alpha1.VarSource{ + ValueFrom: &appsv1.VarSource{ ConfigMapKeyRef: &corev1.ConfigMapKeySelector{ LocalObjectReference: corev1.LocalObjectReference{ Name: "cm", @@ -294,10 +293,10 @@ var _ = Describe("vars", func() { It("secret vars", func() { By("non-exist secret with optional") - vars := []appsv1alpha1.EnvVar{ + vars := []appsv1.EnvVar{ { Name: "non-exist-secret-var", - ValueFrom: &appsv1alpha1.VarSource{ + ValueFrom: &appsv1.VarSource{ SecretKeyRef: &corev1.SecretKeySelector{ LocalObjectReference: corev1.LocalObjectReference{ Name: "non-exist", @@ -314,10 +313,10 @@ var _ = Describe("vars", func() { checkEnvVarNotExist(envVars, "non-exist-secret-var") By("non-exist secret with required") - vars = []appsv1alpha1.EnvVar{ + vars = []appsv1.EnvVar{ { Name: "non-exist-secret-var", - ValueFrom: &appsv1alpha1.VarSource{ + ValueFrom: &appsv1.VarSource{ SecretKeyRef: &corev1.SecretKeySelector{ LocalObjectReference: corev1.LocalObjectReference{ Name: "non-exist", @@ -332,10 +331,10 @@ var _ = Describe("vars", func() { Expect(err).ShouldNot(Succeed()) By("ok") - vars = []appsv1alpha1.EnvVar{ + vars = []appsv1.EnvVar{ { Name: "secret-var", - ValueFrom: &appsv1alpha1.VarSource{ + ValueFrom: &appsv1.VarSource{ SecretKeyRef: &corev1.SecretKeySelector{ LocalObjectReference: corev1.LocalObjectReference{ Name: "secret", @@ -373,21 +372,21 @@ var _ = Describe("vars", func() { }) It("host-network vars", func() { - vars := []appsv1alpha1.EnvVar{ + vars := []appsv1.EnvVar{ { Name: "host-network-port", Value: "3306", // default value - ValueFrom: &appsv1alpha1.VarSource{ - HostNetworkVarRef: &appsv1alpha1.HostNetworkVarSelector{ - ClusterObjectReference: appsv1alpha1.ClusterObjectReference{ + ValueFrom: &appsv1.VarSource{ + HostNetworkVarRef: &appsv1.HostNetworkVarSelector{ + ClusterObjectReference: appsv1.ClusterObjectReference{ Optional: required(), }, - HostNetworkVars: appsv1alpha1.HostNetworkVars{ - Container: &appsv1alpha1.ContainerVars{ + HostNetworkVars: appsv1.HostNetworkVars{ + Container: &appsv1.ContainerVars{ Name: "default", - Port: &appsv1alpha1.NamedVar{ + Port: &appsv1.NamedVar{ Name: "default", - Option: &appsv1alpha1.VarRequired, + Option: &appsv1.VarRequired, }, }, }, @@ -424,21 +423,21 @@ var _ = Describe("vars", func() { checkEnvVarWithValue(envVars, "host-network-port", "30001") By("w/ default value - has host-network port") - vars = []appsv1alpha1.EnvVar{ + vars = []appsv1.EnvVar{ { Name: "host-network-port", Value: "3306", // default value - ValueFrom: &appsv1alpha1.VarSource{ - HostNetworkVarRef: &appsv1alpha1.HostNetworkVarSelector{ - ClusterObjectReference: appsv1alpha1.ClusterObjectReference{ + ValueFrom: &appsv1.VarSource{ + HostNetworkVarRef: &appsv1.HostNetworkVarSelector{ + ClusterObjectReference: appsv1.ClusterObjectReference{ Optional: optional(), // optional }, - HostNetworkVars: appsv1alpha1.HostNetworkVars{ - Container: &appsv1alpha1.ContainerVars{ + HostNetworkVars: appsv1.HostNetworkVars{ + Container: &appsv1.ContainerVars{ Name: "default", - Port: &appsv1alpha1.NamedVar{ + Port: &appsv1.NamedVar{ Name: "default", - Option: &appsv1alpha1.VarRequired, + Option: &appsv1.VarRequired, }, }, }, @@ -542,17 +541,17 @@ var _ = Describe("vars", func() { It("has no service defined", func() { By("optional") - vars := []appsv1alpha1.EnvVar{ + vars := []appsv1.EnvVar{ { Name: "not-defined-service", - ValueFrom: &appsv1alpha1.VarSource{ - ServiceVarRef: &appsv1alpha1.ServiceVarSelector{ - ClusterObjectReference: appsv1alpha1.ClusterObjectReference{ + ValueFrom: &appsv1.VarSource{ + ServiceVarRef: &appsv1.ServiceVarSelector{ + ClusterObjectReference: appsv1.ClusterObjectReference{ Name: "not-defined", // the service has not been defined in the componentDefinition Optional: optional(), }, - ServiceVars: appsv1alpha1.ServiceVars{ - Host: &appsv1alpha1.VarRequired, + ServiceVars: appsv1.ServiceVars{ + Host: &appsv1.VarRequired, }, }, }, @@ -563,17 +562,17 @@ var _ = Describe("vars", func() { Expect(err.Error()).Should(ContainSubstring("not defined in the component definition")) By("required") - vars = []appsv1alpha1.EnvVar{ + vars = []appsv1.EnvVar{ { Name: "not-defined-service", - ValueFrom: &appsv1alpha1.VarSource{ - ServiceVarRef: &appsv1alpha1.ServiceVarSelector{ - ClusterObjectReference: appsv1alpha1.ClusterObjectReference{ + ValueFrom: &appsv1.VarSource{ + ServiceVarRef: &appsv1.ServiceVarSelector{ + ClusterObjectReference: appsv1.ClusterObjectReference{ Name: "not-defined", // the service has not been defined in the componentDefinition Optional: required(), }, - ServiceVars: appsv1alpha1.ServiceVars{ - Host: &appsv1alpha1.VarRequired, + ServiceVars: appsv1.ServiceVars{ + Host: &appsv1.VarRequired, }, }, }, @@ -588,47 +587,47 @@ var _ = Describe("vars", func() { svcName := constant.GenerateComponentServiceName(synthesizedComp.ClusterName, synthesizedComp.Name, "service") svcPort := 3306 - vars := []appsv1alpha1.EnvVar{ + vars := []appsv1.EnvVar{ { Name: "service-type", - ValueFrom: &appsv1alpha1.VarSource{ - ServiceVarRef: &appsv1alpha1.ServiceVarSelector{ - ClusterObjectReference: appsv1alpha1.ClusterObjectReference{ + ValueFrom: &appsv1.VarSource{ + ServiceVarRef: &appsv1.ServiceVarSelector{ + ClusterObjectReference: appsv1.ClusterObjectReference{ Name: "service", Optional: required(), }, - ServiceVars: appsv1alpha1.ServiceVars{ - ServiceType: &appsv1alpha1.VarRequired, + ServiceVars: appsv1.ServiceVars{ + ServiceType: &appsv1.VarRequired, }, }, }, }, { Name: "service-host", - ValueFrom: &appsv1alpha1.VarSource{ - ServiceVarRef: &appsv1alpha1.ServiceVarSelector{ - ClusterObjectReference: appsv1alpha1.ClusterObjectReference{ + ValueFrom: &appsv1.VarSource{ + ServiceVarRef: &appsv1.ServiceVarSelector{ + ClusterObjectReference: appsv1.ClusterObjectReference{ Name: "service", Optional: required(), }, - ServiceVars: appsv1alpha1.ServiceVars{ - Host: &appsv1alpha1.VarRequired, + ServiceVars: appsv1.ServiceVars{ + Host: &appsv1.VarRequired, }, }, }, }, { Name: "service-port", - ValueFrom: &appsv1alpha1.VarSource{ - ServiceVarRef: &appsv1alpha1.ServiceVarSelector{ - ClusterObjectReference: appsv1alpha1.ClusterObjectReference{ + ValueFrom: &appsv1.VarSource{ + ServiceVarRef: &appsv1.ServiceVarSelector{ + ClusterObjectReference: appsv1.ClusterObjectReference{ Name: "service", Optional: required(), }, - ServiceVars: appsv1alpha1.ServiceVars{ - Port: &appsv1alpha1.NamedVar{ + ServiceVars: appsv1.ServiceVars{ + Port: &appsv1.NamedVar{ Name: "default", - Option: &appsv1alpha1.VarRequired, + Option: &appsv1.VarRequired, }, }, }, @@ -636,16 +635,16 @@ var _ = Describe("vars", func() { }, { Name: "service-port-wo-name", - ValueFrom: &appsv1alpha1.VarSource{ - ServiceVarRef: &appsv1alpha1.ServiceVarSelector{ - ClusterObjectReference: appsv1alpha1.ClusterObjectReference{ + ValueFrom: &appsv1.VarSource{ + ServiceVarRef: &appsv1.ServiceVarSelector{ + ClusterObjectReference: appsv1.ClusterObjectReference{ Name: "service-wo-port-name", Optional: required(), }, - ServiceVars: appsv1alpha1.ServiceVars{ - Port: &appsv1alpha1.NamedVar{ + ServiceVars: appsv1.ServiceVars{ + Port: &appsv1.NamedVar{ Name: "default", - Option: &appsv1alpha1.VarRequired, + Option: &appsv1.VarRequired, }, }, }, @@ -747,19 +746,19 @@ var _ = Describe("vars", func() { svcPort := 3306 nodePort := 30001 - vars := []appsv1alpha1.EnvVar{ + vars := []appsv1.EnvVar{ { Name: "service-node-port", - ValueFrom: &appsv1alpha1.VarSource{ - ServiceVarRef: &appsv1alpha1.ServiceVarSelector{ - ClusterObjectReference: appsv1alpha1.ClusterObjectReference{ + ValueFrom: &appsv1.VarSource{ + ServiceVarRef: &appsv1.ServiceVarSelector{ + ClusterObjectReference: appsv1.ClusterObjectReference{ Name: "service", Optional: required(), }, - ServiceVars: appsv1alpha1.ServiceVars{ - Port: &appsv1alpha1.NamedVar{ + ServiceVars: appsv1.ServiceVars{ + Port: &appsv1.NamedVar{ Name: "default", - Option: &appsv1alpha1.VarRequired, + Option: &appsv1.VarRequired, }, }, }, @@ -793,19 +792,19 @@ var _ = Describe("vars", func() { svcPort := 3306 nodePort := 30001 - vars := []appsv1alpha1.EnvVar{ + vars := []appsv1.EnvVar{ { Name: "service-node-port", - ValueFrom: &appsv1alpha1.VarSource{ - ServiceVarRef: &appsv1alpha1.ServiceVarSelector{ - ClusterObjectReference: appsv1alpha1.ClusterObjectReference{ + ValueFrom: &appsv1.VarSource{ + ServiceVarRef: &appsv1.ServiceVarSelector{ + ClusterObjectReference: appsv1.ClusterObjectReference{ Name: "service", Optional: required(), }, - ServiceVars: appsv1alpha1.ServiceVars{ - Port: &appsv1alpha1.NamedVar{ + ServiceVars: appsv1.ServiceVars{ + Port: &appsv1.NamedVar{ Name: "default", - Option: &appsv1alpha1.VarRequired, + Option: &appsv1.VarRequired, }, }, }, @@ -846,47 +845,47 @@ var _ = Describe("vars", func() { svcName1 := constant.GenerateComponentServiceName(synthesizedComp.ClusterName, synthesizedComp.Name, "pod-service-1") svcPort := 3306 - vars := []appsv1alpha1.EnvVar{ + vars := []appsv1.EnvVar{ { Name: "pod-service-type", - ValueFrom: &appsv1alpha1.VarSource{ - ServiceVarRef: &appsv1alpha1.ServiceVarSelector{ - ClusterObjectReference: appsv1alpha1.ClusterObjectReference{ + ValueFrom: &appsv1.VarSource{ + ServiceVarRef: &appsv1.ServiceVarSelector{ + ClusterObjectReference: appsv1.ClusterObjectReference{ Name: "pod-service", Optional: required(), }, - ServiceVars: appsv1alpha1.ServiceVars{ - ServiceType: &appsv1alpha1.VarRequired, + ServiceVars: appsv1.ServiceVars{ + ServiceType: &appsv1.VarRequired, }, }, }, }, { Name: "pod-service-endpoint", - ValueFrom: &appsv1alpha1.VarSource{ - ServiceVarRef: &appsv1alpha1.ServiceVarSelector{ - ClusterObjectReference: appsv1alpha1.ClusterObjectReference{ + ValueFrom: &appsv1.VarSource{ + ServiceVarRef: &appsv1.ServiceVarSelector{ + ClusterObjectReference: appsv1.ClusterObjectReference{ Name: "pod-service", Optional: required(), }, - ServiceVars: appsv1alpha1.ServiceVars{ - Host: &appsv1alpha1.VarRequired, + ServiceVars: appsv1.ServiceVars{ + Host: &appsv1.VarRequired, }, }, }, }, { Name: "pod-service-port", - ValueFrom: &appsv1alpha1.VarSource{ - ServiceVarRef: &appsv1alpha1.ServiceVarSelector{ - ClusterObjectReference: appsv1alpha1.ClusterObjectReference{ + ValueFrom: &appsv1.VarSource{ + ServiceVarRef: &appsv1.ServiceVarSelector{ + ClusterObjectReference: appsv1.ClusterObjectReference{ Name: "pod-service", Optional: required(), }, - ServiceVars: appsv1alpha1.ServiceVars{ - Port: &appsv1alpha1.NamedVar{ + ServiceVars: appsv1.ServiceVars{ + Port: &appsv1.NamedVar{ Name: "default", - Option: &appsv1alpha1.VarRequired, + Option: &appsv1.VarRequired, }, }, }, @@ -940,17 +939,17 @@ var _ = Describe("vars", func() { lbSvcName := constant.GenerateComponentServiceName(synthesizedComp.ClusterName, synthesizedComp.Name, "lb") svcPort := 3306 - vars := []appsv1alpha1.EnvVar{ + vars := []appsv1.EnvVar{ { Name: "lb", - ValueFrom: &appsv1alpha1.VarSource{ - ServiceVarRef: &appsv1alpha1.ServiceVarSelector{ - ClusterObjectReference: appsv1alpha1.ClusterObjectReference{ + ValueFrom: &appsv1.VarSource{ + ServiceVarRef: &appsv1.ServiceVarSelector{ + ClusterObjectReference: appsv1.ClusterObjectReference{ Name: "lb", Optional: required(), }, - ServiceVars: appsv1alpha1.ServiceVars{ - LoadBalancer: &appsv1alpha1.VarRequired, + ServiceVars: appsv1.ServiceVars{ + LoadBalancer: &appsv1.VarRequired, }, }, }, @@ -992,17 +991,17 @@ var _ = Describe("vars", func() { lbSvcName2 := constant.GenerateComponentServiceName(synthesizedComp.ClusterName, synthesizedComp.Name, "lb-2") svcPort := 3306 - vars := []appsv1alpha1.EnvVar{ + vars := []appsv1.EnvVar{ { Name: "lb", - ValueFrom: &appsv1alpha1.VarSource{ - ServiceVarRef: &appsv1alpha1.ServiceVarSelector{ - ClusterObjectReference: appsv1alpha1.ClusterObjectReference{ + ValueFrom: &appsv1.VarSource{ + ServiceVarRef: &appsv1.ServiceVarSelector{ + ClusterObjectReference: appsv1.ClusterObjectReference{ Name: "lb", Optional: required(), }, - ServiceVars: appsv1alpha1.ServiceVars{ - LoadBalancer: &appsv1alpha1.VarRequired, + ServiceVars: appsv1.ServiceVars{ + LoadBalancer: &appsv1.VarRequired, }, }, }, @@ -1103,17 +1102,17 @@ var _ = Describe("vars", func() { lbSvcName1 := constant.GenerateComponentServiceName(synthesizedComp.ClusterName, synthesizedComp.Name, "lb-1") svcPort := 3306 - vars := []appsv1alpha1.EnvVar{ + vars := []appsv1.EnvVar{ { Name: "lb", - ValueFrom: &appsv1alpha1.VarSource{ - ServiceVarRef: &appsv1alpha1.ServiceVarSelector{ - ClusterObjectReference: appsv1alpha1.ClusterObjectReference{ + ValueFrom: &appsv1.VarSource{ + ServiceVarRef: &appsv1.ServiceVarSelector{ + ClusterObjectReference: appsv1.ClusterObjectReference{ Name: "lb", Optional: required(), }, - ServiceVars: appsv1alpha1.ServiceVars{ - LoadBalancer: &appsv1alpha1.VarRequired, + ServiceVars: appsv1.ServiceVars{ + LoadBalancer: &appsv1.VarRequired, }, }, }, @@ -1172,18 +1171,18 @@ var _ = Describe("vars", func() { advertisedSvcName := constant.GenerateComponentServiceName(synthesizedComp.ClusterName, synthesizedComp.Name, "advertised-0") svcPort := 3306 - vars := []appsv1alpha1.EnvVar{ + vars := []appsv1.EnvVar{ { Name: "advertised", - ValueFrom: &appsv1alpha1.VarSource{ - ServiceVarRef: &appsv1alpha1.ServiceVarSelector{ - ClusterObjectReference: appsv1alpha1.ClusterObjectReference{ + ValueFrom: &appsv1.VarSource{ + ServiceVarRef: &appsv1.ServiceVarSelector{ + ClusterObjectReference: appsv1.ClusterObjectReference{ Name: "advertised", Optional: required(), }, - ServiceVars: appsv1alpha1.ServiceVars{ - Host: &appsv1alpha1.VarRequired, // both host and loadBalancer - LoadBalancer: &appsv1alpha1.VarRequired, + ServiceVars: appsv1.ServiceVars{ + Host: &appsv1.VarRequired, // both host and loadBalancer + LoadBalancer: &appsv1.VarRequired, }, }, }, @@ -1226,18 +1225,18 @@ var _ = Describe("vars", func() { advertisedSvcName := constant.GenerateComponentServiceName(synthesizedComp.ClusterName, synthesizedComp.Name, "advertised-0") svcPort := 3306 - vars := []appsv1alpha1.EnvVar{ + vars := []appsv1.EnvVar{ { Name: "advertised", - ValueFrom: &appsv1alpha1.VarSource{ - ServiceVarRef: &appsv1alpha1.ServiceVarSelector{ - ClusterObjectReference: appsv1alpha1.ClusterObjectReference{ + ValueFrom: &appsv1.VarSource{ + ServiceVarRef: &appsv1.ServiceVarSelector{ + ClusterObjectReference: appsv1.ClusterObjectReference{ Name: "advertised", Optional: required(), }, - ServiceVars: appsv1alpha1.ServiceVars{ - Host: &appsv1alpha1.VarRequired, // both host and loadBalancer - LoadBalancer: &appsv1alpha1.VarRequired, + ServiceVars: appsv1.ServiceVars{ + Host: &appsv1.VarRequired, // both host and loadBalancer + LoadBalancer: &appsv1.VarRequired, }, }, }, @@ -1269,18 +1268,18 @@ var _ = Describe("vars", func() { advertisedSvcName := constant.GenerateComponentServiceName(synthesizedComp.ClusterName, synthesizedComp.Name, "advertised") svcPort := 3306 - vars := []appsv1alpha1.EnvVar{ + vars := []appsv1.EnvVar{ { Name: "advertised", - ValueFrom: &appsv1alpha1.VarSource{ - ServiceVarRef: &appsv1alpha1.ServiceVarSelector{ - ClusterObjectReference: appsv1alpha1.ClusterObjectReference{ + ValueFrom: &appsv1.VarSource{ + ServiceVarRef: &appsv1.ServiceVarSelector{ + ClusterObjectReference: appsv1.ClusterObjectReference{ Name: "advertised", Optional: required(), }, - ServiceVars: appsv1alpha1.ServiceVars{ - Host: &appsv1alpha1.VarRequired, // both host and loadBalancer - LoadBalancer: &appsv1alpha1.VarRequired, + ServiceVars: appsv1.ServiceVars{ + Host: &appsv1.VarRequired, // both host and loadBalancer + LoadBalancer: &appsv1.VarRequired, }, }, }, @@ -1340,17 +1339,17 @@ var _ = Describe("vars", func() { Context("credential vars", func() { It("non-exist credential with optional", func() { - vars := []appsv1alpha1.EnvVar{ + vars := []appsv1.EnvVar{ { Name: "non-exist-credential-var", - ValueFrom: &appsv1alpha1.VarSource{ - CredentialVarRef: &appsv1alpha1.CredentialVarSelector{ - ClusterObjectReference: appsv1alpha1.ClusterObjectReference{ + ValueFrom: &appsv1.VarSource{ + CredentialVarRef: &appsv1.CredentialVarSelector{ + ClusterObjectReference: appsv1.ClusterObjectReference{ Name: "non-exist", Optional: optional(), }, - CredentialVars: appsv1alpha1.CredentialVars{ - Username: &appsv1alpha1.VarOptional, + CredentialVars: appsv1.CredentialVars{ + Username: &appsv1.VarOptional, }, }, }, @@ -1363,17 +1362,17 @@ var _ = Describe("vars", func() { }) It("non-exist credential with required", func() { - vars := []appsv1alpha1.EnvVar{ + vars := []appsv1.EnvVar{ { Name: "non-exist-credential-var", - ValueFrom: &appsv1alpha1.VarSource{ - CredentialVarRef: &appsv1alpha1.CredentialVarSelector{ - ClusterObjectReference: appsv1alpha1.ClusterObjectReference{ + ValueFrom: &appsv1.VarSource{ + CredentialVarRef: &appsv1.CredentialVarSelector{ + ClusterObjectReference: appsv1.ClusterObjectReference{ Name: "non-exist", Optional: required(), }, - CredentialVars: appsv1alpha1.CredentialVars{ - Username: &appsv1alpha1.VarRequired, + CredentialVars: appsv1.CredentialVars{ + Username: &appsv1.VarRequired, }, }, }, @@ -1384,31 +1383,31 @@ var _ = Describe("vars", func() { }) It("ok", func() { - vars := []appsv1alpha1.EnvVar{ + vars := []appsv1.EnvVar{ { Name: "credential-username", - ValueFrom: &appsv1alpha1.VarSource{ - CredentialVarRef: &appsv1alpha1.CredentialVarSelector{ - ClusterObjectReference: appsv1alpha1.ClusterObjectReference{ + ValueFrom: &appsv1.VarSource{ + CredentialVarRef: &appsv1.CredentialVarSelector{ + ClusterObjectReference: appsv1.ClusterObjectReference{ Name: "credential", Optional: required(), }, - CredentialVars: appsv1alpha1.CredentialVars{ - Username: &appsv1alpha1.VarRequired, + CredentialVars: appsv1.CredentialVars{ + Username: &appsv1.VarRequired, }, }, }, }, { Name: "credential-password", - ValueFrom: &appsv1alpha1.VarSource{ - CredentialVarRef: &appsv1alpha1.CredentialVarSelector{ - ClusterObjectReference: appsv1alpha1.ClusterObjectReference{ + ValueFrom: &appsv1.VarSource{ + CredentialVarRef: &appsv1.CredentialVarSelector{ + ClusterObjectReference: appsv1.ClusterObjectReference{ Name: "credential", Optional: required(), }, - CredentialVars: appsv1alpha1.CredentialVars{ - Password: &appsv1alpha1.VarRequired, + CredentialVars: appsv1.CredentialVars{ + Password: &appsv1.VarRequired, }, }, }, @@ -1454,17 +1453,17 @@ var _ = Describe("vars", func() { Context("service-ref vars", func() { It("non-exist service-ref with optional", func() { - vars := []appsv1alpha1.EnvVar{ + vars := []appsv1.EnvVar{ { Name: "non-exist-serviceref-var", - ValueFrom: &appsv1alpha1.VarSource{ - ServiceRefVarRef: &appsv1alpha1.ServiceRefVarSelector{ - ClusterObjectReference: appsv1alpha1.ClusterObjectReference{ + ValueFrom: &appsv1.VarSource{ + ServiceRefVarRef: &appsv1.ServiceRefVarSelector{ + ClusterObjectReference: appsv1.ClusterObjectReference{ Name: "non-exist", Optional: optional(), }, - ServiceRefVars: appsv1alpha1.ServiceRefVars{ - Endpoint: &appsv1alpha1.VarOptional, + ServiceRefVars: appsv1.ServiceRefVars{ + Endpoint: &appsv1.VarOptional, }, }, }, @@ -1477,17 +1476,17 @@ var _ = Describe("vars", func() { }) It("non-exist service-ref with required", func() { - vars := []appsv1alpha1.EnvVar{ + vars := []appsv1.EnvVar{ { Name: "non-exist-serviceref-var", - ValueFrom: &appsv1alpha1.VarSource{ - ServiceRefVarRef: &appsv1alpha1.ServiceRefVarSelector{ - ClusterObjectReference: appsv1alpha1.ClusterObjectReference{ + ValueFrom: &appsv1.VarSource{ + ServiceRefVarRef: &appsv1.ServiceRefVarSelector{ + ClusterObjectReference: appsv1.ClusterObjectReference{ Name: "non-exist", Optional: required(), }, - ServiceRefVars: appsv1alpha1.ServiceRefVars{ - Endpoint: &appsv1alpha1.VarRequired, + ServiceRefVars: appsv1.ServiceRefVars{ + Endpoint: &appsv1.VarRequired, }, }, }, @@ -1498,60 +1497,60 @@ var _ = Describe("vars", func() { }) It("ok", func() { - vars := []appsv1alpha1.EnvVar{ + vars := []appsv1.EnvVar{ { Name: "serviceref-endpoint", - ValueFrom: &appsv1alpha1.VarSource{ - ServiceRefVarRef: &appsv1alpha1.ServiceRefVarSelector{ - ClusterObjectReference: appsv1alpha1.ClusterObjectReference{ + ValueFrom: &appsv1.VarSource{ + ServiceRefVarRef: &appsv1.ServiceRefVarSelector{ + ClusterObjectReference: appsv1.ClusterObjectReference{ Name: "serviceref", Optional: required(), }, - ServiceRefVars: appsv1alpha1.ServiceRefVars{ - Endpoint: &appsv1alpha1.VarRequired, + ServiceRefVars: appsv1.ServiceRefVars{ + Endpoint: &appsv1.VarRequired, }, }, }, }, { Name: "serviceref-host", - ValueFrom: &appsv1alpha1.VarSource{ - ServiceRefVarRef: &appsv1alpha1.ServiceRefVarSelector{ - ClusterObjectReference: appsv1alpha1.ClusterObjectReference{ + ValueFrom: &appsv1.VarSource{ + ServiceRefVarRef: &appsv1.ServiceRefVarSelector{ + ClusterObjectReference: appsv1.ClusterObjectReference{ Name: "serviceref", Optional: required(), }, - ServiceRefVars: appsv1alpha1.ServiceRefVars{ - Host: &appsv1alpha1.VarRequired, + ServiceRefVars: appsv1.ServiceRefVars{ + Host: &appsv1.VarRequired, }, }, }, }, { Name: "serviceref-port", - ValueFrom: &appsv1alpha1.VarSource{ - ServiceRefVarRef: &appsv1alpha1.ServiceRefVarSelector{ - ClusterObjectReference: appsv1alpha1.ClusterObjectReference{ + ValueFrom: &appsv1.VarSource{ + ServiceRefVarRef: &appsv1.ServiceRefVarSelector{ + ClusterObjectReference: appsv1.ClusterObjectReference{ Name: "serviceref", Optional: required(), }, - ServiceRefVars: appsv1alpha1.ServiceRefVars{ - Port: &appsv1alpha1.VarRequired, + ServiceRefVars: appsv1.ServiceRefVars{ + Port: &appsv1.VarRequired, }, }, }, }, { Name: "serviceref-username", - ValueFrom: &appsv1alpha1.VarSource{ - ServiceRefVarRef: &appsv1alpha1.ServiceRefVarSelector{ - ClusterObjectReference: appsv1alpha1.ClusterObjectReference{ + ValueFrom: &appsv1.VarSource{ + ServiceRefVarRef: &appsv1.ServiceRefVarSelector{ + ClusterObjectReference: appsv1.ClusterObjectReference{ Name: "serviceref", Optional: required(), }, - ServiceRefVars: appsv1alpha1.ServiceRefVars{ - CredentialVars: appsv1alpha1.CredentialVars{ - Username: &appsv1alpha1.VarRequired, + ServiceRefVars: appsv1.ServiceRefVars{ + CredentialVars: appsv1.CredentialVars{ + Username: &appsv1.VarRequired, }, }, }, @@ -1559,15 +1558,15 @@ var _ = Describe("vars", func() { }, { Name: "serviceref-password", - ValueFrom: &appsv1alpha1.VarSource{ - ServiceRefVarRef: &appsv1alpha1.ServiceRefVarSelector{ - ClusterObjectReference: appsv1alpha1.ClusterObjectReference{ + ValueFrom: &appsv1.VarSource{ + ServiceRefVarRef: &appsv1.ServiceRefVarSelector{ + ClusterObjectReference: appsv1.ClusterObjectReference{ Name: "serviceref", Optional: required(), }, - ServiceRefVars: appsv1alpha1.ServiceRefVars{ - CredentialVars: appsv1alpha1.CredentialVars{ - Password: &appsv1alpha1.VarRequired, + ServiceRefVars: appsv1.ServiceRefVars{ + CredentialVars: appsv1.CredentialVars{ + Password: &appsv1.VarRequired, }, }, }, @@ -1737,16 +1736,16 @@ var _ = Describe("vars", func() { }, { Name: "podNames4EmptyRole", - ValueFrom: &appsv1alpha1.VarSource{ - ComponentVarRef: &appsv1alpha1.ComponentVarSelector{ - ClusterObjectReference: appsv1alpha1.ClusterObjectReference{ + ValueFrom: &appsv1.VarSource{ + ComponentVarRef: &appsv1.ComponentVarSelector{ + ClusterObjectReference: appsv1.ClusterObjectReference{ CompDef: synthesizedComp.CompDefName, Optional: required(), }, - ComponentVars: appsv1alpha1.ComponentVars{ - PodNamesForRole: &appsv1alpha1.RoledVar{ + ComponentVars: appsv1.ComponentVars{ + PodNamesForRole: &appsv1.RoledVar{ // empty role - Option: &appsv1alpha1.VarRequired, + Option: &appsv1.VarRequired, }, }, }, @@ -1754,16 +1753,16 @@ var _ = Describe("vars", func() { }, { Name: "podFQDNs4Leader", - ValueFrom: &appsv1alpha1.VarSource{ - ComponentVarRef: &appsv1alpha1.ComponentVarSelector{ - ClusterObjectReference: appsv1alpha1.ClusterObjectReference{ + ValueFrom: &appsv1.VarSource{ + ComponentVarRef: &appsv1.ComponentVarSelector{ + ClusterObjectReference: appsv1.ClusterObjectReference{ CompDef: synthesizedComp.CompDefName, Optional: required(), }, - ComponentVars: appsv1alpha1.ComponentVars{ - PodFQDNsForRole: &appsv1alpha1.RoledVar{ + ComponentVars: appsv1.ComponentVars{ + PodFQDNsForRole: &appsv1.RoledVar{ Role: "leader", - Option: &appsv1alpha1.VarRequired, + Option: &appsv1.VarRequired, }, }, }, @@ -1854,33 +1853,33 @@ var _ = Describe("vars", func() { Context("cluster vars", func() { It("ok", func() { - vars := []appsv1alpha1.EnvVar{ + vars := []appsv1.EnvVar{ { Name: "namespace", - ValueFrom: &appsv1alpha1.VarSource{ - ClusterVarRef: &appsv1alpha1.ClusterVarSelector{ - ClusterVars: appsv1alpha1.ClusterVars{ - Namespace: &appsv1alpha1.VarRequired, + ValueFrom: &appsv1.VarSource{ + ClusterVarRef: &appsv1.ClusterVarSelector{ + ClusterVars: appsv1.ClusterVars{ + Namespace: &appsv1.VarRequired, }, }, }, }, { Name: "name", - ValueFrom: &appsv1alpha1.VarSource{ - ClusterVarRef: &appsv1alpha1.ClusterVarSelector{ - ClusterVars: appsv1alpha1.ClusterVars{ - ClusterName: &appsv1alpha1.VarRequired, + ValueFrom: &appsv1.VarSource{ + ClusterVarRef: &appsv1.ClusterVarSelector{ + ClusterVars: appsv1.ClusterVars{ + ClusterName: &appsv1.VarRequired, }, }, }, }, { Name: "uid", - ValueFrom: &appsv1alpha1.VarSource{ - ClusterVarRef: &appsv1alpha1.ClusterVarSelector{ - ClusterVars: appsv1alpha1.ClusterVars{ - ClusterUID: &appsv1alpha1.VarRequired, + ValueFrom: &appsv1.VarSource{ + ClusterVarRef: &appsv1.ClusterVarSelector{ + ClusterVars: appsv1.ClusterVars{ + ClusterUID: &appsv1.VarRequired, }, }, }, @@ -1935,18 +1934,18 @@ var _ = Describe("vars", func() { }) It("component not found w/ optional", func() { - vars := []appsv1alpha1.EnvVar{ + vars := []appsv1.EnvVar{ { Name: "service-host", - ValueFrom: &appsv1alpha1.VarSource{ - ServiceVarRef: &appsv1alpha1.ServiceVarSelector{ - ClusterObjectReference: appsv1alpha1.ClusterObjectReference{ + ValueFrom: &appsv1.VarSource{ + ServiceVarRef: &appsv1.ServiceVarSelector{ + ClusterObjectReference: appsv1.ClusterObjectReference{ CompDef: "non-exist", Name: "service", Optional: optional(), }, - ServiceVars: appsv1alpha1.ServiceVars{ - Host: &appsv1alpha1.VarOptional, + ServiceVars: appsv1.ServiceVars{ + Host: &appsv1.VarOptional, }, }, }, @@ -1959,18 +1958,18 @@ var _ = Describe("vars", func() { }) It("component not found w/ required", func() { - vars := []appsv1alpha1.EnvVar{ + vars := []appsv1.EnvVar{ { Name: "service-host", - ValueFrom: &appsv1alpha1.VarSource{ - ServiceVarRef: &appsv1alpha1.ServiceVarSelector{ - ClusterObjectReference: appsv1alpha1.ClusterObjectReference{ + ValueFrom: &appsv1.VarSource{ + ServiceVarRef: &appsv1.ServiceVarSelector{ + ClusterObjectReference: appsv1.ClusterObjectReference{ CompDef: "non-exist", Name: "service", Optional: required(), }, - ServiceVars: appsv1alpha1.ServiceVars{ - Host: &appsv1alpha1.VarRequired, + ServiceVars: appsv1.ServiceVars{ + Host: &appsv1.VarRequired, }, }, }, @@ -1983,18 +1982,18 @@ var _ = Describe("vars", func() { It("default component", func() { svcName := constant.GenerateComponentServiceName(synthesizedComp.ClusterName, synthesizedComp.Name, "service") - vars := []appsv1alpha1.EnvVar{ + vars := []appsv1.EnvVar{ { Name: "service-host", - ValueFrom: &appsv1alpha1.VarSource{ - ServiceVarRef: &appsv1alpha1.ServiceVarSelector{ - ClusterObjectReference: appsv1alpha1.ClusterObjectReference{ + ValueFrom: &appsv1.VarSource{ + ServiceVarRef: &appsv1.ServiceVarSelector{ + ClusterObjectReference: appsv1.ClusterObjectReference{ // don't specify the comp def, it will match self by default Name: "service", Optional: required(), }, - ServiceVars: appsv1alpha1.ServiceVars{ - Host: &appsv1alpha1.VarRequired, + ServiceVars: appsv1.ServiceVars{ + Host: &appsv1.VarRequired, }, }, }, @@ -2171,18 +2170,18 @@ var _ = Describe("vars", func() { }) It("w/ option - ref others", func() { - vars := []appsv1alpha1.EnvVar{ + vars := []appsv1.EnvVar{ { Name: "service-host", - ValueFrom: &appsv1alpha1.VarSource{ - ServiceVarRef: &appsv1alpha1.ServiceVarSelector{ - ClusterObjectReference: appsv1alpha1.ClusterObjectReference{ + ValueFrom: &appsv1.VarSource{ + ServiceVarRef: &appsv1.ServiceVarSelector{ + ClusterObjectReference: appsv1.ClusterObjectReference{ CompDef: "abc" + synthesizedComp.CompDefName, // different with synthesizedComp Name: "service", Optional: required(), }, - ServiceVars: appsv1alpha1.ServiceVars{ - Host: &appsv1alpha1.VarRequired, + ServiceVars: appsv1.ServiceVars{ + Host: &appsv1.VarRequired, }, }, }, @@ -2194,39 +2193,39 @@ var _ = Describe("vars", func() { }) It("individual", func() { - vars := []appsv1alpha1.EnvVar{ + vars := []appsv1.EnvVar{ { Name: "service-host", - ValueFrom: &appsv1alpha1.VarSource{ - ServiceVarRef: &appsv1alpha1.ServiceVarSelector{ - ClusterObjectReference: appsv1alpha1.ClusterObjectReference{ + ValueFrom: &appsv1.VarSource{ + ServiceVarRef: &appsv1.ServiceVarSelector{ + ClusterObjectReference: appsv1.ClusterObjectReference{ CompDef: synthesizedComp.CompDefName, Name: "service", Optional: required(), - MultipleClusterObjectOption: &appsv1alpha1.MultipleClusterObjectOption{ - Strategy: appsv1alpha1.MultipleClusterObjectStrategyIndividual, + MultipleClusterObjectOption: &appsv1.MultipleClusterObjectOption{ + Strategy: appsv1.MultipleClusterObjectStrategyIndividual, }, }, - ServiceVars: appsv1alpha1.ServiceVars{ - Host: &appsv1alpha1.VarRequired, + ServiceVars: appsv1.ServiceVars{ + Host: &appsv1.VarRequired, }, }, }, }, { Name: "credential-username", - ValueFrom: &appsv1alpha1.VarSource{ - CredentialVarRef: &appsv1alpha1.CredentialVarSelector{ - ClusterObjectReference: appsv1alpha1.ClusterObjectReference{ + ValueFrom: &appsv1.VarSource{ + CredentialVarRef: &appsv1.CredentialVarSelector{ + ClusterObjectReference: appsv1.ClusterObjectReference{ CompDef: synthesizedComp.CompDefName, Name: "credential", Optional: required(), - MultipleClusterObjectOption: &appsv1alpha1.MultipleClusterObjectOption{ - Strategy: appsv1alpha1.MultipleClusterObjectStrategyIndividual, + MultipleClusterObjectOption: &appsv1.MultipleClusterObjectOption{ + Strategy: appsv1.MultipleClusterObjectStrategyIndividual, }, }, - CredentialVars: appsv1alpha1.CredentialVars{ - Username: &appsv1alpha1.VarRequired, + CredentialVars: appsv1.CredentialVars{ + Username: &appsv1.VarRequired, }, }, }, @@ -2263,21 +2262,21 @@ var _ = Describe("vars", func() { }) It("combined - reuse", func() { - vars := []appsv1alpha1.EnvVar{ + vars := []appsv1.EnvVar{ { Name: "service-host", - ValueFrom: &appsv1alpha1.VarSource{ - ServiceVarRef: &appsv1alpha1.ServiceVarSelector{ - ClusterObjectReference: appsv1alpha1.ClusterObjectReference{ + ValueFrom: &appsv1.VarSource{ + ServiceVarRef: &appsv1.ServiceVarSelector{ + ClusterObjectReference: appsv1.ClusterObjectReference{ CompDef: synthesizedComp.CompDefName, Name: "service", Optional: required(), - MultipleClusterObjectOption: &appsv1alpha1.MultipleClusterObjectOption{ - Strategy: appsv1alpha1.MultipleClusterObjectStrategyCombined, + MultipleClusterObjectOption: &appsv1.MultipleClusterObjectOption{ + Strategy: appsv1.MultipleClusterObjectStrategyCombined, }, }, - ServiceVars: appsv1alpha1.ServiceVars{ - Host: &appsv1alpha1.VarRequired, + ServiceVars: appsv1.ServiceVars{ + Host: &appsv1.VarRequired, }, }, }, @@ -2299,24 +2298,24 @@ var _ = Describe("vars", func() { suffix := "suffix" combinedSvcVarName := fmt.Sprintf("%s_%s", "service-host", suffix) - vars := []appsv1alpha1.EnvVar{ + vars := []appsv1.EnvVar{ { Name: "service-host", - ValueFrom: &appsv1alpha1.VarSource{ - ServiceVarRef: &appsv1alpha1.ServiceVarSelector{ - ClusterObjectReference: appsv1alpha1.ClusterObjectReference{ + ValueFrom: &appsv1.VarSource{ + ServiceVarRef: &appsv1.ServiceVarSelector{ + ClusterObjectReference: appsv1.ClusterObjectReference{ CompDef: synthesizedComp.CompDefName, Name: "service", Optional: required(), - MultipleClusterObjectOption: &appsv1alpha1.MultipleClusterObjectOption{ - Strategy: appsv1alpha1.MultipleClusterObjectStrategyCombined, - CombinedOption: &appsv1alpha1.MultipleClusterObjectCombinedOption{ + MultipleClusterObjectOption: &appsv1.MultipleClusterObjectOption{ + Strategy: appsv1.MultipleClusterObjectStrategyCombined, + CombinedOption: &appsv1.MultipleClusterObjectCombinedOption{ NewVarSuffix: &suffix, }, }, }, - ServiceVars: appsv1alpha1.ServiceVars{ - Host: &appsv1alpha1.VarRequired, + ServiceVars: appsv1.ServiceVars{ + Host: &appsv1.VarRequired, }, }, }, @@ -2337,21 +2336,21 @@ var _ = Describe("vars", func() { }) It("combined - value from error", func() { - vars := []appsv1alpha1.EnvVar{ + vars := []appsv1.EnvVar{ { Name: "credential-username", - ValueFrom: &appsv1alpha1.VarSource{ - CredentialVarRef: &appsv1alpha1.CredentialVarSelector{ - ClusterObjectReference: appsv1alpha1.ClusterObjectReference{ + ValueFrom: &appsv1.VarSource{ + CredentialVarRef: &appsv1.CredentialVarSelector{ + ClusterObjectReference: appsv1.ClusterObjectReference{ CompDef: synthesizedComp.CompDefName, Name: "credential", Optional: required(), - MultipleClusterObjectOption: &appsv1alpha1.MultipleClusterObjectOption{ - Strategy: appsv1alpha1.MultipleClusterObjectStrategyCombined, + MultipleClusterObjectOption: &appsv1.MultipleClusterObjectOption{ + Strategy: appsv1.MultipleClusterObjectStrategyCombined, }, }, - CredentialVars: appsv1alpha1.CredentialVars{ - Username: &appsv1alpha1.VarRequired, + CredentialVars: appsv1.CredentialVars{ + Username: &appsv1.VarRequired, }, }, }, @@ -2368,21 +2367,21 @@ var _ = Describe("vars", func() { compName2: synthesizedComp.CompDefName, compName3: synthesizedComp.CompDefName, // there is no service object for comp3. } - vars := []appsv1alpha1.EnvVar{ + vars := []appsv1.EnvVar{ { Name: "service-host", - ValueFrom: &appsv1alpha1.VarSource{ - ServiceVarRef: &appsv1alpha1.ServiceVarSelector{ - ClusterObjectReference: appsv1alpha1.ClusterObjectReference{ + ValueFrom: &appsv1.VarSource{ + ServiceVarRef: &appsv1.ServiceVarSelector{ + ClusterObjectReference: appsv1.ClusterObjectReference{ CompDef: synthesizedComp.CompDefName, Name: "service", Optional: optional(), // optional - MultipleClusterObjectOption: &appsv1alpha1.MultipleClusterObjectOption{ - Strategy: appsv1alpha1.MultipleClusterObjectStrategyIndividual, + MultipleClusterObjectOption: &appsv1.MultipleClusterObjectOption{ + Strategy: appsv1.MultipleClusterObjectStrategyIndividual, }, }, - ServiceVars: appsv1alpha1.ServiceVars{ - Host: &appsv1alpha1.VarRequired, + ServiceVars: appsv1.ServiceVars{ + Host: &appsv1.VarRequired, }, }, }, @@ -2408,21 +2407,21 @@ var _ = Describe("vars", func() { compName2: synthesizedComp.CompDefName, compName3: synthesizedComp.CompDefName, // there is no service object for comp3. } - vars := []appsv1alpha1.EnvVar{ + vars := []appsv1.EnvVar{ { Name: "service-host", - ValueFrom: &appsv1alpha1.VarSource{ - ServiceVarRef: &appsv1alpha1.ServiceVarSelector{ - ClusterObjectReference: appsv1alpha1.ClusterObjectReference{ + ValueFrom: &appsv1.VarSource{ + ServiceVarRef: &appsv1.ServiceVarSelector{ + ClusterObjectReference: appsv1.ClusterObjectReference{ CompDef: synthesizedComp.CompDefName, Name: "service", Optional: required(), // required - MultipleClusterObjectOption: &appsv1alpha1.MultipleClusterObjectOption{ - Strategy: appsv1alpha1.MultipleClusterObjectStrategyIndividual, + MultipleClusterObjectOption: &appsv1.MultipleClusterObjectOption{ + Strategy: appsv1.MultipleClusterObjectStrategyIndividual, }, }, - ServiceVars: appsv1alpha1.ServiceVars{ - Host: &appsv1alpha1.VarRequired, + ServiceVars: appsv1.ServiceVars{ + Host: &appsv1.VarRequired, }, }, }, @@ -2464,21 +2463,21 @@ var _ = Describe("vars", func() { compName2: synthesizedComp.CompDefName, compName3: synthesizedComp.CompDefName, // there is no service object for comp3. } - vars := []appsv1alpha1.EnvVar{ + vars := []appsv1.EnvVar{ { Name: "service-host", - ValueFrom: &appsv1alpha1.VarSource{ - ServiceVarRef: &appsv1alpha1.ServiceVarSelector{ - ClusterObjectReference: appsv1alpha1.ClusterObjectReference{ + ValueFrom: &appsv1.VarSource{ + ServiceVarRef: &appsv1.ServiceVarSelector{ + ClusterObjectReference: appsv1.ClusterObjectReference{ CompDef: synthesizedComp.CompDefName, Name: "service", Optional: optional(), - MultipleClusterObjectOption: &appsv1alpha1.MultipleClusterObjectOption{ - Strategy: appsv1alpha1.MultipleClusterObjectStrategyCombined, + MultipleClusterObjectOption: &appsv1.MultipleClusterObjectOption{ + Strategy: appsv1.MultipleClusterObjectStrategyCombined, }, }, - ServiceVars: appsv1alpha1.ServiceVars{ - Host: &appsv1alpha1.VarRequired, + ServiceVars: appsv1.ServiceVars{ + Host: &appsv1.VarRequired, }, }, }, @@ -2504,21 +2503,21 @@ var _ = Describe("vars", func() { compName2: synthesizedComp.CompDefName, compName3: synthesizedComp.CompDefName, // there is no service object for comp3. } - vars := []appsv1alpha1.EnvVar{ + vars := []appsv1.EnvVar{ { Name: "service-host", - ValueFrom: &appsv1alpha1.VarSource{ - ServiceVarRef: &appsv1alpha1.ServiceVarSelector{ - ClusterObjectReference: appsv1alpha1.ClusterObjectReference{ + ValueFrom: &appsv1.VarSource{ + ServiceVarRef: &appsv1.ServiceVarSelector{ + ClusterObjectReference: appsv1.ClusterObjectReference{ CompDef: synthesizedComp.CompDefName, Name: "service", Optional: required(), // required - MultipleClusterObjectOption: &appsv1alpha1.MultipleClusterObjectOption{ - Strategy: appsv1alpha1.MultipleClusterObjectStrategyCombined, + MultipleClusterObjectOption: &appsv1.MultipleClusterObjectOption{ + Strategy: appsv1.MultipleClusterObjectStrategyCombined, }, }, - ServiceVars: appsv1alpha1.ServiceVars{ - Host: &appsv1alpha1.VarRequired, + ServiceVars: appsv1.ServiceVars{ + Host: &appsv1.VarRequired, }, }, }, @@ -2579,7 +2578,7 @@ var _ = Describe("vars", func() { }) It("reference", func() { - vars := []appsv1alpha1.EnvVar{ + vars := []appsv1.EnvVar{ { Name: "aa", Value: "~", @@ -2602,7 +2601,7 @@ var _ = Describe("vars", func() { }) It("reference not defined", func() { - vars := []appsv1alpha1.EnvVar{ + vars := []appsv1.EnvVar{ { Name: "ba", Value: "~", @@ -2625,7 +2624,7 @@ var _ = Describe("vars", func() { }) It("reference credential var", func() { - vars := []appsv1alpha1.EnvVar{ + vars := []appsv1.EnvVar{ { Name: "ca", Value: "~", @@ -2636,14 +2635,14 @@ var _ = Describe("vars", func() { }, { Name: "credential-username", - ValueFrom: &appsv1alpha1.VarSource{ - CredentialVarRef: &appsv1alpha1.CredentialVarSelector{ - ClusterObjectReference: appsv1alpha1.ClusterObjectReference{ + ValueFrom: &appsv1.VarSource{ + CredentialVarRef: &appsv1.CredentialVarSelector{ + ClusterObjectReference: appsv1.ClusterObjectReference{ Name: "credential", Optional: optional(), }, - CredentialVars: appsv1alpha1.CredentialVars{ - Username: &appsv1alpha1.VarOptional, + CredentialVars: appsv1.CredentialVars{ + Username: &appsv1.VarOptional, }, }, }, @@ -2663,7 +2662,7 @@ var _ = Describe("vars", func() { }) It("escaping", func() { - vars := []appsv1alpha1.EnvVar{ + vars := []appsv1.EnvVar{ { Name: "da", Value: "~", @@ -2686,7 +2685,7 @@ var _ = Describe("vars", func() { }) It("reference and escaping", func() { - vars := []appsv1alpha1.EnvVar{ + vars := []appsv1.EnvVar{ { Name: "ea", Value: "~", @@ -2715,7 +2714,7 @@ var _ = Describe("vars", func() { }) It("all in one", func() { - vars := []appsv1alpha1.EnvVar{ + vars := []appsv1.EnvVar{ { Name: "fa", Value: "~", @@ -2726,14 +2725,14 @@ var _ = Describe("vars", func() { }, { Name: "credential-username", - ValueFrom: &appsv1alpha1.VarSource{ - CredentialVarRef: &appsv1alpha1.CredentialVarSelector{ - ClusterObjectReference: appsv1alpha1.ClusterObjectReference{ + ValueFrom: &appsv1.VarSource{ + CredentialVarRef: &appsv1.CredentialVarSelector{ + ClusterObjectReference: appsv1.ClusterObjectReference{ Name: "credential", Optional: optional(), }, - CredentialVars: appsv1alpha1.CredentialVars{ - Username: &appsv1alpha1.VarOptional, + CredentialVars: appsv1.CredentialVars{ + Username: &appsv1.VarOptional, }, }, }, @@ -2748,7 +2747,7 @@ var _ = Describe("vars", func() { Context("vars expression", func() { It("simple format", func() { - vars := []appsv1alpha1.EnvVar{ + vars := []appsv1.EnvVar{ { Name: "port", Value: "12345", @@ -2762,7 +2761,7 @@ var _ = Describe("vars", func() { }) It("cluster domain", func() { - vars := []appsv1alpha1.EnvVar{ + vars := []appsv1.EnvVar{ { Name: "headless", Value: "test-headless.default.svc", @@ -2776,7 +2775,7 @@ var _ = Describe("vars", func() { }) It("condition exp", func() { - vars := []appsv1alpha1.EnvVar{ + vars := []appsv1.EnvVar{ { Name: "port", Value: "12345", @@ -2790,7 +2789,7 @@ var _ = Describe("vars", func() { }) It("exp only", func() { - vars := []appsv1alpha1.EnvVar{ + vars := []appsv1.EnvVar{ { Name: "port", Expression: expp("12345"), @@ -2803,7 +2802,7 @@ var _ = Describe("vars", func() { }) It("exp error", func() { - vars := []appsv1alpha1.EnvVar{ + vars := []appsv1.EnvVar{ { Name: "port", Expression: expp("{{ if eq .port 12345 }}54321{{ end }}"), @@ -2815,7 +2814,7 @@ var _ = Describe("vars", func() { }) It("access another vars", func() { - vars := []appsv1alpha1.EnvVar{ + vars := []appsv1.EnvVar{ { Name: "host", Value: "localhost", @@ -2852,21 +2851,21 @@ var _ = Describe("vars", func() { compName1: synthesizedComp.CompDefName, compName2: synthesizedComp.CompDefName, } - vars := []appsv1alpha1.EnvVar{ + vars := []appsv1.EnvVar{ { Name: "host", - ValueFrom: &appsv1alpha1.VarSource{ - ServiceVarRef: &appsv1alpha1.ServiceVarSelector{ - ClusterObjectReference: appsv1alpha1.ClusterObjectReference{ + ValueFrom: &appsv1.VarSource{ + ServiceVarRef: &appsv1.ServiceVarSelector{ + ClusterObjectReference: appsv1.ClusterObjectReference{ CompDef: synthesizedComp.CompDefName, Name: "", Optional: required(), - MultipleClusterObjectOption: &appsv1alpha1.MultipleClusterObjectOption{ - Strategy: appsv1alpha1.MultipleClusterObjectStrategyIndividual, + MultipleClusterObjectOption: &appsv1.MultipleClusterObjectOption{ + Strategy: appsv1.MultipleClusterObjectStrategyIndividual, }, }, - ServiceVars: appsv1alpha1.ServiceVars{ - Host: &appsv1alpha1.VarRequired, + ServiceVars: appsv1.ServiceVars{ + Host: &appsv1.VarRequired, }, }, }, @@ -2923,17 +2922,17 @@ var _ = Describe("vars", func() { It("exp for resolved but not-exist vars", func() { svcName := constant.GenerateComponentServiceName(synthesizedComp.ClusterName, synthesizedComp.Name, "") - vars := []appsv1alpha1.EnvVar{ + vars := []appsv1.EnvVar{ { Name: "host", - ValueFrom: &appsv1alpha1.VarSource{ - ServiceVarRef: &appsv1alpha1.ServiceVarSelector{ - ClusterObjectReference: appsv1alpha1.ClusterObjectReference{ + ValueFrom: &appsv1.VarSource{ + ServiceVarRef: &appsv1.ServiceVarSelector{ + ClusterObjectReference: appsv1.ClusterObjectReference{ Name: "", // the default component service Optional: optional(), }, - ServiceVars: appsv1alpha1.ServiceVars{ - Host: &appsv1alpha1.VarOptional, + ServiceVars: appsv1.ServiceVars{ + Host: &appsv1.VarOptional, }, }, }, @@ -2970,17 +2969,17 @@ var _ = Describe("vars", func() { }) It("exp for credential-vars", func() { - vars := []appsv1alpha1.EnvVar{ + vars := []appsv1.EnvVar{ { Name: "password", - ValueFrom: &appsv1alpha1.VarSource{ - CredentialVarRef: &appsv1alpha1.CredentialVarSelector{ - ClusterObjectReference: appsv1alpha1.ClusterObjectReference{ + ValueFrom: &appsv1.VarSource{ + CredentialVarRef: &appsv1.CredentialVarSelector{ + ClusterObjectReference: appsv1.ClusterObjectReference{ Name: "credential", Optional: required(), }, - CredentialVars: appsv1alpha1.CredentialVars{ - Password: &appsv1alpha1.VarRequired, + CredentialVars: appsv1.CredentialVars{ + Password: &appsv1.VarRequired, }, }, }, @@ -3015,17 +3014,17 @@ var _ = Describe("vars", func() { }) It("depends on credential-vars", func() { - vars := []appsv1alpha1.EnvVar{ + vars := []appsv1.EnvVar{ { Name: "raw", - ValueFrom: &appsv1alpha1.VarSource{ - CredentialVarRef: &appsv1alpha1.CredentialVarSelector{ - ClusterObjectReference: appsv1alpha1.ClusterObjectReference{ + ValueFrom: &appsv1.VarSource{ + CredentialVarRef: &appsv1.CredentialVarSelector{ + ClusterObjectReference: appsv1.ClusterObjectReference{ Name: "credential", Optional: required(), }, - CredentialVars: appsv1alpha1.CredentialVars{ - Password: &appsv1alpha1.VarRequired, + CredentialVars: appsv1.CredentialVars{ + Password: &appsv1.VarRequired, }, }, }, @@ -3057,7 +3056,7 @@ var _ = Describe("vars", func() { }) It("depends on intermediate values", func() { - vars := []appsv1alpha1.EnvVar{ + vars := []appsv1.EnvVar{ { Name: "endpoint", Expression: expp("{{ .host }}:{{ .port }}"), diff --git a/pkg/controller/component/workload_utils.go b/pkg/controller/component/workload_utils.go index 8204adf5d34..4eca5ee4623 100644 --- a/pkg/controller/component/workload_utils.go +++ b/pkg/controller/component/workload_utils.go @@ -22,7 +22,6 @@ package component import ( "context" "fmt" - appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" "maps" "reflect" "strconv" @@ -31,7 +30,7 @@ import ( corev1 "k8s.io/api/core/v1" "sigs.k8s.io/controller-runtime/pkg/client" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" "github.com/apecloud/kubeblocks/pkg/constant" "github.com/apecloud/kubeblocks/pkg/controller/instanceset" @@ -75,7 +74,7 @@ func ListOwnedServices(ctx context.Context, cli client.Reader, namespace, cluste } // GetMinReadySeconds gets the underlying workload's minReadySeconds of the component. -func GetMinReadySeconds(ctx context.Context, cli client.Client, cluster appsv1alpha1.Cluster, compName string) (minReadySeconds int32, err error) { +func GetMinReadySeconds(ctx context.Context, cli client.Client, cluster appsv1.Cluster, compName string) (minReadySeconds int32, err error) { var its []*workloads.InstanceSet its, err = listWorkloads(ctx, cli, cluster.Namespace, cluster.Name, compName) if err != nil { @@ -137,7 +136,10 @@ func GenerateAllPodNames( workloadName := constant.GenerateWorkloadNamePattern(clusterName, fullCompName) var templates []instanceset.InstanceTemplate for i := range instances { - templates = append(templates, &instances[i]) + templates = append(templates, &workloads.InstanceTemplate{ + Name: instances[i].Name, + Replicas: instances[i].Replicas, + }) } return instanceset.GenerateAllInstanceNames(workloadName, compReplicas, templates, offlineInstances, workloads.Ordinals{}) } @@ -157,7 +159,7 @@ func GenerateAllPodNamesToSet( // key: podName, value: templateName podSet := map[string]string{} for _, insName := range instanceNames { - podSet[insName] = appsv1alpha1.GetInstanceTemplateName(clusterName, fullCompName, insName) + podSet[insName] = appsv1.GetInstanceTemplateName(clusterName, fullCompName, insName) } return podSet, nil } diff --git a/pkg/controller/configuration/builtin_env_test.go b/pkg/controller/configuration/builtin_env_test.go index 341b9043f0f..4c7b26799d1 100644 --- a/pkg/controller/configuration/builtin_env_test.go +++ b/pkg/controller/configuration/builtin_env_test.go @@ -31,7 +31,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" coreclient "sigs.k8s.io/controller-runtime/pkg/client" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" "github.com/apecloud/kubeblocks/pkg/constant" ctrlcomp "github.com/apecloud/kubeblocks/pkg/controller/component" testutil "github.com/apecloud/kubeblocks/pkg/testutil/k8s" @@ -53,7 +53,7 @@ bootstrap: var ( podSpec *corev1.PodSpec component *ctrlcomp.SynthesizedComponent - cluster *appsv1alpha1.Cluster + cluster *appsv1.Cluster mockClient *testutil.K8sClientMockHelper ) @@ -198,7 +198,7 @@ bootstrap: }, }, } - cluster = &appsv1alpha1.Cluster{ + cluster = &appsv1.Cluster{ ObjectMeta: metav1.ObjectMeta{ Name: "my", UID: "b006a20c-fb03-441c-bffa-2605cad7e297", @@ -234,7 +234,7 @@ bootstrap: }}, } cfgBuilder.injectBuiltInObjectsAndFunctions(podSpec, component, localObjs, - &appsv1alpha1.Cluster{ + &appsv1.Cluster{ ObjectMeta: metav1.ObjectMeta{ Name: "my_test", Namespace: "default", diff --git a/pkg/controller/configuration/builtin_objects.go b/pkg/controller/configuration/builtin_objects.go index 0577c4e3d8a..26b1ba88928 100644 --- a/pkg/controller/configuration/builtin_objects.go +++ b/pkg/controller/configuration/builtin_objects.go @@ -25,7 +25,7 @@ import ( "golang.org/x/exp/maps" corev1 "k8s.io/api/core/v1" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" "github.com/apecloud/kubeblocks/pkg/constant" "github.com/apecloud/kubeblocks/pkg/controller/component" "github.com/apecloud/kubeblocks/pkg/gotemplate" @@ -38,7 +38,7 @@ type ResourceDefinition struct { } type builtInObjects struct { - cluster *appsv1alpha1.Cluster + cluster *appsv1.Cluster podSpec *corev1.PodSpec component *component.SynthesizedComponent } @@ -51,7 +51,7 @@ const ( builtinClusterDomainObject = "clusterDomain" ) -func buildInComponentObjects(podSpec *corev1.PodSpec, component *component.SynthesizedComponent, cluster *appsv1alpha1.Cluster) *builtInObjects { +func buildInComponentObjects(podSpec *corev1.PodSpec, component *component.SynthesizedComponent, cluster *appsv1.Cluster) *builtInObjects { return &builtInObjects{ podSpec: podSpec, component: component, diff --git a/pkg/controller/configuration/config_template.go b/pkg/controller/configuration/config_template.go index 84f159ff956..68c1f021923 100644 --- a/pkg/controller/configuration/config_template.go +++ b/pkg/controller/configuration/config_template.go @@ -26,7 +26,7 @@ import ( corev1 "k8s.io/api/core/v1" "sigs.k8s.io/controller-runtime/pkg/client" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" "github.com/apecloud/kubeblocks/pkg/controller/component" "github.com/apecloud/kubeblocks/pkg/gotemplate" ) @@ -41,9 +41,8 @@ type configTemplateBuilder struct { builtInObjects *builtInObjects podSpec *corev1.PodSpec - // cluster *appsv1alpha1.Cluster - ctx context.Context - cli client.Reader + ctx context.Context + cli client.Reader } const defaultTemplateName = "KbTemplate" @@ -91,7 +90,7 @@ func (c *configTemplateBuilder) injectBuiltInObjectsAndFunctions( podSpec *corev1.PodSpec, component *component.SynthesizedComponent, localObjs []client.Object, - cluster *appsv1alpha1.Cluster) { + cluster *appsv1.Cluster) { c.podSpec = podSpec c.builtInFunctions = BuiltInCustomFunctions(c, component, localObjs) c.builtInObjects = buildInComponentObjects(podSpec, component, cluster) diff --git a/pkg/controller/configuration/config_template_test.go b/pkg/controller/configuration/config_template_test.go index 57ff07c107a..a5552064762 100644 --- a/pkg/controller/configuration/config_template_test.go +++ b/pkg/controller/configuration/config_template_test.go @@ -30,7 +30,7 @@ import ( "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" "github.com/apecloud/kubeblocks/pkg/constant" ctrlcomp "github.com/apecloud/kubeblocks/pkg/controller/component" viper "github.com/apecloud/kubeblocks/pkg/viperx" @@ -177,7 +177,7 @@ single_thread_memory = 294912 "default", nil, nil) - cfgBuilder.injectBuiltInObjectsAndFunctions(podSpec, component, nil, &appsv1alpha1.Cluster{ + cfgBuilder.injectBuiltInObjectsAndFunctions(podSpec, component, nil, &appsv1.Cluster{ ObjectMeta: metav1.ObjectMeta{ Name: "my_test", Namespace: "default", @@ -202,7 +202,7 @@ single_thread_memory = 294912 viper.Set(constant.KubernetesClusterDomainEnv, "test-domain") cfgBuilder.injectBuiltInObjectsAndFunctions(podSpec, component, nil, - &appsv1alpha1.Cluster{ + &appsv1.Cluster{ ObjectMeta: metav1.ObjectMeta{ Name: "my_test", Namespace: "default", @@ -269,7 +269,7 @@ single_thread_memory = 294912 ) cfgBuilder.injectBuiltInObjectsAndFunctions(podSpec, component, nil, - &appsv1alpha1.Cluster{ + &appsv1.Cluster{ ObjectMeta: metav1.ObjectMeta{ Name: "my_test", Namespace: "default", diff --git a/pkg/controller/configuration/config_utils.go b/pkg/controller/configuration/config_utils.go index d7dd8976dd0..a6b1df2af88 100644 --- a/pkg/controller/configuration/config_utils.go +++ b/pkg/controller/configuration/config_utils.go @@ -63,7 +63,7 @@ func createConfigObjects(cli client.Client, ctx context.Context, objs []client.O // buildConfigManagerWithComponent build the configmgr sidecar container and update it // into PodSpec if configuration reload option is on func buildConfigManagerWithComponent(podSpec *corev1.PodSpec, configSpecs []appsv1.ComponentConfigSpec, - ctx context.Context, cli client.Client, cluster *appsv1alpha1.Cluster, synthesizedComp *component.SynthesizedComponent) error { + ctx context.Context, cli client.Client, cluster *appsv1.Cluster, synthesizedComp *component.SynthesizedComponent) error { var err error var buildParams *cfgcm.CfgManagerBuildParams @@ -204,7 +204,7 @@ func getUsingVolumesByConfigSpecs(podSpec *corev1.PodSpec, configSpecs []appsv1. return volumeDirs, usingConfigSpecs } -func buildConfigManagerParams(cli client.Client, ctx context.Context, cluster *appsv1alpha1.Cluster, comp *component.SynthesizedComponent, configSpecBuildParams []cfgcm.ConfigSpecMeta, volumeDirs []corev1.VolumeMount, podSpec *corev1.PodSpec) (*cfgcm.CfgManagerBuildParams, error) { +func buildConfigManagerParams(cli client.Client, ctx context.Context, cluster *appsv1.Cluster, comp *component.SynthesizedComponent, configSpecBuildParams []cfgcm.ConfigSpecMeta, volumeDirs []corev1.VolumeMount, podSpec *corev1.PodSpec) (*cfgcm.CfgManagerBuildParams, error) { cfgManagerParams := &cfgcm.CfgManagerBuildParams{ ManagerName: constant.ConfigSidecarName, ComponentName: comp.Name, diff --git a/pkg/controller/configuration/configuration_test.go b/pkg/controller/configuration/configuration_test.go index 253438d1377..f561ee3703c 100644 --- a/pkg/controller/configuration/configuration_test.go +++ b/pkg/controller/configuration/configuration_test.go @@ -29,7 +29,6 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" "github.com/apecloud/kubeblocks/pkg/controller/component" intctrlutil "github.com/apecloud/kubeblocks/pkg/controllerutil" testapps "github.com/apecloud/kubeblocks/pkg/testutil/apps" @@ -59,7 +58,7 @@ func allFieldsCompDefObj(create bool) *appsv1.ComponentDefinition { return compDef } -func newAllFieldsClusterObj(compDef *appsv1.ComponentDefinition, create bool) (*appsv1alpha1.Cluster, *appsv1.ComponentDefinition, types.NamespacedName) { +func newAllFieldsClusterObj(compDef *appsv1.ComponentDefinition, create bool) (*appsv1.Cluster, *appsv1.ComponentDefinition, types.NamespacedName) { // setup Cluster obj requires default ComponentDefinition object if compDef == nil { compDef = allFieldsCompDefObj(create) @@ -79,7 +78,7 @@ func newAllFieldsClusterObj(compDef *appsv1.ComponentDefinition, create bool) (* return clusterObj, compDef, key } -func newAllFieldsSynthesizedComponent(compDef *appsv1.ComponentDefinition, cluster *appsv1alpha1.Cluster) *component.SynthesizedComponent { +func newAllFieldsSynthesizedComponent(compDef *appsv1.ComponentDefinition, cluster *appsv1.Cluster) *component.SynthesizedComponent { reqCtx := intctrlutil.RequestCtx{ Ctx: testCtx.Ctx, Log: logger, @@ -99,7 +98,7 @@ func newAllFieldsSynthesizedComponent(compDef *appsv1.ComponentDefinition, clust return synthesizeComp } -func newAllFieldsComponent(cluster *appsv1alpha1.Cluster) *appsv1.Component { +func newAllFieldsComponent(cluster *appsv1.Cluster) *appsv1.Component { comp, _ := component.BuildComponent(cluster, &cluster.Spec.ComponentSpecs[0], nil, nil) return comp } diff --git a/pkg/controller/configuration/envfrom_utils.go b/pkg/controller/configuration/envfrom_utils.go index f1fb66bfcfc..cbbe13f80da 100644 --- a/pkg/controller/configuration/envfrom_utils.go +++ b/pkg/controller/configuration/envfrom_utils.go @@ -28,7 +28,6 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" appsv1beta1 "github.com/apecloud/kubeblocks/apis/apps/v1beta1" "github.com/apecloud/kubeblocks/pkg/configuration/core" cfgutil "github.com/apecloud/kubeblocks/pkg/configuration/util" @@ -39,7 +38,7 @@ import ( "github.com/apecloud/kubeblocks/pkg/generics" ) -func injectTemplateEnvFrom(cluster *appsv1alpha1.Cluster, component *component.SynthesizedComponent, podSpec *corev1.PodSpec, cli client.Client, ctx context.Context, localObjs []client.Object) error { +func injectTemplateEnvFrom(cluster *appsv1.Cluster, component *component.SynthesizedComponent, podSpec *corev1.PodSpec, cli client.Client, ctx context.Context, localObjs []client.Object) error { var err error var cm *corev1.ConfigMap @@ -128,7 +127,7 @@ func fetchConfigmap(localObjs []client.Object, cmName, namespace string, cli cli return cmObj, nil } -func createEnvFromConfigmap(cluster *appsv1alpha1.Cluster, componentName string, template appsv1.ComponentConfigSpec, originKey client.ObjectKey, envMap map[string]string, ctx context.Context, cli client.Client) (*corev1.ConfigMap, error) { +func createEnvFromConfigmap(cluster *appsv1.Cluster, componentName string, template appsv1.ComponentConfigSpec, originKey client.ObjectKey, envMap map[string]string, ctx context.Context, cli client.Client) (*corev1.ConfigMap, error) { cmKey := client.ObjectKey{ Name: core.GenerateEnvFromName(originKey.Name), Namespace: originKey.Namespace, diff --git a/pkg/controller/configuration/envfrom_utils_test.go b/pkg/controller/configuration/envfrom_utils_test.go index 4b5e0c581bc..df960f0c391 100644 --- a/pkg/controller/configuration/envfrom_utils_test.go +++ b/pkg/controller/configuration/envfrom_utils_test.go @@ -27,7 +27,6 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" appsv1beta1 "github.com/apecloud/kubeblocks/apis/apps/v1beta1" "github.com/apecloud/kubeblocks/pkg/configuration/core" "github.com/apecloud/kubeblocks/pkg/controller/component" @@ -45,7 +44,7 @@ var _ = Describe("ConfigEnvFrom test", func() { var ( compDef *appsv1.ComponentDefinition - cluster *appsv1alpha1.Cluster + cluster *appsv1.Cluster k8sMockClient *testutil.K8sClientMockHelper origCMObject *corev1.ConfigMap diff --git a/pkg/controller/configuration/operator.go b/pkg/controller/configuration/operator.go index 863f818fee8..f5cabf3a779 100644 --- a/pkg/controller/configuration/operator.go +++ b/pkg/controller/configuration/operator.go @@ -24,7 +24,6 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" "github.com/apecloud/kubeblocks/pkg/controller/component" ) @@ -33,7 +32,7 @@ type configOperator struct { } func NewConfigReconcileTask(resourceCtx *ResourceCtx, - cluster *appsv1alpha1.Cluster, + cluster *appsv1.Cluster, component *appsv1.Component, synthesizedComponent *component.SynthesizedComponent, podSpec *corev1.PodSpec, diff --git a/pkg/controller/configuration/operator_test.go b/pkg/controller/configuration/operator_test.go index 07a23dbbd58..4764f4ac049 100644 --- a/pkg/controller/configuration/operator_test.go +++ b/pkg/controller/configuration/operator_test.go @@ -40,7 +40,7 @@ import ( ) var _ = Describe("ConfigurationOperatorTest", func() { - var clusterObj *appsv1alpha1.Cluster + var clusterObj *appsv1.Cluster var compDefObj *appsv1.ComponentDefinition var componentObj *appsv1.Component var synthesizedComponent *component.SynthesizedComponent diff --git a/pkg/controller/configuration/pipeline.go b/pkg/controller/configuration/pipeline.go index 42ff08f03ba..c8dc1af6e19 100644 --- a/pkg/controller/configuration/pipeline.go +++ b/pkg/controller/configuration/pipeline.go @@ -39,7 +39,7 @@ import ( type ReconcileCtx struct { *ResourceCtx - Cluster *appsv1alpha1.Cluster + Cluster *appsv1.Cluster Component *appsv1.Component SynthesizedComponent *component.SynthesizedComponent PodSpec *corev1.PodSpec diff --git a/pkg/controller/configuration/pipeline_test.go b/pkg/controller/configuration/pipeline_test.go index f41dfd0d4fd..a3fbab97d65 100644 --- a/pkg/controller/configuration/pipeline_test.go +++ b/pkg/controller/configuration/pipeline_test.go @@ -45,7 +45,7 @@ import ( var _ = Describe("ConfigurationPipelineTest", func() { const testConfigFile = "postgresql.conf" - var clusterObj *appsv1alpha1.Cluster + var clusterObj *appsv1.Cluster var componentObj *appsv1.Component var compDefObj *appsv1.ComponentDefinition var synthesizedComponent *component.SynthesizedComponent diff --git a/pkg/controller/configuration/resource_wrapper.go b/pkg/controller/configuration/resource_wrapper.go index f00feae5ba7..80ff927a8e9 100644 --- a/pkg/controller/configuration/resource_wrapper.go +++ b/pkg/controller/configuration/resource_wrapper.go @@ -51,10 +51,10 @@ type ResourceFetcher[T any] struct { obj *T *ResourceCtx - ClusterObj *appsv1alpha1.Cluster + ClusterObj *appsv1.Cluster ComponentObj *appsv1.Component ComponentDefObj *appsv1.ComponentDefinition - ClusterComObj *appsv1alpha1.ClusterComponentSpec + ClusterComObj *appsv1.ClusterComponentSpec // Deprecated: this API will be removed from version 0.9.0 ClusterDefObj *appsv1.ClusterDefinition @@ -85,7 +85,7 @@ func (r *ResourceFetcher[T]) Cluster() *T { Name: r.ClusterName, } return r.Wrap(func() error { - r.ClusterObj = &appsv1alpha1.Cluster{} + r.ClusterObj = &appsv1.Cluster{} return r.Client.Get(r.Context, clusterKey, r.ClusterObj) }) } diff --git a/pkg/controller/configuration/resource_wrapper_test.go b/pkg/controller/configuration/resource_wrapper_test.go index 8cb26e91ffd..93f5b08faf0 100644 --- a/pkg/controller/configuration/resource_wrapper_test.go +++ b/pkg/controller/configuration/resource_wrapper_test.go @@ -28,7 +28,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/client" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1beta1 "github.com/apecloud/kubeblocks/apis/apps/v1beta1" cfgcore "github.com/apecloud/kubeblocks/pkg/configuration/core" testapps "github.com/apecloud/kubeblocks/pkg/testutil/apps" @@ -45,7 +45,7 @@ var _ = Describe("resource Fetcher", func() { var ( k8sMockClient *testutil.K8sClientMockHelper - cluster *appsv1alpha1.Cluster + cluster *appsv1.Cluster ) BeforeEach(func() { diff --git a/pkg/controller/configuration/template_merger.go b/pkg/controller/configuration/template_merger.go index cbfd9c2a8bf..e937de6e16c 100644 --- a/pkg/controller/configuration/template_merger.go +++ b/pkg/controller/configuration/template_merger.go @@ -146,7 +146,7 @@ func NewTemplateMerger(template appsv1.ConfigTemplateExtension, ctx context.Cont return merger, nil } -func mergerConfigTemplate(template *appsv1alpha1.LegacyRenderedTemplateSpec, +func mergerConfigTemplate(template *appsv1.LegacyRenderedTemplateSpec, builder *configTemplateBuilder, configSpec appsv1.ComponentConfigSpec, baseData map[string]string, diff --git a/pkg/controller/configuration/template_merger_test.go b/pkg/controller/configuration/template_merger_test.go index 35cffe27fb7..db562ee1198 100644 --- a/pkg/controller/configuration/template_merger_test.go +++ b/pkg/controller/configuration/template_merger_test.go @@ -30,7 +30,6 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" appsv1beta1 "github.com/apecloud/kubeblocks/apis/apps/v1beta1" cfgcore "github.com/apecloud/kubeblocks/pkg/configuration/core" "github.com/apecloud/kubeblocks/pkg/controller/component" @@ -117,7 +116,7 @@ max_connections=666 "default", nil, nil) templateBuilder.injectBuiltInObjectsAndFunctions( &corev1.PodSpec{}, &component.SynthesizedComponent{}, nil, - &appsv1alpha1.Cluster{ + &appsv1.Cluster{ ObjectMeta: metav1.ObjectMeta{ Name: testClusterName, Namespace: "default", @@ -137,12 +136,12 @@ max_connections=666 Context("with patch Merge", func() { It("mergerConfigTemplate patch policy", func() { - importedTemplate := &appsv1alpha1.LegacyRenderedTemplateSpec{ - ConfigTemplateExtension: appsv1alpha1.ConfigTemplateExtension{ + importedTemplate := &appsv1.LegacyRenderedTemplateSpec{ + ConfigTemplateExtension: appsv1.ConfigTemplateExtension{ Namespace: "default", // Name: configSpec.Name, TemplateRef: updatedCMObject.GetName(), - Policy: appsv1alpha1.PatchPolicy, + Policy: appsv1.PatchPolicy, }, } @@ -167,11 +166,11 @@ max_connections=666 Context("with replace Merge", func() { It("test mergerConfigTemplate replace policy", func() { - importedTemplate := &appsv1alpha1.LegacyRenderedTemplateSpec{ - ConfigTemplateExtension: appsv1alpha1.ConfigTemplateExtension{ + importedTemplate := &appsv1.LegacyRenderedTemplateSpec{ + ConfigTemplateExtension: appsv1.ConfigTemplateExtension{ Namespace: "default", TemplateRef: updatedCMObject.GetName(), - Policy: appsv1alpha1.ReplacePolicy, + Policy: appsv1.ReplacePolicy, }, } @@ -194,11 +193,11 @@ max_connections=666 Context("with only add Merge", func() { It("test mergerConfigTemplate add policy", func() { - importedTemplate := &appsv1alpha1.LegacyRenderedTemplateSpec{ - ConfigTemplateExtension: appsv1alpha1.ConfigTemplateExtension{ + importedTemplate := &appsv1.LegacyRenderedTemplateSpec{ + ConfigTemplateExtension: appsv1.ConfigTemplateExtension{ Namespace: "default", TemplateRef: updatedCMObject.GetName(), - Policy: appsv1alpha1.OnlyAddPolicy, + Policy: appsv1.OnlyAddPolicy, }, } @@ -210,11 +209,11 @@ max_connections=666 Context("with none Merge", func() { It("test mergerConfigTemplate none policy", func() { - importedTemplate := &appsv1alpha1.LegacyRenderedTemplateSpec{ - ConfigTemplateExtension: appsv1alpha1.ConfigTemplateExtension{ + importedTemplate := &appsv1.LegacyRenderedTemplateSpec{ + ConfigTemplateExtension: appsv1.ConfigTemplateExtension{ Namespace: "default", TemplateRef: updatedCMObject.GetName(), - Policy: appsv1alpha1.NoneMergePolicy, + Policy: appsv1.NoneMergePolicy, }, } @@ -227,8 +226,8 @@ max_connections=666 Context("failed test", func() { It("test mergerConfigTemplate function", func() { - importedTemplate := &appsv1alpha1.LegacyRenderedTemplateSpec{ - ConfigTemplateExtension: appsv1alpha1.ConfigTemplateExtension{ + importedTemplate := &appsv1.LegacyRenderedTemplateSpec{ + ConfigTemplateExtension: appsv1.ConfigTemplateExtension{ Namespace: "default", TemplateRef: updatedCMObject.GetName(), Policy: "", @@ -241,8 +240,8 @@ max_connections=666 }) It("not configconstraint", func() { - importedTemplate := &appsv1alpha1.LegacyRenderedTemplateSpec{ - ConfigTemplateExtension: appsv1alpha1.ConfigTemplateExtension{ + importedTemplate := &appsv1.LegacyRenderedTemplateSpec{ + ConfigTemplateExtension: appsv1.ConfigTemplateExtension{ Namespace: "default", TemplateRef: updatedCMObject.GetName(), Policy: "none", @@ -257,8 +256,8 @@ max_connections=666 }) It("not formatter", func() { - importedTemplate := &appsv1alpha1.LegacyRenderedTemplateSpec{ - ConfigTemplateExtension: appsv1alpha1.ConfigTemplateExtension{ + importedTemplate := &appsv1.LegacyRenderedTemplateSpec{ + ConfigTemplateExtension: appsv1.ConfigTemplateExtension{ Namespace: "default", TemplateRef: updatedCMObject.GetName(), Policy: "none", diff --git a/pkg/controller/configuration/template_wrapper.go b/pkg/controller/configuration/template_wrapper.go index 4daaf9e388d..49c819fa142 100644 --- a/pkg/controller/configuration/template_wrapper.go +++ b/pkg/controller/configuration/template_wrapper.go @@ -55,12 +55,12 @@ type renderWrapper struct { ctx context.Context cli client.Client - cluster *appsv1alpha1.Cluster + cluster *appsv1.Cluster component *appsv1.Component } func newTemplateRenderWrapper(ctx context.Context, cli client.Client, templateBuilder *configTemplateBuilder, - cluster *appsv1alpha1.Cluster, component *appsv1.Component) renderWrapper { + cluster *appsv1.Cluster, component *appsv1.Component) renderWrapper { return renderWrapper{ ctx: ctx, cli: cli, @@ -100,7 +100,7 @@ func (wrapper *renderWrapper) checkRerenderTemplateSpec(cfgCMName string, localO return cmObj, nil } -func (wrapper *renderWrapper) renderConfigTemplate(cluster *appsv1alpha1.Cluster, +func (wrapper *renderWrapper) renderConfigTemplate(cluster *appsv1.Cluster, component *component.SynthesizedComponent, localObjs []client.Object, configuration *appsv1alpha1.Configuration) error { revision := fromConfiguration(configuration) for _, configSpec := range component.ConfigTemplates { @@ -188,7 +188,7 @@ func applyUpdatedParameters(item *appsv1alpha1.ConfigurationItemDetail, cm *core return } -func (wrapper *renderWrapper) rerenderConfigTemplate(cluster *appsv1alpha1.Cluster, +func (wrapper *renderWrapper) rerenderConfigTemplate(cluster *appsv1.Cluster, component *component.SynthesizedComponent, configSpec appsv1.ComponentConfigSpec, item *appsv1alpha1.ConfigurationItemDetail, @@ -211,7 +211,7 @@ func (wrapper *renderWrapper) rerenderConfigTemplate(cluster *appsv1alpha1.Clust // render user specified template if item != nil && item.ImportTemplateRef != nil { newData, err := mergerConfigTemplate( - &appsv1alpha1.LegacyRenderedTemplateSpec{ + &appsv1.LegacyRenderedTemplateSpec{ ConfigTemplateExtension: *item.ImportTemplateRef, }, wrapper.templateBuilder, @@ -228,7 +228,7 @@ func (wrapper *renderWrapper) rerenderConfigTemplate(cluster *appsv1alpha1.Clust return newCMObj, nil } -func (wrapper *renderWrapper) renderScriptTemplate(cluster *appsv1alpha1.Cluster, component *component.SynthesizedComponent, +func (wrapper *renderWrapper) renderScriptTemplate(cluster *appsv1.Cluster, component *component.SynthesizedComponent, localObjs []client.Object) error { for _, templateSpec := range component.ScriptTemplates { cmName := core.GetComponentCfgName(cluster.Name, component.Name, templateSpec.Name) @@ -328,7 +328,7 @@ func UpdateCMConfigSpecLabels(cm *corev1.ConfigMap, configSpec appsv1.ComponentC } // generateConfigMapFromTpl renders config file by config template provided by provider. -func generateConfigMapFromTpl(cluster *appsv1alpha1.Cluster, +func generateConfigMapFromTpl(cluster *appsv1.Cluster, component *component.SynthesizedComponent, tplBuilder *configTemplateBuilder, cmName string, diff --git a/pkg/controller/configuration/template_wrapper_test.go b/pkg/controller/configuration/template_wrapper_test.go index 6c4cb5cf18a..120e63bd915 100644 --- a/pkg/controller/configuration/template_wrapper_test.go +++ b/pkg/controller/configuration/template_wrapper_test.go @@ -28,7 +28,6 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" appsv1beta1 "github.com/apecloud/kubeblocks/apis/apps/v1beta1" cfgcore "github.com/apecloud/kubeblocks/pkg/configuration/core" "github.com/apecloud/kubeblocks/pkg/constant" @@ -38,7 +37,7 @@ import ( var _ = Describe("TemplateWrapperTest", func() { var mockK8sCli *testutil.K8sClientMockHelper - var clusterObj *appsv1alpha1.Cluster + var clusterObj *appsv1.Cluster var componentObj *appsv1.Component var compDefObj *appsv1.ComponentDefinition var clusterComponent *component.SynthesizedComponent diff --git a/pkg/controller/configuration/tool_image_builder_test.go b/pkg/controller/configuration/tool_image_builder_test.go index 22546e32451..f6e24dadfb6 100644 --- a/pkg/controller/configuration/tool_image_builder_test.go +++ b/pkg/controller/configuration/tool_image_builder_test.go @@ -20,13 +20,12 @@ along with this program. If not, see . package configuration import ( - appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" corev1 "k8s.io/api/core/v1" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1beta1 "github.com/apecloud/kubeblocks/apis/apps/v1beta1" cfgcm "github.com/apecloud/kubeblocks/pkg/configuration/config_manager" "github.com/apecloud/kubeblocks/pkg/constant" @@ -39,7 +38,7 @@ var _ = Describe("ToolsImageBuilderTest", func() { const kbToolsImage = "apecloud/kubeblocks-tools:latest" var noneCommand = []string{"/bin/true"} - var clusterObj *appsv1alpha1.Cluster + var clusterObj *appsv1.Cluster var compDefObj *appsv1.ComponentDefinition var clusterComponent *component.SynthesizedComponent @@ -96,11 +95,11 @@ var _ = Describe("ToolsImageBuilderTest", func() { ConfigLazyRenderedVolumes: make(map[string]corev1.VolumeMount), } cfgManagerParams.ConfigSpecsBuildParams[0].ConfigSpec.VolumeName = "data" - cfgManagerParams.ConfigSpecsBuildParams[0].ConfigSpec.LegacyRenderedConfigSpec = &appsv1alpha1.LegacyRenderedTemplateSpec{ - ConfigTemplateExtension: appsv1alpha1.ConfigTemplateExtension{ + cfgManagerParams.ConfigSpecsBuildParams[0].ConfigSpec.LegacyRenderedConfigSpec = &appsv1.LegacyRenderedTemplateSpec{ + ConfigTemplateExtension: appsv1.ConfigTemplateExtension{ Namespace: testCtx.DefaultNamespace, TemplateRef: "secondary_template", - Policy: appsv1alpha1.NoneMergePolicy, + Policy: appsv1.NoneMergePolicy, }, } Expect(buildReloadToolsContainer(cfgManagerParams, &its.Spec.Template.Spec)).Should(Succeed()) diff --git a/pkg/controller/factory/builder.go b/pkg/controller/factory/builder.go index 3ce10972f1a..bafb54e7352 100644 --- a/pkg/controller/factory/builder.go +++ b/pkg/controller/factory/builder.go @@ -31,7 +31,6 @@ import ( "k8s.io/klog/v2" appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" appsv1beta1 "github.com/apecloud/kubeblocks/apis/apps/v1beta1" dpv1alpha1 "github.com/apecloud/kubeblocks/apis/dataprotection/v1alpha1" workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" @@ -244,7 +243,7 @@ func GetRestoreSystemAccountPassword(synthesizedComp *component.SynthesizedCompo return password } -func BuildPVC(cluster *appsv1alpha1.Cluster, +func BuildPVC(cluster *appsv1.Cluster, component *component.SynthesizedComponent, vct *corev1.PersistentVolumeClaimTemplate, pvcKey types.NamespacedName, @@ -272,7 +271,7 @@ func BuildPVC(cluster *appsv1alpha1.Cluster, return pvc } -func BuildBackup(cluster *appsv1alpha1.Cluster, +func BuildBackup(cluster *appsv1.Cluster, component *component.SynthesizedComponent, backupPolicyName string, backupKey types.NamespacedName, @@ -290,7 +289,7 @@ func BuildBackup(cluster *appsv1alpha1.Cluster, GetObject() } -func BuildConfigMapWithTemplate(cluster *appsv1alpha1.Cluster, +func BuildConfigMapWithTemplate(cluster *appsv1.Cluster, component *component.SynthesizedComponent, configs map[string]string, cmName string, @@ -383,7 +382,7 @@ func BuildVolumeSnapshotClass(name string, driver string) *snapshotv1.VolumeSnap GetObject() } -func BuildServiceAccount(cluster *appsv1alpha1.Cluster, saName string) *corev1.ServiceAccount { +func BuildServiceAccount(cluster *appsv1.Cluster, saName string) *corev1.ServiceAccount { // TODO(component): compName wellKnownLabels := constant.GetKBWellKnownLabels(cluster.Spec.ClusterDefRef, cluster.Name, "") return builder.NewServiceAccountBuilder(cluster.Namespace, saName). @@ -392,7 +391,7 @@ func BuildServiceAccount(cluster *appsv1alpha1.Cluster, saName string) *corev1.S GetObject() } -func BuildRoleBinding(cluster *appsv1alpha1.Cluster, saName string) *rbacv1.RoleBinding { +func BuildRoleBinding(cluster *appsv1.Cluster, saName string) *rbacv1.RoleBinding { // TODO(component): compName wellKnownLabels := constant.GetKBWellKnownLabels(cluster.Spec.ClusterDefRef, cluster.Name, "") return builder.NewRoleBindingBuilder(cluster.Namespace, saName). @@ -410,7 +409,7 @@ func BuildRoleBinding(cluster *appsv1alpha1.Cluster, saName string) *rbacv1.Role GetObject() } -func BuildClusterRoleBinding(cluster *appsv1alpha1.Cluster, saName string) *rbacv1.ClusterRoleBinding { +func BuildClusterRoleBinding(cluster *appsv1.Cluster, saName string) *rbacv1.ClusterRoleBinding { // TODO(component): compName wellKnownLabels := constant.GetKBWellKnownLabels(cluster.Spec.ClusterDefRef, cluster.Name, "") return builder.NewClusterRoleBindingBuilder(cluster.Namespace, saName). diff --git a/pkg/controller/factory/builder_test.go b/pkg/controller/factory/builder_test.go index 3167824ab60..fa88eb8e116 100644 --- a/pkg/controller/factory/builder_test.go +++ b/pkg/controller/factory/builder_test.go @@ -32,7 +32,6 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" appsv1beta1 "github.com/apecloud/kubeblocks/apis/apps/v1beta1" workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" cfgcm "github.com/apecloud/kubeblocks/pkg/configuration/config_manager" @@ -68,7 +67,7 @@ var _ = Describe("builder", func() { } } - newAllFieldsClusterObj := func(compDefObj *appsv1.ComponentDefinition, create bool) (*appsv1alpha1.Cluster, *appsv1.ComponentDefinition, types.NamespacedName) { + newAllFieldsClusterObj := func(compDefObj *appsv1.ComponentDefinition, create bool) (*appsv1.Cluster, *appsv1.ComponentDefinition, types.NamespacedName) { // setup Cluster obj requires default ComponentDefinition object if compDefObj == nil { compDefObj = allFieldsCompDefObj(create) @@ -117,7 +116,7 @@ var _ = Describe("builder", func() { return reqCtx } - newAllFieldsSynthesizedComponent := func(compDef *appsv1.ComponentDefinition, cluster *appsv1alpha1.Cluster) *component.SynthesizedComponent { + newAllFieldsSynthesizedComponent := func(compDef *appsv1.ComponentDefinition, cluster *appsv1.Cluster) *component.SynthesizedComponent { reqCtx := newReqCtx() By("assign every available fields") comp, err := component.BuildComponent(cluster, &cluster.Spec.ComponentSpecs[0], nil, nil) @@ -133,7 +132,7 @@ var _ = Describe("builder", func() { return synthesizeComp } - newClusterObjs := func(compDefObj *appsv1.ComponentDefinition) (*appsv1.ComponentDefinition, *appsv1alpha1.Cluster, *component.SynthesizedComponent) { + newClusterObjs := func(compDefObj *appsv1.ComponentDefinition) (*appsv1.ComponentDefinition, *appsv1.Cluster, *component.SynthesizedComponent) { cluster, compDef, _ := newAllFieldsClusterObj(compDefObj, false) synthesizedComponent := newAllFieldsSynthesizedComponent(compDef, cluster) return compDef, cluster, synthesizedComponent diff --git a/pkg/controller/job/job_utils.go b/pkg/controller/job/job_utils.go index c8ed0e9ca5c..e02d7c86244 100644 --- a/pkg/controller/job/job_utils.go +++ b/pkg/controller/job/job_utils.go @@ -29,7 +29,7 @@ import ( "k8s.io/apimachinery/pkg/types" "sigs.k8s.io/controller-runtime/pkg/client" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" "github.com/apecloud/kubeblocks/pkg/constant" intctrlutil "github.com/apecloud/kubeblocks/pkg/controllerutil" viper "github.com/apecloud/kubeblocks/pkg/viperx" @@ -45,7 +45,7 @@ var ( // GetJobWithLabels gets the job list with the specified labels. func GetJobWithLabels(ctx context.Context, cli client.Client, - cluster *appsv1alpha1.Cluster, + cluster *appsv1.Cluster, matchLabels client.MatchingLabels) ([]batchv1.Job, error) { jobList := &batchv1.JobList{} if err := cli.List(ctx, jobList, client.InNamespace(cluster.Namespace), matchLabels); err != nil { @@ -57,7 +57,7 @@ func GetJobWithLabels(ctx context.Context, // CleanJobWithLabels cleans up the job tasks with label. func CleanJobWithLabels(ctx context.Context, cli client.Client, - cluster *appsv1alpha1.Cluster, + cluster *appsv1.Cluster, matchLabels client.MatchingLabels) error { jobList, err := GetJobWithLabels(ctx, cli, cluster, matchLabels) if err != nil { @@ -76,7 +76,7 @@ func CleanJobWithLabels(ctx context.Context, // CleanJobByName cleans up the job task by name. func CleanJobByName(ctx context.Context, cli client.Client, - cluster *appsv1alpha1.Cluster, + cluster *appsv1.Cluster, jobName string) error { job := &batchv1.Job{} key := types.NamespacedName{Namespace: cluster.Namespace, Name: jobName} @@ -97,7 +97,7 @@ func CleanJobByName(ctx context.Context, // - error: any error that occurred during the handling func CheckJobSucceed(ctx context.Context, cli client.Reader, - cluster *appsv1alpha1.Cluster, + cluster *appsv1.Cluster, jobName string) error { key := types.NamespacedName{Namespace: cluster.Namespace, Name: jobName} currentJob := batchv1.Job{} @@ -122,7 +122,7 @@ func CheckJobSucceed(ctx context.Context, return intctrlutil.NewErrorf(intctrlutil.ErrorTypeExpectedInProcess, "requeue to waiting for job %s finished.", key.Name) } -func BuildJobTolerations(cluster *appsv1alpha1.Cluster, job *batchv1.Job) error { +func BuildJobTolerations(cluster *appsv1.Cluster, job *batchv1.Job) error { // build data plane tolerations from config var tolerations []corev1.Toleration if val := viper.GetString(constant.CfgKeyDataPlaneTolerations); val != "" { @@ -137,11 +137,6 @@ func BuildJobTolerations(cluster *appsv1alpha1.Cluster, job *batchv1.Job) error job.Spec.Template.Spec.Tolerations = tolerations } - // build job tolerations from legacy cluster.spec.Tolerations - if len(cluster.Spec.Tolerations) > 0 { - job.Spec.Template.Spec.Tolerations = append(job.Spec.Template.Spec.Tolerations, cluster.Spec.Tolerations...) - } - // build job tolerations from cluster.spec.SchedulingPolicy.Tolerations if cluster.Spec.SchedulingPolicy != nil && len(cluster.Spec.SchedulingPolicy.Tolerations) > 0 { job.Spec.Template.Spec.Tolerations = append(job.Spec.Template.Spec.Tolerations, cluster.Spec.SchedulingPolicy.Tolerations...) diff --git a/pkg/controller/job/job_utils_test.go b/pkg/controller/job/job_utils_test.go index 3e213bee0da..87ace4d8211 100644 --- a/pkg/controller/job/job_utils_test.go +++ b/pkg/controller/job/job_utils_test.go @@ -28,7 +28,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/client" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" "github.com/apecloud/kubeblocks/pkg/constant" testapps "github.com/apecloud/kubeblocks/pkg/testutil/apps" ) @@ -44,7 +44,7 @@ var _ = Describe("Job Utils Test", func() { ) var ( - cluster *appsv1alpha1.Cluster + cluster *appsv1.Cluster ) createJob := func(name string, keys ...string) *batchv1.Job { diff --git a/pkg/controller/plan/prepare.go b/pkg/controller/plan/prepare.go index 798f4d70b17..e24a26159e4 100644 --- a/pkg/controller/plan/prepare.go +++ b/pkg/controller/plan/prepare.go @@ -24,7 +24,6 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" "github.com/apecloud/kubeblocks/pkg/controller/component" "github.com/apecloud/kubeblocks/pkg/controller/configuration" ) @@ -32,7 +31,7 @@ import ( // RenderConfigNScriptFiles generates volumes for PodTemplate, volumeMount for container, rendered configTemplate and scriptTemplate, // and generates configManager sidecar for the reconfigure operation. func RenderConfigNScriptFiles(resourceCtx *configuration.ResourceCtx, - cluster *appsv1alpha1.Cluster, + cluster *appsv1.Cluster, component *appsv1.Component, synthesizedComponent *component.SynthesizedComponent, podSpec *corev1.PodSpec, diff --git a/pkg/controller/plan/prepare_test.go b/pkg/controller/plan/prepare_test.go index b58aa1078bf..61b22566344 100644 --- a/pkg/controller/plan/prepare_test.go +++ b/pkg/controller/plan/prepare_test.go @@ -27,7 +27,6 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" appsv1beta1 "github.com/apecloud/kubeblocks/apis/apps/v1beta1" cfgcore "github.com/apecloud/kubeblocks/pkg/configuration/core" "github.com/apecloud/kubeblocks/pkg/controller/component" @@ -71,7 +70,7 @@ var _ = Describe("Prepare Test", func() { var ( compDefObj *appsv1.ComponentDefinition - cluster *appsv1alpha1.Cluster + cluster *appsv1.Cluster comp *appsv1.Component configSpecName string ) diff --git a/pkg/controller/plan/restore.go b/pkg/controller/plan/restore.go index 45daea9e011..97c7b363370 100644 --- a/pkg/controller/plan/restore.go +++ b/pkg/controller/plan/restore.go @@ -50,7 +50,7 @@ import ( type RestoreManager struct { client.Client Ctx context.Context - Cluster *appsv1alpha1.Cluster + Cluster *appsv1.Cluster Scheme *k8sruntime.Scheme // private @@ -65,7 +65,7 @@ type RestoreManager struct { func NewRestoreManager(ctx context.Context, cli client.Client, - cluster *appsv1alpha1.Cluster, + cluster *appsv1.Cluster, scheme *k8sruntime.Scheme, restoreLabels map[string]string, replicas, startingIndex int32, @@ -104,7 +104,7 @@ func (r *RestoreManager) DoRestore(comp *component.SynthesizedComponent, compObj if !postProvisionDone { return nil } - if r.doReadyRestoreAfterClusterRunning && r.Cluster.Status.Phase != appsv1alpha1.RunningClusterPhase { + if r.doReadyRestoreAfterClusterRunning && r.Cluster.Status.Phase != appsv1.RunningClusterPhase { return nil } if err = r.DoPostReady(comp, compObj, backupObj); err != nil { @@ -169,7 +169,7 @@ func (r *RestoreManager) BuildPrepareDataRestore(comp *component.SynthesizedComp Name: clusterSpec.GetName(), UID: clusterSpec.GetUID(), } - clusterSpec.Status = appsv1alpha1.ClusterStatus{} + clusterSpec.Status = appsv1.ClusterStatus{} b, _ := json.Marshal(*clusterSpec) return string(b) } @@ -302,7 +302,7 @@ func (r *RestoreManager) buildRequiredPolicy(sourceTarget *dpv1alpha1.BackupStat func (r *RestoreManager) buildSchedulingSpec(comp *component.SynthesizedComponent) (dpv1alpha1.SchedulingSpec, error) { shardingName := comp.Labels[constant.KBAppShardingNameLabelKey] - var compSpec *appsv1alpha1.ClusterComponentSpec + var compSpec *appsv1.ClusterComponentSpec if shardingName != "" { compSpec = &r.Cluster.Spec.GetShardingByName(shardingName).Template } else { @@ -414,7 +414,7 @@ func (r *RestoreManager) cleanupRestoreAnnotations(compName string) error { return nil } -func CleanupClusterRestoreAnnotation(cluster *appsv1alpha1.Cluster, compName string) (bool, error) { +func CleanupClusterRestoreAnnotation(cluster *appsv1.Cluster, compName string) (bool, error) { restoreInfo := cluster.Annotations[constant.RestoreFromBackupAnnotationKey] if restoreInfo == "" { return false, nil diff --git a/pkg/controller/plan/restore_test.go b/pkg/controller/plan/restore_test.go index 64afb865250..e2c414133ff 100644 --- a/pkg/controller/plan/restore_test.go +++ b/pkg/controller/plan/restore_test.go @@ -101,7 +101,7 @@ var _ = Describe("Restore", func() { var ( compDef *appsv1.ComponentDefinition - cluster *appsv1alpha1.Cluster + cluster *appsv1.Cluster synthesizedComponent *component.SynthesizedComponent compObj *appsv1.Component pvc *corev1.PersistentVolumeClaim @@ -119,13 +119,6 @@ var _ = Describe("Restore", func() { cluster = testapps.NewClusterFactory(testCtx.DefaultNamespace, clusterName, ""). AddComponent(defaultCompName, compDefName). SetReplicas(3). - SetClusterAffinity(&appsv1alpha1.Affinity{ - PodAntiAffinity: appsv1alpha1.Required, - TopologyKeys: []string{topologyKey}, - NodeLabels: map[string]string{ - labelKey: labelValue, - }, - }). AddVolumeClaimTemplate(testapps.DataVolumeName, pvcSpec). Create(&testCtx).GetObject() @@ -218,7 +211,7 @@ var _ = Describe("Restore", func() { It("Test restore", func() { By("restore from backup") restoreFromBackup := fmt.Sprintf(`{"%s": {"name":"%s"}}`, defaultCompName, backup.Name) - Expect(testapps.ChangeObj(&testCtx, cluster, func(tmpCluster *appsv1alpha1.Cluster) { + Expect(testapps.ChangeObj(&testCtx, cluster, func(tmpCluster *appsv1.Cluster) { tmpCluster.Annotations = map[string]string{ constant.RestoreFromBackupAnnotationKey: restoreFromBackup, } @@ -237,10 +230,10 @@ var _ = Describe("Restore", func() { By("mock component and cluster phase to Running") Expect(testapps.ChangeObjStatus(&testCtx, cluster, func() { - cluster.Status.Phase = appsv1alpha1.RunningClusterPhase - cluster.Status.Components = map[string]appsv1alpha1.ClusterComponentStatus{ + cluster.Status.Phase = appsv1.RunningClusterPhase + cluster.Status.Components = map[string]appsv1.ClusterComponentStatus{ defaultCompName: { - Phase: appsv1alpha1.RunningClusterCompPhase, + Phase: appsv1.RunningClusterCompPhase, }, } })).Should(Succeed()) @@ -264,7 +257,7 @@ var _ = Describe("Restore", func() { By("clean up annotations after cluster running") _ = restoreMGR.DoRestore(synthesizedComponent, compObj, true) - Eventually(testapps.CheckObj(&testCtx, client.ObjectKeyFromObject(cluster), func(g Gomega, tmpCluster *appsv1alpha1.Cluster) { + Eventually(testapps.CheckObj(&testCtx, client.ObjectKeyFromObject(cluster), func(g Gomega, tmpCluster *appsv1.Cluster) { g.Expect(tmpCluster.Annotations[constant.RestoreFromBackupAnnotationKey]).Should(BeEmpty()) })).Should(Succeed()) }) diff --git a/pkg/controller/scheduling/scheduling_utils.go b/pkg/controller/scheduling/scheduling_utils.go index 898babf5f04..c0f6e69dc6e 100644 --- a/pkg/controller/scheduling/scheduling_utils.go +++ b/pkg/controller/scheduling/scheduling_utils.go @@ -21,32 +21,22 @@ package scheduling import ( "encoding/json" - "sort" - "strings" - "golang.org/x/exp/maps" corev1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" "github.com/apecloud/kubeblocks/pkg/constant" viper "github.com/apecloud/kubeblocks/pkg/viperx" ) -func BuildSchedulingPolicy(cluster *appsv1alpha1.Cluster, compSpec *appsv1alpha1.ClusterComponentSpec) (*appsv1.SchedulingPolicy, error) { +func BuildSchedulingPolicy(cluster *appsv1.Cluster, compSpec *appsv1.ClusterComponentSpec) (*appsv1.SchedulingPolicy, error) { if cluster.Spec.SchedulingPolicy != nil || (compSpec != nil && compSpec.SchedulingPolicy != nil) { return buildSchedulingPolicy(cluster, compSpec) } - return buildSchedulingPolicy4Legacy(cluster, compSpec) + return nil, nil } -func BuildSchedulingPolicy4Component(clusterName, compName string, affinity *appsv1alpha1.Affinity, - tolerations []corev1.Toleration) (*appsv1.SchedulingPolicy, error) { - return buildSchedulingPolicy4LegacyComponent(clusterName, compName, affinity, tolerations) -} - -func buildSchedulingPolicy(cluster *appsv1alpha1.Cluster, compSpec *appsv1alpha1.ClusterComponentSpec) (*appsv1.SchedulingPolicy, error) { +func buildSchedulingPolicy(cluster *appsv1.Cluster, compSpec *appsv1.ClusterComponentSpec) (*appsv1.SchedulingPolicy, error) { schedulingPolicy := cluster.Spec.SchedulingPolicy if compSpec != nil && compSpec.SchedulingPolicy != nil { schedulingPolicy = compSpec.SchedulingPolicy @@ -82,170 +72,7 @@ func buildSchedulingPolicy(cluster *appsv1alpha1.Cluster, compSpec *appsv1alpha1 if err := mergeGlobalTolerations(); err != nil { return nil, err } - return toV1SchedulingPolicy(schedulingPolicy), nil -} - -func toV1SchedulingPolicy(schedulingPolicy *appsv1alpha1.SchedulingPolicy) *appsv1.SchedulingPolicy { - if schedulingPolicy != nil { - return &appsv1.SchedulingPolicy{ - SchedulerName: schedulingPolicy.SchedulerName, - NodeSelector: schedulingPolicy.NodeSelector, - NodeName: schedulingPolicy.NodeName, - Affinity: schedulingPolicy.Affinity, - Tolerations: schedulingPolicy.Tolerations, - TopologySpreadConstraints: schedulingPolicy.TopologySpreadConstraints, - } - } - return nil -} - -func buildSchedulingPolicy4Legacy(cluster *appsv1alpha1.Cluster, compSpec *appsv1alpha1.ClusterComponentSpec) (*appsv1.SchedulingPolicy, error) { - affinity := buildAffinity4Legacy(cluster, compSpec) - tolerations, err := buildTolerations4Legacy(cluster, compSpec) - if err != nil { - return nil, err - } - return buildSchedulingPolicy4LegacyComponent(cluster.Name, compSpec.Name, affinity, tolerations) -} - -func buildSchedulingPolicy4LegacyComponent(clusterName, compName string, affinity *appsv1alpha1.Affinity, - tolerations []corev1.Toleration) (*appsv1.SchedulingPolicy, error) { - podAffinity, err := buildPodAffinity4Legacy(clusterName, compName, affinity) - if err != nil { - return nil, err - } - return &appsv1.SchedulingPolicy{ - Affinity: podAffinity, - Tolerations: tolerations, - TopologySpreadConstraints: buildPodTopologySpreadConstraints4Legacy(clusterName, compName, affinity), - }, nil -} - -func buildAffinity4Legacy(cluster *appsv1alpha1.Cluster, compSpec *appsv1alpha1.ClusterComponentSpec) *appsv1alpha1.Affinity { - var affinity *appsv1alpha1.Affinity - if cluster.Spec.Affinity != nil { - affinity = cluster.Spec.Affinity - } - if compSpec != nil && compSpec.Affinity != nil { - affinity = compSpec.Affinity - } - return affinity -} - -func buildTolerations4Legacy(cluster *appsv1alpha1.Cluster, compSpec *appsv1alpha1.ClusterComponentSpec) ([]corev1.Toleration, error) { - tolerations := cluster.Spec.Tolerations - if compSpec != nil && len(compSpec.Tolerations) != 0 { - tolerations = compSpec.Tolerations - } - dpTolerations, err := buildClusterWideTolerations() - if err != nil { - return nil, err - } - return append(tolerations, dpTolerations...), nil -} - -func buildPodTopologySpreadConstraints4Legacy(clusterName, compName string, compAffinity *appsv1alpha1.Affinity) []corev1.TopologySpreadConstraint { - if compAffinity == nil { - return nil - } - - var topologySpreadConstraints []corev1.TopologySpreadConstraint - - var whenUnsatisfiable corev1.UnsatisfiableConstraintAction - if compAffinity.PodAntiAffinity == appsv1alpha1.Required { - whenUnsatisfiable = corev1.DoNotSchedule - } else { - whenUnsatisfiable = corev1.ScheduleAnyway - } - for _, topologyKey := range compAffinity.TopologyKeys { - topologySpreadConstraints = append(topologySpreadConstraints, corev1.TopologySpreadConstraint{ - MaxSkew: 1, - WhenUnsatisfiable: whenUnsatisfiable, - TopologyKey: topologyKey, - LabelSelector: &metav1.LabelSelector{ - MatchLabels: map[string]string{ - constant.AppInstanceLabelKey: clusterName, - constant.KBAppComponentLabelKey: compName, - }, - }, - }) - } - return topologySpreadConstraints -} - -func buildPodAffinity4Legacy(clusterName string, compName string, compAffinity *appsv1alpha1.Affinity) (*corev1.Affinity, error) { - affinity := buildNewAffinity4Legacy(clusterName, compName, compAffinity) - dpAffinity, err := buildClusterWideAffinity() - if err != nil { - return nil, err - } - return mergeAffinity(affinity, dpAffinity), nil -} - -func buildNewAffinity4Legacy(clusterName, compName string, compAffinity *appsv1alpha1.Affinity) *corev1.Affinity { - if compAffinity == nil { - return nil - } - affinity := new(corev1.Affinity) - // Build NodeAffinity - var matchExpressions []corev1.NodeSelectorRequirement - nodeLabelKeys := maps.Keys(compAffinity.NodeLabels) - // NodeLabels must be ordered - sort.Strings(nodeLabelKeys) - for _, key := range nodeLabelKeys { - values := strings.Split(compAffinity.NodeLabels[key], ",") - matchExpressions = append(matchExpressions, corev1.NodeSelectorRequirement{ - Key: key, - Operator: corev1.NodeSelectorOpIn, - Values: values, - }) - } - if len(matchExpressions) > 0 { - nodeSelectorTerm := corev1.NodeSelectorTerm{ - MatchExpressions: matchExpressions, - } - affinity.NodeAffinity = &corev1.NodeAffinity{ - RequiredDuringSchedulingIgnoredDuringExecution: &corev1.NodeSelector{ - NodeSelectorTerms: []corev1.NodeSelectorTerm{nodeSelectorTerm}, - }, - } - } - // Build PodAntiAffinity - var podAntiAffinity *corev1.PodAntiAffinity - var podAffinityTerms []corev1.PodAffinityTerm - for _, topologyKey := range compAffinity.TopologyKeys { - podAffinityTerms = append(podAffinityTerms, corev1.PodAffinityTerm{ - TopologyKey: topologyKey, - LabelSelector: &metav1.LabelSelector{ - MatchLabels: map[string]string{ - constant.AppInstanceLabelKey: clusterName, - constant.KBAppComponentLabelKey: compName, - }, - }, - }) - } - if compAffinity.PodAntiAffinity == appsv1alpha1.Required { - podAntiAffinity = &corev1.PodAntiAffinity{ - RequiredDuringSchedulingIgnoredDuringExecution: podAffinityTerms, - } - } else { - var weightedPodAffinityTerms []corev1.WeightedPodAffinityTerm - for _, podAffinityTerm := range podAffinityTerms { - weightedPodAffinityTerms = append(weightedPodAffinityTerms, corev1.WeightedPodAffinityTerm{ - Weight: 100, - PodAffinityTerm: podAffinityTerm, - }) - } - podAntiAffinity = &corev1.PodAntiAffinity{ - PreferredDuringSchedulingIgnoredDuringExecution: weightedPodAffinityTerms, - } - } - // Add pod PodAffinityTerm for dedicated node - // if compAffinity.Tenancy == appsv1alpha1.DedicatedNode { - // // TODO(v1.0): workload type has been removed - // } - affinity.PodAntiAffinity = podAntiAffinity - return affinity + return schedulingPolicy, nil } // buildClusterWideAffinity builds data plane affinity from global config diff --git a/pkg/controller/scheduling/scheduling_utils_test.go b/pkg/controller/scheduling/scheduling_utils_test.go deleted file mode 100644 index effe72347e1..00000000000 --- a/pkg/controller/scheduling/scheduling_utils_test.go +++ /dev/null @@ -1,169 +0,0 @@ -/* -Copyright (C) 2022-2024 ApeCloud Co., Ltd - -This file is part of KubeBlocks project - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Affero General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Affero General Public License for more details. - -You should have received a copy of the GNU Affero General Public License -along with this program. If not, see . -*/ - -package scheduling - -import ( - "fmt" - - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - - corev1 "k8s.io/api/core/v1" - - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" - "github.com/apecloud/kubeblocks/pkg/constant" - testapps "github.com/apecloud/kubeblocks/pkg/testutil/apps" - viper "github.com/apecloud/kubeblocks/pkg/viperx" -) - -var _ = Describe("affinity utils", func() { - const ( - clusterName = "test-cluster" - compName = "test-comp" - clusterTolerationKey = "test-clusterTolerationKey" - topologyKey = "test-topologyKey" - labelKey = "test-nodeLabelKey" - labelValue = "test-labelValue" - nodeKey = "test-nodeKey" - ) - - var ( - clusterObj *appsv1alpha1.Cluster - compSpec *appsv1alpha1.ClusterComponentSpec - - buildObjs = func(podAntiAffinity appsv1alpha1.PodAntiAffinity) { - affinity := &appsv1alpha1.Affinity{ - PodAntiAffinity: podAntiAffinity, - TopologyKeys: []string{topologyKey}, - NodeLabels: map[string]string{ - labelKey: labelValue, - }, - } - toleration := corev1.Toleration{ - Key: clusterTolerationKey, - Operator: corev1.TolerationOpExists, - Effect: corev1.TaintEffectNoExecute, - } - - clusterObj = testapps.NewClusterFactory("default", clusterName, ""). - AddComponent(compName, ""). - SetClusterAffinity(affinity). - AddClusterToleration(toleration). - GetObject() - compSpec = &clusterObj.Spec.ComponentSpecs[0] - } - ) - - Context("with PodAntiAffinity set to Required", func() { - BeforeEach(func() { - buildObjs(appsv1alpha1.Required) - }) - - It("should have correct Affinity and TopologySpreadConstraints", func() { - schedulingPolicy, err := BuildSchedulingPolicy(clusterObj, compSpec) - Expect(err).Should(Succeed()) - Expect(schedulingPolicy).ShouldNot(BeNil()) - - affinity := schedulingPolicy.Affinity - Expect(affinity.NodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution.NodeSelectorTerms[0].MatchExpressions[0].Key).Should(Equal(labelKey)) - Expect(affinity.PodAntiAffinity.RequiredDuringSchedulingIgnoredDuringExecution[0].TopologyKey).Should(Equal(topologyKey)) - Expect(affinity.PodAntiAffinity.PreferredDuringSchedulingIgnoredDuringExecution).Should(BeEmpty()) - Expect(affinity.NodeAffinity.PreferredDuringSchedulingIgnoredDuringExecution).Should(BeEmpty()) - - topologySpreadConstraints := schedulingPolicy.TopologySpreadConstraints - Expect(topologySpreadConstraints[0].WhenUnsatisfiable).Should(Equal(corev1.DoNotSchedule)) - Expect(topologySpreadConstraints[0].TopologyKey).Should(Equal(topologyKey)) - }) - - It("when data plane affinity is set, should have correct Affinity and TopologySpreadConstraints", func() { - viper.Set(constant.CfgKeyDataPlaneAffinity, - fmt.Sprintf("{\"nodeAffinity\":{\"preferredDuringSchedulingIgnoredDuringExecution\":[{\"preference\":{\"matchExpressions\":[{\"key\":\"%s\",\"operator\":\"In\",\"values\":[\"true\"]}]},\"weight\":100}]}}", nodeKey)) - defer viper.Set(constant.CfgKeyDataPlaneAffinity, "") - - schedulingPolicy, err := BuildSchedulingPolicy(clusterObj, compSpec) - Expect(err).Should(Succeed()) - Expect(schedulingPolicy).ShouldNot(BeNil()) - - affinity := schedulingPolicy.Affinity - Expect(affinity.NodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution.NodeSelectorTerms[0].MatchExpressions[0].Key).Should(Equal(labelKey)) - Expect(affinity.PodAntiAffinity.RequiredDuringSchedulingIgnoredDuringExecution[0].TopologyKey).Should(Equal(topologyKey)) - Expect(affinity.PodAntiAffinity.PreferredDuringSchedulingIgnoredDuringExecution).Should(BeEmpty()) - Expect(affinity.NodeAffinity.PreferredDuringSchedulingIgnoredDuringExecution[0].Preference.MatchExpressions[0].Key).Should(Equal(nodeKey)) - - topologySpreadConstraints := schedulingPolicy.TopologySpreadConstraints - Expect(topologySpreadConstraints[0].WhenUnsatisfiable).Should(Equal(corev1.DoNotSchedule)) - Expect(topologySpreadConstraints[0].TopologyKey).Should(Equal(topologyKey)) - }) - }) - - Context("with PodAntiAffinity set to Preferred", func() { - BeforeEach(func() { - buildObjs(appsv1alpha1.Preferred) - }) - - It("should have correct Affinity and TopologySpreadConstraints", func() { - schedulingPolicy, err := BuildSchedulingPolicy(clusterObj, compSpec) - Expect(err).Should(Succeed()) - Expect(schedulingPolicy).ShouldNot(BeNil()) - - affinity := schedulingPolicy.Affinity - Expect(err).Should(Succeed()) - Expect(affinity.NodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution.NodeSelectorTerms[0].MatchExpressions[0].Key).Should(Equal(labelKey)) - Expect(affinity.PodAntiAffinity.RequiredDuringSchedulingIgnoredDuringExecution).Should(BeEmpty()) - Expect(affinity.PodAntiAffinity.PreferredDuringSchedulingIgnoredDuringExecution[0].Weight).ShouldNot(BeNil()) - Expect(affinity.PodAntiAffinity.PreferredDuringSchedulingIgnoredDuringExecution[0].PodAffinityTerm.TopologyKey).Should(Equal(topologyKey)) - - topologySpreadConstraints := schedulingPolicy.TopologySpreadConstraints - Expect(topologySpreadConstraints[0].WhenUnsatisfiable).Should(Equal(corev1.ScheduleAnyway)) - Expect(topologySpreadConstraints[0].TopologyKey).Should(Equal(topologyKey)) - }) - }) - - Context("with tolerations", func() { - BeforeEach(func() { - buildObjs(appsv1alpha1.Required) - }) - - It("should have correct tolerations", func() { - schedulingPolicy, err := BuildSchedulingPolicy(clusterObj, compSpec) - Expect(err).Should(Succeed()) - Expect(schedulingPolicy).ShouldNot(BeNil()) - - tolerations := schedulingPolicy.Tolerations - Expect(tolerations).ShouldNot(BeEmpty()) - Expect(tolerations[0].Key).Should(Equal(clusterTolerationKey)) - }) - - It("when data plane tolerations is set, should have correct tolerations", func() { - const dpTolerationKey = "dataPlaneTolerationKey" - viper.Set(constant.CfgKeyDataPlaneTolerations, fmt.Sprintf("[{\"key\":\"%s\", \"operator\": \"Exists\", \"effect\": \"NoSchedule\"}]", dpTolerationKey)) - defer viper.Set(constant.CfgKeyDataPlaneTolerations, "") - - schedulingPolicy, err := BuildSchedulingPolicy(clusterObj, compSpec) - Expect(err).Should(Succeed()) - Expect(schedulingPolicy).ShouldNot(BeNil()) - - tolerations := schedulingPolicy.Tolerations - Expect(tolerations).Should(HaveLen(2)) - Expect(tolerations[0].Key).Should(Equal(clusterTolerationKey)) - Expect(tolerations[1].Key).Should(Equal(dpTolerationKey)) - }) - }) -}) diff --git a/pkg/controller/scheduling/suite_test.go b/pkg/controller/scheduling/suite_test.go deleted file mode 100644 index 7921603833c..00000000000 --- a/pkg/controller/scheduling/suite_test.go +++ /dev/null @@ -1,91 +0,0 @@ -/* -Copyright (C) 2022-2024 ApeCloud Co., Ltd - -This file is part of KubeBlocks project - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Affero General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Affero General Public License for more details. - -You should have received a copy of the GNU Affero General Public License -along with this program. If not, see . -*/ - -package scheduling - -import ( - "context" - "path/filepath" - "testing" - - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - - "github.com/go-logr/logr" - "go.uber.org/zap/zapcore" - "k8s.io/client-go/rest" - "sigs.k8s.io/controller-runtime/pkg/envtest" - logf "sigs.k8s.io/controller-runtime/pkg/log" - "sigs.k8s.io/controller-runtime/pkg/log/zap" - - viper "github.com/apecloud/kubeblocks/pkg/viperx" -) - -// These tests use Ginkgo (BDD-style Go testing framework). Refer to -// http://onsi.github.io/ginkgo/ to learn more about Ginkgo. - -var cfg *rest.Config -var env *envtest.Environment -var ctx context.Context -var logger logr.Logger - -func init() { - viper.AutomaticEnv() -} - -func TestAPIs(t *testing.T) { - RegisterFailHandler(Fail) - - RunSpecs(t, "Controller Suite") -} - -var _ = BeforeSuite(func() { - if viper.GetBool("ENABLE_DEBUG_LOG") { - logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true), func(o *zap.Options) { - o.TimeEncoder = zapcore.ISO8601TimeEncoder - })) - } - - logger = logf.FromContext(ctx).WithValues() - logger.Info("logger start") - - By("bootstrapping test environment") - env = &envtest.Environment{ - CRDDirectoryPaths: []string{ - filepath.Join("..", "..", "..", "config", "crd", "bases"), - // use dependent external CRDs. - // resolved by ref: https://github.com/operator-framework/operator-sdk/issues/4434#issuecomment-786794418 - // filepath.Join(build.Default.GOPATH, "pkg", "mod", "github.com", "kubernetes-csi/external-snapshotter/", - // "client/v6@v6.2.0", "config", "crd"), - }, - ErrorIfCRDPathMissing: true, - } - - var err error - // cfg is defined in this file globally. - cfg, err = env.Start() - Expect(err).NotTo(HaveOccurred()) - Expect(cfg).NotTo(BeNil()) -}) - -var _ = AfterSuite(func() { - By("tearing down the test environment") - err := env.Stop() - Expect(err).NotTo(HaveOccurred()) -}) diff --git a/pkg/controllerutil/cluster_utils.go b/pkg/controllerutil/cluster_utils.go index 16b97d9c06c..4fc29e59fd2 100644 --- a/pkg/controllerutil/cluster_utils.go +++ b/pkg/controllerutil/cluster_utils.go @@ -24,12 +24,12 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" ) // GetOriginalOrGeneratedComponentSpecByName get an original or generated cluster component spec by componentName. func GetOriginalOrGeneratedComponentSpecByName(ctx context.Context, cli client.Reader, - cluster *appsv1alpha1.Cluster, componentName string) (*appsv1alpha1.ClusterComponentSpec, error) { + cluster *appsv1.Cluster, componentName string) (*appsv1.ClusterComponentSpec, error) { compSpec := cluster.Spec.GetComponentByName(componentName) if compSpec != nil { return compSpec, nil diff --git a/pkg/controllerutil/cluster_utils_test.go b/pkg/controllerutil/cluster_utils_test.go index 107c79b9b56..dff16d0fc3b 100644 --- a/pkg/controllerutil/cluster_utils_test.go +++ b/pkg/controllerutil/cluster_utils_test.go @@ -25,7 +25,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" "github.com/apecloud/kubeblocks/pkg/constant" "github.com/apecloud/kubeblocks/pkg/generics" testapps "github.com/apecloud/kubeblocks/pkg/testutil/apps" @@ -63,7 +63,7 @@ var _ = Describe("cluster utils test", func() { ) var ( - cluster *appsv1alpha1.Cluster + cluster *appsv1.Cluster ) BeforeEach(func() { @@ -97,7 +97,7 @@ var _ = Describe("cluster utils test", func() { Create(&testCtx). GetObject() compKey := client.ObjectKeyFromObject(mockCompObj) - Eventually(testapps.CheckObjExists(&testCtx, compKey, &appsv1alpha1.Component{}, true)).Should(Succeed()) + Eventually(testapps.CheckObjExists(&testCtx, compKey, &appsv1.Component{}, true)).Should(Succeed()) compSpec, err = GetOriginalOrGeneratedComponentSpecByName(testCtx.Ctx, k8sClient, cluster, mysqlShardingCompName) Expect(err).ShouldNot(HaveOccurred()) diff --git a/pkg/controllerutil/controller_common.go b/pkg/controllerutil/controller_common.go index dd595de7fe9..450c8a6010e 100644 --- a/pkg/controllerutil/controller_common.go +++ b/pkg/controllerutil/controller_common.go @@ -41,7 +41,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" "sigs.k8s.io/controller-runtime/pkg/reconcile" - "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" "github.com/apecloud/kubeblocks/pkg/constant" viper "github.com/apecloud/kubeblocks/pkg/viperx" ) @@ -134,9 +134,9 @@ func HandleCRDeletion(reqCtx RequestCtx, // If the resource has dependencies, it will not be automatically deleted. // It can also prevent users from manually deleting it without event records if reqCtx.Recorder != nil { - cluster, ok := cr.(*v1alpha1.Cluster) + cluster, ok := cr.(*appsv1.Cluster) // throw warning event if terminationPolicy set to DoNotTerminate - if ok && cluster.Spec.TerminationPolicy == v1alpha1.DoNotTerminate { + if ok && cluster.Spec.TerminationPolicy == appsv1.DoNotTerminate { reqCtx.Eventf(cr, corev1.EventTypeWarning, constant.ReasonDeleteFailed, "Deleting %s: %s failed due to terminationPolicy set to DoNotTerminate", strings.ToLower(cr.GetObjectKind().GroupVersionKind().Kind), cr.GetName()) diff --git a/pkg/controllerutil/sharding_utils.go b/pkg/controllerutil/sharding_utils.go index 390f49a62e5..b33f2f1af21 100644 --- a/pkg/controllerutil/sharding_utils.go +++ b/pkg/controllerutil/sharding_utils.go @@ -28,7 +28,6 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" "github.com/apecloud/kubeblocks/pkg/common" "github.com/apecloud/kubeblocks/pkg/constant" ) @@ -38,8 +37,8 @@ const ( ) func GenShardingCompSpecList(ctx context.Context, cli client.Reader, - cluster *appsv1alpha1.Cluster, shardingSpec *appsv1alpha1.ShardingSpec) ([]*appsv1alpha1.ClusterComponentSpec, error) { - compSpecList := make([]*appsv1alpha1.ClusterComponentSpec, 0) + cluster *appsv1.Cluster, shardingSpec *appsv1.ShardingSpec) ([]*appsv1.ClusterComponentSpec, error) { + compSpecList := make([]*appsv1.ClusterComponentSpec, 0) // list undeleted sharding component specs, the deleting ones are not included undeletedShardingCompSpecs, err := listUndeletedShardingCompSpecs(ctx, cli, cluster, shardingSpec) if err != nil { @@ -74,14 +73,14 @@ func GenShardingCompSpecList(ctx context.Context, cli client.Reader, // listNCheckShardingComponents lists sharding components and checks if the sharding components are correct. It returns undeleted and deleting sharding components. func listNCheckShardingComponents(ctx context.Context, cli client.Reader, - cluster *appsv1alpha1.Cluster, shardingSpec *appsv1alpha1.ShardingSpec) ([]appsv1alpha1.Component, []appsv1alpha1.Component, error) { + cluster *appsv1.Cluster, shardingSpec *appsv1.ShardingSpec) ([]appsv1.Component, []appsv1.Component, error) { shardingComps, err := ListShardingComponents(ctx, cli, cluster, shardingSpec.Name) if err != nil { return nil, nil, err } - deletingShardingComps := make([]appsv1alpha1.Component, 0) - undeletedShardingComps := make([]appsv1alpha1.Component, 0) + deletingShardingComps := make([]appsv1.Component, 0) + undeletedShardingComps := make([]appsv1.Component, 0) for _, comp := range shardingComps { if comp.GetDeletionTimestamp().IsZero() { undeletedShardingComps = append(undeletedShardingComps, comp) @@ -98,7 +97,7 @@ func listNCheckShardingComponents(ctx context.Context, cli client.Reader, } func ListShardingComponents(ctx context.Context, cli client.Reader, - cluster *appsv1alpha1.Cluster, shardingName string) ([]appsv1.Component, error) { + cluster *appsv1.Cluster, shardingName string) ([]appsv1.Component, error) { compList := &appsv1.ComponentList{} ml := client.MatchingLabels{ constant.AppInstanceLabelKey: cluster.Name, @@ -111,17 +110,17 @@ func ListShardingComponents(ctx context.Context, cli client.Reader, } // listUndeletedShardingCompSpecs lists undeleted sharding component specs. -func listUndeletedShardingCompSpecs(ctx context.Context, cli client.Reader, cluster *appsv1alpha1.Cluster, shardingSpec *appsv1alpha1.ShardingSpec) ([]*appsv1alpha1.ClusterComponentSpec, error) { +func listUndeletedShardingCompSpecs(ctx context.Context, cli client.Reader, cluster *appsv1.Cluster, shardingSpec *appsv1.ShardingSpec) ([]*appsv1.ClusterComponentSpec, error) { return listShardingCompSpecs(ctx, cli, cluster, shardingSpec, false) } // listAllShardingCompSpecs lists all sharding component specs, including undeleted and deleting ones. -func listAllShardingCompSpecs(ctx context.Context, cli client.Reader, cluster *appsv1alpha1.Cluster, shardingSpec *appsv1alpha1.ShardingSpec) ([]*appsv1alpha1.ClusterComponentSpec, error) { +func listAllShardingCompSpecs(ctx context.Context, cli client.Reader, cluster *appsv1.Cluster, shardingSpec *appsv1.ShardingSpec) ([]*appsv1.ClusterComponentSpec, error) { return listShardingCompSpecs(ctx, cli, cluster, shardingSpec, true) } // listShardingCompSpecs lists sharding component specs, with an option to include those marked for deletion. -func listShardingCompSpecs(ctx context.Context, cli client.Reader, cluster *appsv1alpha1.Cluster, shardingSpec *appsv1alpha1.ShardingSpec, includeDeleting bool) ([]*appsv1alpha1.ClusterComponentSpec, error) { +func listShardingCompSpecs(ctx context.Context, cli client.Reader, cluster *appsv1.Cluster, shardingSpec *appsv1.ShardingSpec, includeDeleting bool) ([]*appsv1.ClusterComponentSpec, error) { if shardingSpec == nil { return nil, nil } @@ -131,10 +130,10 @@ func listShardingCompSpecs(ctx context.Context, cli client.Reader, cluster *apps return nil, err } - compSpecList := make([]*appsv1alpha1.ClusterComponentSpec, 0, len(undeletedShardingComps)+len(deletingShardingComps)) + compSpecList := make([]*appsv1.ClusterComponentSpec, 0, len(undeletedShardingComps)+len(deletingShardingComps)) shardTpl := shardingSpec.Template - processComps := func(comps []appsv1alpha1.Component) error { + processComps := func(comps []appsv1.Component) error { for _, comp := range comps { compShortName, err := parseCompShortName(cluster.Name, comp.Name) if err != nil { diff --git a/pkg/controllerutil/sharding_utils_test.go b/pkg/controllerutil/sharding_utils_test.go index 6d98ca93a90..b576072ac02 100644 --- a/pkg/controllerutil/sharding_utils_test.go +++ b/pkg/controllerutil/sharding_utils_test.go @@ -25,7 +25,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" "github.com/apecloud/kubeblocks/pkg/constant" "github.com/apecloud/kubeblocks/pkg/generics" testapps "github.com/apecloud/kubeblocks/pkg/testutil/apps" @@ -63,7 +63,7 @@ var _ = Describe("cluster shard component", func() { ) var ( - cluster *appsv1alpha1.Cluster + cluster *appsv1.Cluster ) BeforeEach(func() { @@ -88,10 +88,10 @@ var _ = Describe("cluster shard component", func() { Create(&testCtx). GetObject() compKey := client.ObjectKeyFromObject(mockCompObj) - Eventually(testapps.CheckObjExists(&testCtx, compKey, &appsv1alpha1.Component{}, true)).Should(Succeed()) + Eventually(testapps.CheckObjExists(&testCtx, compKey, &appsv1.Component{}, true)).Should(Succeed()) - shardingSpec := &appsv1alpha1.ShardingSpec{ - Template: appsv1alpha1.ClusterComponentSpec{ + shardingSpec := &appsv1.ShardingSpec{ + Template: appsv1.ClusterComponentSpec{ Replicas: 2, }, Name: mysqlShardingName, diff --git a/pkg/controllerutil/util.go b/pkg/controllerutil/util.go index a1c5f734555..53db5ee6474 100644 --- a/pkg/controllerutil/util.go +++ b/pkg/controllerutil/util.go @@ -35,6 +35,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" "github.com/apecloud/kubeblocks/pkg/constant" "github.com/apecloud/kubeblocks/pkg/generics" @@ -64,7 +65,7 @@ func GetUncachedObjects() []client.Object { // avoid to cache potential large data objects &corev1.ConfigMap{}, &corev1.Secret{}, - &appsv1alpha1.Cluster{}, + &appsv1.Cluster{}, &appsv1alpha1.Configuration{}, } } @@ -141,7 +142,7 @@ func MergeMetadataMaps(originalMap map[string]string, targetMaps ...map[string]s return mergeMap } -var innerScheme, _ = appsv1alpha1.SchemeBuilder.Build() +var innerScheme, _ = appsv1.SchemeBuilder.Build() func SetOwnerReference(owner, object metav1.Object) error { return controllerutil.SetOwnerReference(owner, object, innerScheme) diff --git a/pkg/dataprotection/backup/scheduler.go b/pkg/dataprotection/backup/scheduler.go index d47f6443dee..8aea4543ebf 100644 --- a/pkg/dataprotection/backup/scheduler.go +++ b/pkg/dataprotection/backup/scheduler.go @@ -33,6 +33,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" dpv1alpha1 "github.com/apecloud/kubeblocks/apis/dataprotection/v1alpha1" "github.com/apecloud/kubeblocks/pkg/constant" @@ -399,11 +400,11 @@ func (s *Scheduler) reconfigure(schedulePolicy *dpv1alpha1.SchedulePolicy) error } targetPodSelector := targets[0].PodSelector clusterName := targetPodSelector.MatchLabels[constant.AppInstanceLabelKey] - cluster := &appsv1alpha1.Cluster{} + cluster := &appsv1.Cluster{} if err := s.Client.Get(s.Ctx, client.ObjectKey{Name: clusterName, Namespace: s.BackupSchedule.Namespace}, cluster); err != nil { return err } - if !slices.Contains(appsv1alpha1.GetReconfiguringRunningPhases(), cluster.Status.Phase) { + if !slices.Contains(appsv1.GetReconfiguringRunningPhases(), cluster.Status.Phase) { return intctrlutil.NewErrorf(intctrlutil.ErrorTypeRequeue, "requeue to waiting for the cluster %s to be available.", clusterName) } ops := appsv1alpha1.OpsRequest{ diff --git a/pkg/dataprotection/backup/scheduler_test.go b/pkg/dataprotection/backup/scheduler_test.go index 165dd794695..f925c42241f 100644 --- a/pkg/dataprotection/backup/scheduler_test.go +++ b/pkg/dataprotection/backup/scheduler_test.go @@ -27,7 +27,7 @@ import ( "k8s.io/utils/pointer" "sigs.k8s.io/controller-runtime/pkg/client" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" dpv1alpha1 "github.com/apecloud/kubeblocks/apis/dataprotection/v1alpha1" "github.com/apecloud/kubeblocks/pkg/constant" ctrlutil "github.com/apecloud/kubeblocks/pkg/controllerutil" @@ -83,7 +83,7 @@ var _ = Describe("Scheduler Test", func() { backupSchedule *dpv1alpha1.BackupSchedule actionSet *dpv1alpha1.ActionSet scheduler *Scheduler - cluster *appsv1alpha1.Cluster + cluster *appsv1.Cluster ) BeforeEach(func() { @@ -104,7 +104,7 @@ var _ = Describe("Scheduler Test", func() { backupSchedule = testdp.NewFakeBackupSchedule(&testCtx, func(schedule *dpv1alpha1.BackupSchedule) { schedule.OwnerReferences = []v1.OwnerReference{ { - APIVersion: appsv1alpha1.APIVersion, + APIVersion: appsv1.APIVersion, Kind: "Cluster", Name: cluster.Name, UID: cluster.UID, @@ -161,7 +161,7 @@ var _ = Describe("Scheduler Test", func() { backupSchedule = testdp.NewFakeBackupSchedule(&testCtx, func(schedule *dpv1alpha1.BackupSchedule) { schedule.OwnerReferences = []v1.OwnerReference{ { - APIVersion: appsv1alpha1.APIVersion, + APIVersion: appsv1.APIVersion, Kind: "Cluster", Name: cluster.Name, UID: cluster.UID, diff --git a/pkg/generics/type.go b/pkg/generics/type.go index df08eb74e69..afffae03549 100644 --- a/pkg/generics/type.go +++ b/pkg/generics/type.go @@ -87,7 +87,7 @@ var VolumeSnapshotSignature = func(_ snapshotv1.VolumeSnapshot, _ *snapshotv1.Vo var VolumeSnapshotClassSignature = func(_ snapshotv1.VolumeSnapshotClass, _ *snapshotv1.VolumeSnapshotClass, _ snapshotv1.VolumeSnapshotClassList, _ *snapshotv1.VolumeSnapshotClassList) { } -var ClusterSignature = func(_ appsv1alpha1.Cluster, _ *appsv1alpha1.Cluster, _ appsv1alpha1.ClusterList, _ *appsv1alpha1.ClusterList) { +var ClusterSignature = func(_ appsv1.Cluster, _ *appsv1.Cluster, _ appsv1.ClusterList, _ *appsv1.ClusterList) { } var ClusterDefinitionSignature = func(_ appsv1.ClusterDefinition, _ *appsv1.ClusterDefinition, _ appsv1.ClusterDefinitionList, _ *appsv1.ClusterDefinitionList) { } diff --git a/pkg/testutil/apps/cluster_factory.go b/pkg/testutil/apps/cluster_factory.go index 4dbc385b9c0..21ce2547802 100644 --- a/pkg/testutil/apps/cluster_factory.go +++ b/pkg/testutil/apps/cluster_factory.go @@ -22,21 +22,21 @@ package apps import ( corev1 "k8s.io/api/core/v1" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" ) type MockClusterFactory struct { - BaseFactory[appsv1alpha1.Cluster, *appsv1alpha1.Cluster, MockClusterFactory] + BaseFactory[appsv1.Cluster, *appsv1.Cluster, MockClusterFactory] } func NewClusterFactory(namespace, name, cdRef string) *MockClusterFactory { f := &MockClusterFactory{} f.Init(namespace, name, - &appsv1alpha1.Cluster{ - Spec: appsv1alpha1.ClusterSpec{ + &appsv1.Cluster{ + Spec: appsv1.ClusterSpec{ ClusterDefRef: cdRef, - ComponentSpecs: []appsv1alpha1.ClusterComponentSpec{}, - TerminationPolicy: appsv1alpha1.WipeOut, + ComponentSpecs: []appsv1.ClusterComponentSpec{}, + TerminationPolicy: appsv1.WipeOut, }, }, f) return f @@ -47,29 +47,19 @@ func (factory *MockClusterFactory) SetTopology(topology string) *MockClusterFact return factory } -func (factory *MockClusterFactory) SetTerminationPolicy(policyType appsv1alpha1.TerminationPolicyType) *MockClusterFactory { +func (factory *MockClusterFactory) SetTerminationPolicy(policyType appsv1.TerminationPolicyType) *MockClusterFactory { factory.Get().Spec.TerminationPolicy = policyType return factory } -func (factory *MockClusterFactory) SetClusterAffinity(affinity *appsv1alpha1.Affinity) *MockClusterFactory { - factory.Get().Spec.Affinity = affinity - return factory -} - -func (factory *MockClusterFactory) AddClusterToleration(toleration corev1.Toleration) *MockClusterFactory { - tolerations := factory.Get().Spec.Tolerations - if len(tolerations) == 0 { - tolerations = []corev1.Toleration{} - } - tolerations = append(tolerations, toleration) - factory.Get().Spec.Tolerations = tolerations +func (factory *MockClusterFactory) SetSchedulingPolicy(schedulingPolicy *appsv1.SchedulingPolicy) *MockClusterFactory { + factory.Get().Spec.SchedulingPolicy = schedulingPolicy return factory } func (factory *MockClusterFactory) AddShardingSpec(shardingName string, compDefName string) *MockClusterFactory { - shardingSpec := appsv1alpha1.ShardingSpec{ - Template: appsv1alpha1.ClusterComponentSpec{ + shardingSpec := appsv1.ShardingSpec{ + Template: appsv1.ClusterComponentSpec{ Name: "fake", ComponentDef: compDefName, Replicas: 1, @@ -82,7 +72,7 @@ func (factory *MockClusterFactory) AddShardingSpec(shardingName string, compDefN } func (factory *MockClusterFactory) AddComponent(compName string, compDefName string) *MockClusterFactory { - comp := appsv1alpha1.ClusterComponentSpec{ + comp := appsv1.ClusterComponentSpec{ Name: compName, ComponentDef: compDefName, } @@ -91,10 +81,10 @@ func (factory *MockClusterFactory) AddComponent(compName string, compDefName str } func (factory *MockClusterFactory) AddMultipleTemplateComponent(compName string, compDefName string) *MockClusterFactory { - comp := appsv1alpha1.ClusterComponentSpec{ + comp := appsv1.ClusterComponentSpec{ Name: compName, ComponentDef: compDefName, - Instances: []appsv1alpha1.InstanceTemplate{{ + Instances: []appsv1.InstanceTemplate{{ Name: "foo", Replicas: func() *int32 { replicas := int32(1); return &replicas }(), }}, @@ -103,19 +93,19 @@ func (factory *MockClusterFactory) AddMultipleTemplateComponent(compName string, return factory } -func (factory *MockClusterFactory) AddService(service appsv1alpha1.ClusterService) *MockClusterFactory { +func (factory *MockClusterFactory) AddService(service appsv1.ClusterService) *MockClusterFactory { services := factory.Get().Spec.Services if len(services) == 0 { - services = []appsv1alpha1.ClusterService{} + services = []appsv1.ClusterService{} } services = append(services, service) factory.Get().Spec.Services = services return factory } -type updateFn func(comp *appsv1alpha1.ClusterComponentSpec) +type updateFn func(comp *appsv1.ClusterComponentSpec) -type shardingUpdateFn func(shardingSpec *appsv1alpha1.ShardingSpec) +type shardingUpdateFn func(shardingSpec *appsv1.ShardingSpec) func (factory *MockClusterFactory) lastComponentRef(update updateFn) *MockClusterFactory { comps := factory.Get().Spec.ComponentSpecs @@ -136,113 +126,84 @@ func (factory *MockClusterFactory) lastShardingSpec(update shardingUpdateFn) *Mo } func (factory *MockClusterFactory) SetShards(shards int32) *MockClusterFactory { - return factory.lastShardingSpec(func(shardingSpec *appsv1alpha1.ShardingSpec) { + return factory.lastShardingSpec(func(shardingSpec *appsv1.ShardingSpec) { shardingSpec.Shards = shards }) } func (factory *MockClusterFactory) SetCompDef(compDef string) *MockClusterFactory { - return factory.lastComponentRef(func(comp *appsv1alpha1.ClusterComponentSpec) { + return factory.lastComponentRef(func(comp *appsv1.ClusterComponentSpec) { comp.ComponentDef = compDef }) } func (factory *MockClusterFactory) SetServiceVersion(serviceVersion string) *MockClusterFactory { - return factory.lastComponentRef(func(comp *appsv1alpha1.ClusterComponentSpec) { + return factory.lastComponentRef(func(comp *appsv1.ClusterComponentSpec) { comp.ServiceVersion = serviceVersion }) } func (factory *MockClusterFactory) SetReplicas(replicas int32) *MockClusterFactory { - return factory.lastComponentRef(func(comp *appsv1alpha1.ClusterComponentSpec) { + return factory.lastComponentRef(func(comp *appsv1.ClusterComponentSpec) { comp.Replicas = replicas }) } func (factory *MockClusterFactory) SetServiceAccountName(serviceAccountName string) *MockClusterFactory { - return factory.lastComponentRef(func(comp *appsv1alpha1.ClusterComponentSpec) { + return factory.lastComponentRef(func(comp *appsv1.ClusterComponentSpec) { comp.ServiceAccountName = serviceAccountName }) } func (factory *MockClusterFactory) SetResources(resources corev1.ResourceRequirements) *MockClusterFactory { - return factory.lastComponentRef(func(comp *appsv1alpha1.ClusterComponentSpec) { + return factory.lastComponentRef(func(comp *appsv1.ClusterComponentSpec) { comp.Resources = resources }) } -func (factory *MockClusterFactory) SetComponentAffinity(affinity *appsv1alpha1.Affinity) *MockClusterFactory { - return factory.lastComponentRef(func(comp *appsv1alpha1.ClusterComponentSpec) { - comp.Affinity = affinity - }) -} - func (factory *MockClusterFactory) SetEnabledLogs(logName ...string) *MockClusterFactory { - return factory.lastComponentRef(func(comp *appsv1alpha1.ClusterComponentSpec) { + return factory.lastComponentRef(func(comp *appsv1.ClusterComponentSpec) { comp.EnabledLogs = logName }) } -func (factory *MockClusterFactory) AddComponentToleration(toleration corev1.Toleration) *MockClusterFactory { - return factory.lastComponentRef(func(comp *appsv1alpha1.ClusterComponentSpec) { - tolerations := comp.Tolerations - if len(tolerations) == 0 { - tolerations = []corev1.Toleration{} - } - tolerations = append(tolerations, toleration) - comp.Tolerations = tolerations - }) -} - func (factory *MockClusterFactory) AddVolumeClaimTemplate(volumeName string, - pvcSpec appsv1alpha1.PersistentVolumeClaimSpec) *MockClusterFactory { - return factory.lastComponentRef(func(comp *appsv1alpha1.ClusterComponentSpec) { + pvcSpec appsv1.PersistentVolumeClaimSpec) *MockClusterFactory { + return factory.lastComponentRef(func(comp *appsv1.ClusterComponentSpec) { comp.VolumeClaimTemplates = append(comp.VolumeClaimTemplates, - appsv1alpha1.ClusterComponentVolumeClaimTemplate{ + appsv1.ClusterComponentVolumeClaimTemplate{ Name: volumeName, Spec: pvcSpec, }) }) } -// func (factory *MockClusterFactory) SetMonitor(monitor bool) *MockClusterFactory { -// return factory.lastComponentRef(func(comp *appsv1alpha1.ClusterComponentSpec) { -// comp.Monitor = monitor -// }) -// } - -func (factory *MockClusterFactory) SetSwitchPolicy(switchPolicy *appsv1alpha1.ClusterSwitchPolicy) *MockClusterFactory { - return factory.lastComponentRef(func(comp *appsv1alpha1.ClusterComponentSpec) { - comp.SwitchPolicy = switchPolicy - }) -} - func (factory *MockClusterFactory) SetTLS(tls bool) *MockClusterFactory { - return factory.lastComponentRef(func(comp *appsv1alpha1.ClusterComponentSpec) { + return factory.lastComponentRef(func(comp *appsv1.ClusterComponentSpec) { comp.TLS = tls }) } -func (factory *MockClusterFactory) SetIssuer(issuer *appsv1alpha1.Issuer) *MockClusterFactory { - return factory.lastComponentRef(func(comp *appsv1alpha1.ClusterComponentSpec) { +func (factory *MockClusterFactory) SetIssuer(issuer *appsv1.Issuer) *MockClusterFactory { + return factory.lastComponentRef(func(comp *appsv1.ClusterComponentSpec) { comp.Issuer = issuer }) } func (factory *MockClusterFactory) AddComponentService(serviceName string, serviceType corev1.ServiceType) *MockClusterFactory { - return factory.lastComponentRef(func(comp *appsv1alpha1.ClusterComponentSpec) { + return factory.lastComponentRef(func(comp *appsv1.ClusterComponentSpec) { comp.Services = append(comp.Services, - appsv1alpha1.ClusterComponentService{ + appsv1.ClusterComponentService{ Name: serviceName, ServiceType: serviceType, }) }) } -func (factory *MockClusterFactory) AddSystemAccount(name string, passwordConfig *appsv1alpha1.PasswordConfig, secretRef *appsv1alpha1.ProvisionSecretRef) *MockClusterFactory { - return factory.lastComponentRef(func(comp *appsv1alpha1.ClusterComponentSpec) { +func (factory *MockClusterFactory) AddSystemAccount(name string, passwordConfig *appsv1.PasswordConfig, secretRef *appsv1.ProvisionSecretRef) *MockClusterFactory { + return factory.lastComponentRef(func(comp *appsv1.ClusterComponentSpec) { comp.SystemAccounts = append(comp.SystemAccounts, - appsv1alpha1.ComponentSystemAccount{ + appsv1.ComponentSystemAccount{ Name: name, PasswordConfig: passwordConfig, SecretRef: secretRef, @@ -250,20 +211,20 @@ func (factory *MockClusterFactory) AddSystemAccount(name string, passwordConfig }) } -func (factory *MockClusterFactory) SetBackup(backup *appsv1alpha1.ClusterBackup) *MockClusterFactory { +func (factory *MockClusterFactory) SetBackup(backup *appsv1.ClusterBackup) *MockClusterFactory { factory.Get().Spec.Backup = backup return factory } -func (factory *MockClusterFactory) SetServiceRefs(serviceRefs []appsv1alpha1.ServiceRef) *MockClusterFactory { - return factory.lastComponentRef(func(comp *appsv1alpha1.ClusterComponentSpec) { +func (factory *MockClusterFactory) SetServiceRefs(serviceRefs []appsv1.ServiceRef) *MockClusterFactory { + return factory.lastComponentRef(func(comp *appsv1.ClusterComponentSpec) { comp.ServiceRefs = serviceRefs }) } func (factory *MockClusterFactory) AddUserSecretVolume(name, mountPoint, resName, containerName string) *MockClusterFactory { - secretResource := appsv1alpha1.SecretRef{ - ResourceMeta: appsv1alpha1.ResourceMeta{ + secretResource := appsv1.SecretRef{ + ResourceMeta: appsv1.ResourceMeta{ Name: name, MountPoint: mountPoint, AsVolumeFrom: []string{containerName}, @@ -272,10 +233,10 @@ func (factory *MockClusterFactory) AddUserSecretVolume(name, mountPoint, resName SecretName: resName, }, } - return factory.lastComponentRef(func(comp *appsv1alpha1.ClusterComponentSpec) { + return factory.lastComponentRef(func(comp *appsv1.ClusterComponentSpec) { userResourcesRefs := comp.UserResourceRefs if userResourcesRefs == nil { - userResourcesRefs = &appsv1alpha1.UserResourceRefs{} + userResourcesRefs = &appsv1.UserResourceRefs{} comp.UserResourceRefs = userResourcesRefs } userResourcesRefs.SecretRefs = append(userResourcesRefs.SecretRefs, secretResource) @@ -283,8 +244,8 @@ func (factory *MockClusterFactory) AddUserSecretVolume(name, mountPoint, resName } func (factory *MockClusterFactory) AddUserConfigmapVolume(name, mountPoint, resName, containerName string) *MockClusterFactory { - cmResource := appsv1alpha1.ConfigMapRef{ - ResourceMeta: appsv1alpha1.ResourceMeta{ + cmResource := appsv1.ConfigMapRef{ + ResourceMeta: appsv1.ResourceMeta{ Name: name, MountPoint: mountPoint, AsVolumeFrom: []string{containerName}, @@ -295,10 +256,10 @@ func (factory *MockClusterFactory) AddUserConfigmapVolume(name, mountPoint, resN }, }, } - return factory.lastComponentRef(func(comp *appsv1alpha1.ClusterComponentSpec) { + return factory.lastComponentRef(func(comp *appsv1.ClusterComponentSpec) { userResourcesRefs := comp.UserResourceRefs if userResourcesRefs == nil { - userResourcesRefs = &appsv1alpha1.UserResourceRefs{} + userResourcesRefs = &appsv1.UserResourceRefs{} comp.UserResourceRefs = userResourcesRefs } userResourcesRefs.ConfigMapRefs = append(userResourcesRefs.ConfigMapRefs, cmResource) @@ -306,7 +267,7 @@ func (factory *MockClusterFactory) AddUserConfigmapVolume(name, mountPoint, resN } func (factory *MockClusterFactory) SetStop(stop *bool) *MockClusterFactory { - return factory.lastComponentRef(func(comp *appsv1alpha1.ClusterComponentSpec) { + return factory.lastComponentRef(func(comp *appsv1.ClusterComponentSpec) { comp.Stop = stop }) } diff --git a/pkg/testutil/apps/cluster_instance_set_test_util.go b/pkg/testutil/apps/cluster_instance_set_test_util.go index 68e8414d044..f74625f4a7e 100644 --- a/pkg/testutil/apps/cluster_instance_set_test_util.go +++ b/pkg/testutil/apps/cluster_instance_set_test_util.go @@ -34,7 +34,6 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" "github.com/apecloud/kubeblocks/pkg/constant" "github.com/apecloud/kubeblocks/pkg/testutil" @@ -45,13 +44,13 @@ const ( replicas = 3 ) -func InitConsensusMysql(testCtx *testutil.TestContext, clusterName, compDefName, compName string) (*appsv1.ComponentDefinition, *appsv1alpha1.Cluster) { +func InitConsensusMysql(testCtx *testutil.TestContext, clusterName, compDefName, compName string) (*appsv1.ComponentDefinition, *appsv1.Cluster) { compDef := createCompDef(testCtx, compDefName) cluster := CreateDefaultMysqlCluster(testCtx, clusterName, compDef.GetName(), compName) return compDef, cluster } -func CreateDefaultMysqlCluster(testCtx *testutil.TestContext, clusterName, compDefName, compName string, pvcSize ...string) *appsv1alpha1.Cluster { +func CreateDefaultMysqlCluster(testCtx *testutil.TestContext, clusterName, compDefName, compName string, pvcSize ...string) *appsv1.Cluster { size := "2Gi" if len(pvcSize) > 0 { size = pvcSize[0] @@ -88,7 +87,7 @@ func MockInstanceSetComponent( func MockInstanceSetPods( testCtx *testutil.TestContext, its *workloads.InstanceSet, - cluster *appsv1alpha1.Cluster, + cluster *appsv1.Cluster, compName string) []*corev1.Pod { getReplicas := func() int { if its == nil || its.Spec.Replicas == nil { @@ -250,7 +249,7 @@ func generateInstanceNames(parentName, templateName string, return instanceNameList } -func generatePodNames(cluster *appsv1alpha1.Cluster, compName string) []string { +func generatePodNames(cluster *appsv1.Cluster, compName string) []string { podNames := make([]string, 0) insTPLReplicasCnt := int32(0) workloadName := constant.GenerateWorkloadNamePattern(cluster.Name, compName) @@ -279,7 +278,7 @@ func podIsReady(pod *corev1.Pod) bool { return false } -func MockInstanceSetStatus(testCtx testutil.TestContext, cluster *appsv1alpha1.Cluster, fullCompName string) { +func MockInstanceSetStatus(testCtx testutil.TestContext, cluster *appsv1.Cluster, fullCompName string) { currentPodNames := generatePodNames(cluster, fullCompName) updateRevisions := map[string]string{} for _, podName := range currentPodNames { diff --git a/pkg/testutil/apps/cluster_util.go b/pkg/testutil/apps/cluster_util.go index ed1cf244b49..845cb81f18a 100644 --- a/pkg/testutil/apps/cluster_util.go +++ b/pkg/testutil/apps/cluster_util.go @@ -28,7 +28,7 @@ import ( "k8s.io/apimachinery/pkg/types" "sigs.k8s.io/controller-runtime/pkg/client" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" "github.com/apecloud/kubeblocks/pkg/testutil" ) @@ -49,9 +49,9 @@ func CheckedCreateK8sResource(testCtx *testutil.TestContext, obj client.Object) } // GetClusterComponentPhase gets the component phase of testing cluster for verification. -func GetClusterComponentPhase(testCtx *testutil.TestContext, clusterKey types.NamespacedName, componentName string) func(g gomega.Gomega) appsv1alpha1.ClusterComponentPhase { - return func(g gomega.Gomega) appsv1alpha1.ClusterComponentPhase { - tmpCluster := &appsv1alpha1.Cluster{} +func GetClusterComponentPhase(testCtx *testutil.TestContext, clusterKey types.NamespacedName, componentName string) func(g gomega.Gomega) appsv1.ClusterComponentPhase { + return func(g gomega.Gomega) appsv1.ClusterComponentPhase { + tmpCluster := &appsv1.Cluster{} g.Expect(testCtx.Cli.Get(context.Background(), client.ObjectKey{Name: clusterKey.Name, Namespace: clusterKey.Namespace}, tmpCluster)).Should(gomega.Succeed()) return tmpCluster.Status.Components[componentName].Phase @@ -59,9 +59,9 @@ func GetClusterComponentPhase(testCtx *testutil.TestContext, clusterKey types.Na } // GetClusterPhase gets the testing cluster's phase in status for verification. -func GetClusterPhase(testCtx *testutil.TestContext, clusterKey types.NamespacedName) func(gomega.Gomega) appsv1alpha1.ClusterPhase { - return func(g gomega.Gomega) appsv1alpha1.ClusterPhase { - cluster := &appsv1alpha1.Cluster{} +func GetClusterPhase(testCtx *testutil.TestContext, clusterKey types.NamespacedName) func(gomega.Gomega) appsv1.ClusterPhase { + return func(g gomega.Gomega) appsv1.ClusterPhase { + cluster := &appsv1.Cluster{} g.Expect(testCtx.Cli.Get(testCtx.Ctx, clusterKey, cluster)).Should(gomega.Succeed()) return cluster.Status.Phase } @@ -70,7 +70,7 @@ func GetClusterPhase(testCtx *testutil.TestContext, clusterKey types.NamespacedN // GetClusterGeneration gets the testing cluster's metadata.generation. func GetClusterGeneration(testCtx *testutil.TestContext, clusterKey types.NamespacedName) func(gomega.Gomega) int64 { return func(g gomega.Gomega) int64 { - cluster := &appsv1alpha1.Cluster{} + cluster := &appsv1.Cluster{} g.Expect(testCtx.Cli.Get(testCtx.Ctx, clusterKey, cluster)).Should(gomega.Succeed()) return cluster.GetGeneration() } @@ -79,15 +79,15 @@ func GetClusterGeneration(testCtx *testutil.TestContext, clusterKey types.Namesp // GetClusterObservedGeneration gets the testing cluster's ObservedGeneration in status for verification. func GetClusterObservedGeneration(testCtx *testutil.TestContext, clusterKey types.NamespacedName) func(gomega.Gomega) int64 { return func(g gomega.Gomega) int64 { - cluster := &appsv1alpha1.Cluster{} + cluster := &appsv1.Cluster{} g.Expect(testCtx.Cli.Get(testCtx.Ctx, clusterKey, cluster)).Should(gomega.Succeed()) return cluster.Status.ObservedGeneration } } // NewPVCSpec creates appsv1alpha1.PersistentVolumeClaimSpec. -func NewPVCSpec(size string) appsv1alpha1.PersistentVolumeClaimSpec { - return appsv1alpha1.PersistentVolumeClaimSpec{ +func NewPVCSpec(size string) appsv1.PersistentVolumeClaimSpec { + return appsv1.PersistentVolumeClaimSpec{ AccessModes: []corev1.PersistentVolumeAccessMode{corev1.ReadWriteOnce}, Resources: corev1.VolumeResourceRequirements{ Requests: corev1.ResourceList{ diff --git a/pkg/testutil/apps/common_util.go b/pkg/testutil/apps/common_util.go index 32e4e9ecc2f..319cb288638 100644 --- a/pkg/testutil/apps/common_util.go +++ b/pkg/testutil/apps/common_util.go @@ -82,7 +82,7 @@ func ChangeObjStatus[T intctrlutil.Object, PT intctrlutil.PObject[T]](testCtx *t // Each helper returns a Gomega assertion function, which should be passed into // Eventually() or Consistently() as the first parameter. // Example: -// Eventually(GetAndChangeObj(testCtx, key, func(fetched *appsv1alpha1.ClusterDefinition) { +// Eventually(GetAndChangeObj(testCtx, key, func(fetched *appsv1.ClusterDefinition) { // // modify fetched clusterDef // })).Should(Succeed()) // Warning: these functions should NOT be used together with Expect(). @@ -120,7 +120,7 @@ func GetAndChangeObjStatus[T intctrlutil.Object, PT intctrlutil.PObject[T]]( // Each helper returns a Gomega assertion function, which should be passed into // Eventually() or Consistently() as the first parameter. // Example: -// Eventually(CheckObj(testCtx, key, func(g Gomega, fetched *appsv1alpha1.Cluster) { +// Eventually(CheckObj(testCtx, key, func(g Gomega, fetched *appsv1.Cluster) { // g.Expect(..).To(BeTrue()) // do some check // })).Should(Succeed()) // Warning: these functions should NOT be used together with Expect(). diff --git a/pkg/testutil/dataprotection/types.go b/pkg/testutil/dataprotection/types.go index 50dbe2e674d..7b4c2f7081e 100644 --- a/pkg/testutil/dataprotection/types.go +++ b/pkg/testutil/dataprotection/types.go @@ -22,11 +22,11 @@ package dataprotection import ( corev1 "k8s.io/api/core/v1" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" ) type BackupClusterInfo struct { - Cluster *appsv1alpha1.Cluster + Cluster *appsv1.Cluster TargetPod *corev1.Pod TargetPVC string } From 7aacf71995372f4c9de459d5529d5785ac24038c Mon Sep 17 00:00:00 2001 From: Leon Date: Wed, 4 Sep 2024 00:51:08 +0800 Subject: [PATCH 08/15] update --- apis/apps/v1alpha1/component_conversion.go | 14 +++++----- apis/apps/v1alpha1/opsrequest_validation.go | 2 +- .../apps/operations/custom_workflow.go | 2 +- .../operations/horizontal_scaling_test.go | 8 +++--- .../apps/operations/ops_comp_helper.go | 2 +- .../apps/operations/ops_progress_util_test.go | 4 +-- .../apps/operations/rebuild_instance_test.go | 2 +- controllers/apps/operations/reconfigure.go | 5 ++-- .../apps/operations/reconfigure_pipeline.go | 9 ++++--- .../operations/reconfigure_pipeline_test.go | 15 ++++++----- .../apps/operations/reconfigure_util.go | 3 ++- controllers/apps/operations/restart.go | 5 ++-- .../transformer_cluster_component_status.go | 17 ++++++------ .../transformer_cluster_load_resources.go | 10 ++----- .../transformer_component_service_test.go | 2 +- controllers/apps/transformer_component_tls.go | 2 +- .../config_manager/config_handler.go | 5 ++-- .../config_manager/config_handler_test.go | 12 ++++----- .../config_manager/handler_util_test.go | 4 +-- .../config_manager/reload_util_test.go | 22 ++++++++-------- .../builder/builder_configuration_test.go | 10 +++---- .../component/lifecycle/lfa_member.go | 5 ++-- pkg/controller/component/vars.go | 5 +++- pkg/controller/configuration/operator.go | 10 +++---- .../configuration/template_merger.go | 11 ++++---- .../configuration/template_wrapper.go | 6 ++++- pkg/controller/plan/tls_utils_test.go | 4 +-- pkg/controllerutil/volume_util_test.go | 26 +++++++++---------- 28 files changed, 113 insertions(+), 109 deletions(-) diff --git a/apis/apps/v1alpha1/component_conversion.go b/apis/apps/v1alpha1/component_conversion.go index cdd140b423a..9a150bb4ed0 100644 --- a/apis/apps/v1alpha1/component_conversion.go +++ b/apis/apps/v1alpha1/component_conversion.go @@ -32,14 +32,13 @@ func (r *Component) ConvertTo(dstRaw conversion.Hub) error { dst.ObjectMeta = r.ObjectMeta // spec - dst.Spec.CompatibilityRules = r.compatibilityRulesTo(r.Spec.CompatibilityRules) - dst.Spec.Releases = r.releasesTo(r.Spec.Releases) + // TODO(v1.0) // status dst.Status.ObservedGeneration = r.Status.ObservedGeneration - dst.Status.Phase = appsv1.Phase(r.Status.Phase) + dst.Status.Conditions = r.Status.Conditions + dst.Status.Phase = appsv1.ClusterComponentPhase(r.Status.Phase) dst.Status.Message = r.Status.Message - dst.Status.ServiceVersions = r.Status.ServiceVersions return nil } @@ -52,14 +51,13 @@ func (r *Component) ConvertFrom(srcRaw conversion.Hub) error { r.ObjectMeta = src.ObjectMeta // spec - r.Spec.CompatibilityRules = r.compatibilityRulesFrom(src.Spec.CompatibilityRules) - r.Spec.Releases = r.releasesFrom(src.Spec.Releases) + // TODO(v1.0) // status r.Status.ObservedGeneration = src.Status.ObservedGeneration - r.Status.Phase = Phase(src.Status.Phase) + r.Status.Conditions = src.Status.Conditions + r.Status.Phase = ClusterComponentPhase(src.Status.Phase) r.Status.Message = src.Status.Message - r.Status.ServiceVersions = src.Status.ServiceVersions return nil } diff --git a/apis/apps/v1alpha1/opsrequest_validation.go b/apis/apps/v1alpha1/opsrequest_validation.go index b39a1d08148..e0836a2fb05 100644 --- a/apis/apps/v1alpha1/opsrequest_validation.go +++ b/apis/apps/v1alpha1/opsrequest_validation.go @@ -386,7 +386,7 @@ func (r *OpsRequest) validateHorizontalScalingSpec(hScale HorizontalScaling, com // Rules: // 1. length of offlineInstancesToOnline or onlineInstancesToOffline can't greater than the configured replicaChanges for the component. // 2. replicaChanges for component must greater than or equal to the sum of replicaChanges configured in instance templates. - validateHScaleOperation := func(replicaChanger ReplicaChanger, newInstances []InstanceTemplate, offlineOrOnlineInsNames []string, isScaleIn bool) error { + validateHScaleOperation := func(replicaChanger ReplicaChanger, newInstances []appsv1.InstanceTemplate, offlineOrOnlineInsNames []string, isScaleIn bool) error { msgPrefix := "ScaleIn:" hScaleInstanceFieldName := "onlineInstancesToOffline" if !isScaleIn { diff --git a/controllers/apps/operations/custom_workflow.go b/controllers/apps/operations/custom_workflow.go index 172f9c4058d..db366f3fb78 100644 --- a/controllers/apps/operations/custom_workflow.go +++ b/controllers/apps/operations/custom_workflow.go @@ -21,10 +21,10 @@ package operations import ( "fmt" - appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" "sigs.k8s.io/controller-runtime/pkg/client" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" "github.com/apecloud/kubeblocks/controllers/apps/operations/custom" intctrlutil "github.com/apecloud/kubeblocks/pkg/controllerutil" diff --git a/controllers/apps/operations/horizontal_scaling_test.go b/controllers/apps/operations/horizontal_scaling_test.go index 28b9dfb8eaa..babf1c81dab 100644 --- a/controllers/apps/operations/horizontal_scaling_test.go +++ b/controllers/apps/operations/horizontal_scaling_test.go @@ -423,19 +423,19 @@ var _ = Describe("HorizontalScaling OpsRequest", func() { }) It("h-scale new instance templates and scale in all old replicas", func() { - templateFoo := appsv1alpha1.InstanceTemplate{ + templateFoo := appsv1.InstanceTemplate{ Name: insTplName, Replicas: func() *int32 { r := int32(3); return &r }(), } - templateBar := appsv1alpha1.InstanceTemplate{ + templateBar := appsv1.InstanceTemplate{ Name: "bar", Replicas: func() *int32 { r := int32(3); return &r }(), } - instances := []appsv1alpha1.InstanceTemplate{templateFoo, templateBar} + instances := []appsv1.InstanceTemplate{templateFoo, templateBar} reqCtx := intctrlutil.RequestCtx{Ctx: testCtx.Ctx} opsRes, pods := commonHScaleConsensusCompTest(reqCtx, nil, appsv1alpha1.HorizontalScaling{ ScaleOut: &appsv1alpha1.ScaleOut{ - NewInstances: []appsv1alpha1.InstanceTemplate{templateFoo, templateBar}, + NewInstances: []appsv1.InstanceTemplate{templateFoo, templateBar}, }, ScaleIn: &appsv1alpha1.ScaleIn{ ReplicaChanger: appsv1alpha1.ReplicaChanger{ReplicaChanges: pointer.Int32(3)}, diff --git a/controllers/apps/operations/ops_comp_helper.go b/controllers/apps/operations/ops_comp_helper.go index 657f95371d1..ada031b6be1 100644 --- a/controllers/apps/operations/ops_comp_helper.go +++ b/controllers/apps/operations/ops_comp_helper.go @@ -259,7 +259,7 @@ func (c componentOpsHelper) reconcileActionWithComponentOps(reqCtx intctrlutil.R if err != nil { return opsRequestPhase, 0, err } - componentPhase = appsv1.ClusterComponentPhase(compObj.Status.Phase) + componentPhase = compObj.Status.Phase } // conditions whether ops is running: // 1. completedProgressCount is not equal to expectProgressCount when the ops do not need to wait component phase to a terminal phase. diff --git a/controllers/apps/operations/ops_progress_util_test.go b/controllers/apps/operations/ops_progress_util_test.go index f2ed1848f27..535a26428e9 100644 --- a/controllers/apps/operations/ops_progress_util_test.go +++ b/controllers/apps/operations/ops_progress_util_test.go @@ -75,7 +75,7 @@ var _ = Describe("Ops ProgressDetails", func() { initClusterForOps := func(opsRes *OpsResource) { Expect(opsutil.UpdateClusterOpsAnnotations(ctx, k8sClient, opsRes.Cluster, nil)).Should(Succeed()) - opsRes.Cluster.Status.Phase = appsv1alpha1.RunningClusterPhase + opsRes.Cluster.Status.Phase = appsv1.RunningClusterPhase } testProgressDetailsWithStatefulPodUpdating := func(reqCtx intctrlutil.RequestCtx, opsRes *OpsResource, pods []*corev1.Pod) { @@ -180,7 +180,7 @@ var _ = Describe("Ops ProgressDetails", func() { ComponentOps: appsv1alpha1.ComponentOps{ComponentName: defaultCompName}, Replicas: pointer.Int32(4), }) - mockComponentIsOperating(opsRes.Cluster, appsv1alpha1.UpdatingClusterCompPhase, defaultCompName) // appsv1alpha1.HorizontalScalingPhase + mockComponentIsOperating(opsRes.Cluster, appsv1.UpdatingClusterCompPhase, defaultCompName) // appsv1.HorizontalScalingPhase initClusterForOps(opsRes) By("mock HorizontalScaling OpsRequest phase is running") diff --git a/controllers/apps/operations/rebuild_instance_test.go b/controllers/apps/operations/rebuild_instance_test.go index 4c22affb534..fec78ad841a 100644 --- a/controllers/apps/operations/rebuild_instance_test.go +++ b/controllers/apps/operations/rebuild_instance_test.go @@ -21,7 +21,6 @@ package operations import ( "fmt" - appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" @@ -31,6 +30,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/client" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" dpv1alpha1 "github.com/apecloud/kubeblocks/apis/dataprotection/v1alpha1" "github.com/apecloud/kubeblocks/pkg/common" diff --git a/controllers/apps/operations/reconfigure.go b/controllers/apps/operations/reconfigure.go index 6dea9ce5a1b..aa44ca04a9e 100644 --- a/controllers/apps/operations/reconfigure.go +++ b/controllers/apps/operations/reconfigure.go @@ -28,6 +28,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/client" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" "github.com/apecloud/kubeblocks/pkg/configuration/core" configctrl "github.com/apecloud/kubeblocks/pkg/controller/configuration" @@ -42,9 +43,9 @@ func init() { opsManager := GetOpsManager() reconfigureBehaviour := OpsBehaviour{ // REVIEW: can do opsrequest if not running? - FromClusterPhases: appsv1alpha1.GetReconfiguringRunningPhases(), + FromClusterPhases: appsv1.GetReconfiguringRunningPhases(), // TODO: add cluster reconcile Reconfiguring phase. - ToClusterPhase: appsv1alpha1.UpdatingClusterPhase, + ToClusterPhase: appsv1.UpdatingClusterPhase, QueueByCluster: true, OpsHandler: &reAction, } diff --git a/controllers/apps/operations/reconfigure_pipeline.go b/controllers/apps/operations/reconfigure_pipeline.go index 4bcdd7d32a6..36b51912e0a 100644 --- a/controllers/apps/operations/reconfigure_pipeline.go +++ b/controllers/apps/operations/reconfigure_pipeline.go @@ -21,16 +21,19 @@ package operations import ( "fmt" + "slices" "github.com/pkg/errors" "k8s.io/apimachinery/pkg/util/validation/field" "sigs.k8s.io/controller-runtime/pkg/client" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" appsv1beta1 "github.com/apecloud/kubeblocks/apis/apps/v1beta1" cfgcore "github.com/apecloud/kubeblocks/pkg/configuration/core" "github.com/apecloud/kubeblocks/pkg/configuration/validate" + "github.com/apecloud/kubeblocks/pkg/controller/builder" configctrl "github.com/apecloud/kubeblocks/pkg/controller/configuration" intctrlutil "github.com/apecloud/kubeblocks/pkg/controllerutil" ) @@ -57,7 +60,7 @@ type pipeline struct { updatedObject *appsv1alpha1.Configuration configConstraint *appsv1beta1.ConfigConstraint - configSpec *appsv1alpha1.ComponentConfigSpec + configSpec *appsv1.ComponentConfigSpec reconfigureContext configctrl.ResourceFetcher[pipeline] @@ -91,7 +94,7 @@ func (p *pipeline) Validate() *pipeline { return cfgcore.MakeError("failed to reconfigure, not existed config[%s]", p.config.Name) } - p.configSpec = item.ConfigSpec + p.configSpec = builder.ToV1ConfigSpec(item.ConfigSpec) return nil } @@ -172,7 +175,7 @@ func (p *pipeline) doMergeImpl(parameters appsv1alpha1.ConfigurationItem) error return p.createUpdatePatch(item, configSpec) } -func (p *pipeline) createUpdatePatch(item *appsv1alpha1.ConfigurationItemDetail, configSpec *appsv1alpha1.ComponentConfigSpec) error { +func (p *pipeline) createUpdatePatch(item *appsv1alpha1.ConfigurationItemDetail, configSpec *appsv1.ComponentConfigSpec) error { if p.configConstraint == nil { return nil } diff --git a/controllers/apps/operations/reconfigure_pipeline_test.go b/controllers/apps/operations/reconfigure_pipeline_test.go index 33c4bc4d6fe..9acc5610d83 100644 --- a/controllers/apps/operations/reconfigure_pipeline_test.go +++ b/controllers/apps/operations/reconfigure_pipeline_test.go @@ -30,6 +30,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/log" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" appsv1beta1 "github.com/apecloud/kubeblocks/apis/apps/v1beta1" "github.com/apecloud/kubeblocks/pkg/configuration/core" @@ -43,8 +44,8 @@ var _ = Describe("Reconfigure util test", func() { var ( k8sMockClient *testutil.K8sClientMockHelper - tpl appsv1alpha1.ComponentConfigSpec - tpl2 appsv1alpha1.ComponentConfigSpec + tpl appsv1.ComponentConfigSpec + tpl2 appsv1.ComponentConfigSpec updatedCfg appsv1alpha1.ConfigurationItem ) @@ -53,7 +54,7 @@ var _ = Describe("Reconfigure util test", func() { componentName = "mysql" ) - mockCfgTplObj := func(tpl appsv1alpha1.ComponentConfigSpec) (*corev1.ConfigMap, *appsv1beta1.ConfigConstraint, *appsv1alpha1.Configuration) { + mockCfgTplObj := func(tpl appsv1.ComponentConfigSpec) (*corev1.ConfigMap, *appsv1beta1.ConfigConstraint, *appsv1alpha1.Configuration) { By("By assure an cm obj") cfgCM := testapps.NewCustomizedObj("operations_config/config-template.yaml", @@ -74,16 +75,16 @@ var _ = Describe("Reconfigure util test", func() { BeforeEach(func() { k8sMockClient = testutil.NewK8sMockClient() - tpl = appsv1alpha1.ComponentConfigSpec{ - ComponentTemplateSpec: appsv1alpha1.ComponentTemplateSpec{ + tpl = appsv1.ComponentConfigSpec{ + ComponentTemplateSpec: appsv1.ComponentTemplateSpec{ Name: "for_test", TemplateRef: "cm_obj", }, ConfigConstraintRef: "cfg_constraint_obj", Keys: []string{"my.cnf"}, } - tpl2 = appsv1alpha1.ComponentConfigSpec{ - ComponentTemplateSpec: appsv1alpha1.ComponentTemplateSpec{ + tpl2 = appsv1.ComponentConfigSpec{ + ComponentTemplateSpec: appsv1.ComponentTemplateSpec{ Name: "for_test2", TemplateRef: "cm_obj", }, diff --git a/controllers/apps/operations/reconfigure_util.go b/controllers/apps/operations/reconfigure_util.go index 0d8a3eee35d..4e2becd63f2 100644 --- a/controllers/apps/operations/reconfigure_util.go +++ b/controllers/apps/operations/reconfigure_util.go @@ -27,6 +27,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/log" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" appsv1beta1 "github.com/apecloud/kubeblocks/apis/apps/v1beta1" "github.com/apecloud/kubeblocks/pkg/configuration/core" @@ -142,7 +143,7 @@ func makeReconfiguringResult(err error, ops ...func(*reconfiguringResult)) recon return result } -func constructReconfiguringConditions(result reconfiguringResult, resource *OpsResource, configSpec *appsv1alpha1.ComponentConfigSpec) *metav1.Condition { +func constructReconfiguringConditions(result reconfiguringResult, resource *OpsResource, configSpec *appsv1.ComponentConfigSpec) *metav1.Condition { if result.noFormatFilesUpdated || (result.configPatch != nil && result.configPatch.IsModify) { return appsv1alpha1.NewReconfigureRunningCondition( resource.OpsRequest, diff --git a/controllers/apps/operations/restart.go b/controllers/apps/operations/restart.go index f3039741841..fe1213d7142 100644 --- a/controllers/apps/operations/restart.go +++ b/controllers/apps/operations/restart.go @@ -29,6 +29,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/client" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" "github.com/apecloud/kubeblocks/pkg/constant" @@ -44,8 +45,8 @@ var _ OpsHandler = restartOpsHandler{} func init() { restartBehaviour := OpsBehaviour{ // if cluster is Abnormal or Failed, new opsRequest may repair it. - FromClusterPhases: appsv1alpha1.GetClusterUpRunningPhases(), - ToClusterPhase: appsv1alpha1.UpdatingClusterPhase, + FromClusterPhases: appsv1.GetClusterUpRunningPhases(), + ToClusterPhase: appsv1.UpdatingClusterPhase, QueueByCluster: true, OpsHandler: restartOpsHandler{}, } diff --git a/controllers/apps/transformer_cluster_component_status.go b/controllers/apps/transformer_cluster_component_status.go index c682cf6782c..5c3f500f4a7 100644 --- a/controllers/apps/transformer_cluster_component_status.go +++ b/controllers/apps/transformer_cluster_component_status.go @@ -22,7 +22,6 @@ package apps import ( "fmt" - "golang.org/x/exp/slices" corev1 "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/types" @@ -122,14 +121,14 @@ func (t *clusterComponentStatusTransformer) updateClusterComponentStatus(comp *a // } } -func (t *clusterComponentStatusTransformer) isClusterComponentPodsReady(phase appsv1.ClusterComponentPhase) bool { - podsReadyPhases := []appsv1.ClusterComponentPhase{ - appsv1.RunningClusterCompPhase, - appsv1.StoppingClusterCompPhase, - appsv1.StoppedClusterCompPhase, - } - return slices.Contains(podsReadyPhases, phase) -} +// func (t *clusterComponentStatusTransformer) isClusterComponentPodsReady(phase appsv1.ClusterComponentPhase) bool { +// podsReadyPhases := []appsv1.ClusterComponentPhase{ +// appsv1.RunningClusterCompPhase, +// appsv1.StoppingClusterCompPhase, +// appsv1.StoppedClusterCompPhase, +// } +// return slices.Contains(podsReadyPhases, phase) +// } func clusterComponentPhaseTransitionMsg(phase appsv1.ClusterComponentPhase) string { if len(phase) == 0 { diff --git a/controllers/apps/transformer_cluster_load_resources.go b/controllers/apps/transformer_cluster_load_resources.go index 7dc9394ca4c..dc62e045b6d 100644 --- a/controllers/apps/transformer_cluster_load_resources.go +++ b/controllers/apps/transformer_cluster_load_resources.go @@ -135,14 +135,8 @@ func withClusterLegacyDefinition(cluster *appsv1.Cluster) bool { } func withClusterSimplifiedAPI(cluster *appsv1.Cluster) bool { - return cluster.Spec.Replicas != nil || - !cluster.Spec.Resources.CPU.IsZero() || - !cluster.Spec.Resources.Memory.IsZero() || - !cluster.Spec.Storage.Size.IsZero() || - // cluster.Spec.Monitor.MonitoringInterval != nil || - cluster.Spec.Network != nil || - len(cluster.Spec.Tenancy) > 0 || - len(cluster.Spec.AvailabilityPolicy) > 0 + // TODO(v1.0): remove this + return false } func clusterCompCnt(cluster *appsv1.Cluster) int { diff --git a/controllers/apps/transformer_component_service_test.go b/controllers/apps/transformer_component_service_test.go index 51253944d78..6b7eaea7035 100644 --- a/controllers/apps/transformer_component_service_test.go +++ b/controllers/apps/transformer_component_service_test.go @@ -21,7 +21,6 @@ package apps import ( "fmt" - appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" @@ -31,6 +30,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/client" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" "github.com/apecloud/kubeblocks/pkg/constant" "github.com/apecloud/kubeblocks/pkg/controller/component" "github.com/apecloud/kubeblocks/pkg/controller/graph" diff --git a/controllers/apps/transformer_component_tls.go b/controllers/apps/transformer_component_tls.go index 314feaf5d8e..e16affd205e 100644 --- a/controllers/apps/transformer_component_tls.go +++ b/controllers/apps/transformer_component_tls.go @@ -22,7 +22,6 @@ package apps import ( "context" "fmt" - appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" "strings" corev1 "k8s.io/api/core/v1" @@ -30,6 +29,7 @@ import ( "k8s.io/apimachinery/pkg/types" "sigs.k8s.io/controller-runtime/pkg/client" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" cfgcore "github.com/apecloud/kubeblocks/pkg/configuration/core" "github.com/apecloud/kubeblocks/pkg/constant" diff --git a/pkg/configuration/config_manager/config_handler.go b/pkg/configuration/config_manager/config_handler.go index b94ca71ca93..2fb9c1665eb 100644 --- a/pkg/configuration/config_manager/config_handler.go +++ b/pkg/configuration/config_manager/config_handler.go @@ -31,6 +31,7 @@ import ( "github.com/fsnotify/fsnotify" "github.com/pkg/errors" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" appsv1beta1 "github.com/apecloud/kubeblocks/apis/apps/v1beta1" cfgcore "github.com/apecloud/kubeblocks/pkg/configuration/core" @@ -451,8 +452,8 @@ func createDownwardHandler(meta *ConfigSpecInfo) (map[string]ConfigHandler, erro handlers := make(map[string]ConfigHandler) for _, field := range meta.DownwardAPIOptions { - mockConfigSpec := &ConfigSpecInfo{ConfigSpec: appsv1alpha1.ComponentConfigSpec{ - ComponentTemplateSpec: appsv1alpha1.ComponentTemplateSpec{ + mockConfigSpec := &ConfigSpecInfo{ConfigSpec: appsv1.ComponentConfigSpec{ + ComponentTemplateSpec: appsv1.ComponentTemplateSpec{ Name: strings.Join([]string{meta.ConfigSpec.Name, field.Name}, "."), VolumeName: field.MountPoint, }}} diff --git a/pkg/configuration/config_manager/config_handler_test.go b/pkg/configuration/config_manager/config_handler_test.go index b16090aee62..37d86851352 100644 --- a/pkg/configuration/config_manager/config_handler_test.go +++ b/pkg/configuration/config_manager/config_handler_test.go @@ -36,7 +36,7 @@ import ( "github.com/fsnotify/fsnotify" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1beta1 "github.com/apecloud/kubeblocks/apis/apps/v1beta1" "github.com/apecloud/kubeblocks/pkg/configuration/util" testutil "github.com/apecloud/kubeblocks/pkg/testutil/k8s" @@ -67,9 +67,9 @@ var _ = Describe("Config Handler Test", func() { DeferCleanup(mockK8sCli.Finish) }) - newConfigSpec := func() appsv1alpha1.ComponentConfigSpec { - return appsv1alpha1.ComponentConfigSpec{ - ComponentTemplateSpec: appsv1alpha1.ComponentTemplateSpec{ + newConfigSpec := func() appsv1.ComponentConfigSpec { + return appsv1.ComponentConfigSpec{ + ComponentTemplateSpec: appsv1.ComponentTemplateSpec{ Name: "config", TemplateRef: "config-template", VolumeName: "/opt/config", @@ -179,8 +179,8 @@ var _ = Describe("Config Handler Test", func() { _, err = CreateExecHandler([]string{}, "", nil, "") Expect(err.Error()).To(ContainSubstring("invalid command")) c, err := CreateExecHandler([]string{"go", "version"}, "", &ConfigSpecInfo{ - ConfigSpec: appsv1alpha1.ComponentConfigSpec{ - ComponentTemplateSpec: appsv1alpha1.ComponentTemplateSpec{ + ConfigSpec: appsv1.ComponentConfigSpec{ + ComponentTemplateSpec: appsv1.ComponentTemplateSpec{ Name: "for_test", }}}, "") diff --git a/pkg/configuration/config_manager/handler_util_test.go b/pkg/configuration/config_manager/handler_util_test.go index 2df019fea98..81320ee0310 100644 --- a/pkg/configuration/config_manager/handler_util_test.go +++ b/pkg/configuration/config_manager/handler_util_test.go @@ -21,18 +21,18 @@ package configmanager import ( "context" - appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" "strings" "testing" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" - "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/assert" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/client" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1beta1 "github.com/apecloud/kubeblocks/apis/apps/v1beta1" cfgcore "github.com/apecloud/kubeblocks/pkg/configuration/core" cfgutil "github.com/apecloud/kubeblocks/pkg/configuration/util" diff --git a/pkg/configuration/config_manager/reload_util_test.go b/pkg/configuration/config_manager/reload_util_test.go index 96c253f15be..8e1bda2f461 100644 --- a/pkg/configuration/config_manager/reload_util_test.go +++ b/pkg/configuration/config_manager/reload_util_test.go @@ -37,7 +37,7 @@ import ( "github.com/stretchr/testify/require" "go.uber.org/zap" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1beta1 "github.com/apecloud/kubeblocks/apis/apps/v1beta1" "github.com/apecloud/kubeblocks/pkg/gotemplate" testapps "github.com/apecloud/kubeblocks/pkg/testutil/apps" @@ -335,8 +335,8 @@ var _ = Describe("ReloadUtil Test", func() { name: "test2", args: []ConfigSpecMeta{{ ConfigSpecInfo: ConfigSpecInfo{ - ConfigSpec: appsv1alpha1.ComponentConfigSpec{ - ComponentTemplateSpec: appsv1alpha1.ComponentTemplateSpec{ + ConfigSpec: appsv1.ComponentConfigSpec{ + ComponentTemplateSpec: appsv1.ComponentTemplateSpec{ Name: "test", TemplateRef: "test_cm", }}, @@ -347,8 +347,8 @@ var _ = Describe("ReloadUtil Test", func() { name: "test3", args: []ConfigSpecMeta{{ ConfigSpecInfo: ConfigSpecInfo{ - ConfigSpec: appsv1alpha1.ComponentConfigSpec{ - ComponentTemplateSpec: appsv1alpha1.ComponentTemplateSpec{ + ConfigSpec: appsv1.ComponentConfigSpec{ + ComponentTemplateSpec: appsv1.ComponentTemplateSpec{ Name: "test", TemplateRef: "test_cm", }, @@ -358,8 +358,8 @@ var _ = Describe("ReloadUtil Test", func() { }, }, { ConfigSpecInfo: ConfigSpecInfo{ - ConfigSpec: appsv1alpha1.ComponentConfigSpec{ - ComponentTemplateSpec: appsv1alpha1.ComponentTemplateSpec{ + ConfigSpec: appsv1.ComponentConfigSpec{ + ComponentTemplateSpec: appsv1.ComponentTemplateSpec{ Name: "test2", TemplateRef: "test_cm", }, @@ -372,8 +372,8 @@ var _ = Describe("ReloadUtil Test", func() { name: "test4", args: []ConfigSpecMeta{{ ConfigSpecInfo: ConfigSpecInfo{ - ConfigSpec: appsv1alpha1.ComponentConfigSpec{ - ComponentTemplateSpec: appsv1alpha1.ComponentTemplateSpec{ + ConfigSpec: appsv1.ComponentConfigSpec{ + ComponentTemplateSpec: appsv1.ComponentTemplateSpec{ Name: "test", TemplateRef: "test_cm", }, @@ -383,8 +383,8 @@ var _ = Describe("ReloadUtil Test", func() { }, }, { ConfigSpecInfo: ConfigSpecInfo{ - ConfigSpec: appsv1alpha1.ComponentConfigSpec{ - ComponentTemplateSpec: appsv1alpha1.ComponentTemplateSpec{ + ConfigSpec: appsv1.ComponentConfigSpec{ + ComponentTemplateSpec: appsv1.ComponentTemplateSpec{ Name: "test2", TemplateRef: "test_cm", }, diff --git a/pkg/controller/builder/builder_configuration_test.go b/pkg/controller/builder/builder_configuration_test.go index 0ac10aac412..2f66f308483 100644 --- a/pkg/controller/builder/builder_configuration_test.go +++ b/pkg/controller/builder/builder_configuration_test.go @@ -23,7 +23,7 @@ import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" - "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" "github.com/apecloud/kubeblocks/pkg/configuration/core" ) @@ -38,13 +38,13 @@ var _ = Describe("configuration builder", func() { config := NewConfigurationBuilder(ns, name). ClusterRef(clusterName). Component(componentName). - AddConfigurationItem(v1alpha1.ComponentConfigSpec{ - ComponentTemplateSpec: v1alpha1.ComponentTemplateSpec{ + AddConfigurationItem(appsv1.ComponentConfigSpec{ + ComponentTemplateSpec: appsv1.ComponentTemplateSpec{ Name: "mysql-config", }, }). - AddConfigurationItem(v1alpha1.ComponentConfigSpec{ - ComponentTemplateSpec: v1alpha1.ComponentTemplateSpec{ + AddConfigurationItem(appsv1.ComponentConfigSpec{ + ComponentTemplateSpec: appsv1.ComponentTemplateSpec{ Name: "mysql-oteld-config", }, }). diff --git a/pkg/controller/component/lifecycle/lfa_member.go b/pkg/controller/component/lifecycle/lfa_member.go index 185380ac4fb..f3072069085 100644 --- a/pkg/controller/component/lifecycle/lfa_member.go +++ b/pkg/controller/component/lifecycle/lfa_member.go @@ -27,7 +27,6 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" "github.com/apecloud/kubeblocks/pkg/constant" "github.com/apecloud/kubeblocks/pkg/controller/component" ) @@ -141,7 +140,7 @@ func (a *memberLeave) parameters(ctx context.Context, cli client.Reader) (map[st // - KB_LEADER_POD_NAME: The name of the current leader's pod prior to the switchover. // - KB_LEADER_POD_FQDN: The FQDN of the current leader's pod prior to the switchover. -func hackParameters4Switchover(ctx context.Context, cli client.Reader, namespace, clusterName, compName string, roles []appsv1alpha1.ReplicaRole) (map[string]string, error) { +func hackParameters4Switchover(ctx context.Context, cli client.Reader, namespace, clusterName, compName string, roles []appsv1.ReplicaRole) (map[string]string, error) { const ( leaderPodName = "KB_LEADER_POD_NAME" leaderPodFQDN = "KB_LEADER_POD_FQDN" @@ -172,7 +171,7 @@ func hackParameters4Switchover(ctx context.Context, cli client.Reader, namespace }, nil } -func leaderRole(roles []appsv1alpha1.ReplicaRole) (string, error) { +func leaderRole(roles []appsv1.ReplicaRole) (string, error) { targetRole := "" for _, role := range roles { if role.Serviceable && role.Writable { diff --git a/pkg/controller/component/vars.go b/pkg/controller/component/vars.go index 7388e37ec05..e7e9ea9ef70 100644 --- a/pkg/controller/component/vars.go +++ b/pkg/controller/component/vars.go @@ -1199,7 +1199,10 @@ func resolveComponentPodsRef(ctx context.Context, cli client.Reader, synthesized comp := obj.(*appsv1.Component) var templates []instanceset.InstanceTemplate for i := range comp.Spec.Instances { - templates = append(templates, &comp.Spec.Instances[i]) + templates = append(templates, &workloads.InstanceTemplate{ + Name: comp.Spec.Instances[i].Name, + Replicas: comp.Spec.Instances[i].Replicas, + }) } names, err := instanceset.GenerateAllInstanceNames(comp.Name, comp.Spec.Replicas, templates, comp.Spec.OfflineInstances, workloads.Ordinals{}) if err != nil { diff --git a/pkg/controller/configuration/operator.go b/pkg/controller/configuration/operator.go index f5cabf3a779..b8f44812379 100644 --- a/pkg/controller/configuration/operator.go +++ b/pkg/controller/configuration/operator.go @@ -59,11 +59,11 @@ func (c *configOperator) Reconcile() error { return NewCreatePipeline(c.ReconcileCtx). Prepare(). - RenderScriptTemplate(). // render scriptTemplate into ConfigMap - UpdateConfiguration(). // create or update Configuration - Configuration(). // fetch the latest Configuration - CreateConfigTemplate(). // render configTemplate into ConfigMap (only for the first time) - UpdatePodVolumes(). // update podSpec.Volumes + RenderScriptTemplate(). // render scriptTemplate into ConfigMap + UpdateConfiguration(). // create or update Configuration + Configuration(). // fetch the latest Configuration + CreateConfigTemplate(). // render configTemplate into ConfigMap (only for the first time) + UpdatePodVolumes(). // update podSpec.Volumes BuildConfigManagerSidecar(). // build configManager sidecar and update podSpec.Containers and podSpec.InitContainers UpdateConfigRelatedObject(). // handle InjectEnvTo, and create or update ConfigMaps UpdateConfigurationStatus(). // update ConfigurationItemStatus revision and phase etc. diff --git a/pkg/controller/configuration/template_merger.go b/pkg/controller/configuration/template_merger.go index e937de6e16c..c7ea9f13520 100644 --- a/pkg/controller/configuration/template_merger.go +++ b/pkg/controller/configuration/template_merger.go @@ -25,7 +25,6 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" appsv1beta1 "github.com/apecloud/kubeblocks/apis/apps/v1beta1" "github.com/apecloud/kubeblocks/pkg/configuration/core" ) @@ -50,7 +49,7 @@ type mergeContext struct { } func (m *mergeContext) renderTemplate() (map[string]string, error) { - templateSpec := appsv1alpha1.ComponentTemplateSpec{ + templateSpec := appsv1.ComponentTemplateSpec{ // Name: m.template.Name, Namespace: m.template.Namespace, TemplateRef: m.template.TemplateRef, @@ -134,13 +133,13 @@ func NewTemplateMerger(template appsv1.ConfigTemplateExtension, ctx context.Cont switch template.Policy { default: return nil, core.MakeError("unknown template policy: %s", template.Policy) - case appsv1alpha1.NoneMergePolicy: + case appsv1.NoneMergePolicy: merger = &noneOp{templateData} - case appsv1alpha1.PatchPolicy: + case appsv1.PatchPolicy: merger = &configPatcher{templateData} - case appsv1alpha1.OnlyAddPolicy: + case appsv1.OnlyAddPolicy: merger = &configOnlyAddMerger{templateData} - case appsv1alpha1.ReplacePolicy: + case appsv1.ReplacePolicy: merger = &configReplaceMerger{templateData} } return merger, nil diff --git a/pkg/controller/configuration/template_wrapper.go b/pkg/controller/configuration/template_wrapper.go index 49c819fa142..ad2ff24632b 100644 --- a/pkg/controller/configuration/template_wrapper.go +++ b/pkg/controller/configuration/template_wrapper.go @@ -212,7 +212,11 @@ func (wrapper *renderWrapper) rerenderConfigTemplate(cluster *appsv1.Cluster, if item != nil && item.ImportTemplateRef != nil { newData, err := mergerConfigTemplate( &appsv1.LegacyRenderedTemplateSpec{ - ConfigTemplateExtension: *item.ImportTemplateRef, + ConfigTemplateExtension: appsv1.ConfigTemplateExtension{ + TemplateRef: item.ImportTemplateRef.TemplateRef, + Namespace: item.ImportTemplateRef.Namespace, + Policy: appsv1.MergedPolicy(item.ImportTemplateRef.Policy), + }, }, wrapper.templateBuilder, configSpec, diff --git a/pkg/controller/plan/tls_utils_test.go b/pkg/controller/plan/tls_utils_test.go index 9f6ea3dad65..96ae43bc59a 100644 --- a/pkg/controller/plan/tls_utils_test.go +++ b/pkg/controller/plan/tls_utils_test.go @@ -32,7 +32,7 @@ import ( "k8s.io/apimachinery/pkg/runtime/schema" "sigs.k8s.io/controller-runtime/pkg/client" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" "github.com/apecloud/kubeblocks/pkg/constant" testutil "github.com/apecloud/kubeblocks/pkg/testutil/k8s" ) @@ -63,7 +63,7 @@ var _ = Describe("TLSUtilsTest", func() { It("should work well", func() { ctx := context.Background() name := "bar" - secretRef := &appsv1alpha1.TLSSecretRef{ + secretRef := &appsv1.TLSSecretRef{ Name: name, CA: "caName", Cert: "certName", diff --git a/pkg/controllerutil/volume_util_test.go b/pkg/controllerutil/volume_util_test.go index 2f265ed83fc..a2253bd86a3 100644 --- a/pkg/controllerutil/volume_util_test.go +++ b/pkg/controllerutil/volume_util_test.go @@ -29,7 +29,7 @@ import ( appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" + kbappsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" cfgutil "github.com/apecloud/kubeblocks/pkg/configuration/util" "github.com/apecloud/kubeblocks/pkg/constant" viper "github.com/apecloud/kubeblocks/pkg/viperx" @@ -39,7 +39,7 @@ var _ = Describe("lifecycle_utils", func() { Context("has the checkAndUpdatePodVolumes function which generates Pod Volumes for mounting ConfigMap objects", func() { var sts appsv1.StatefulSet - var volumes map[string]appsv1alpha1.ComponentTemplateSpec + var volumes map[string]kbappsv1.ComponentTemplateSpec BeforeEach(func() { sts = appsv1.StatefulSet{ Spec: appsv1.StatefulSetSpec{ @@ -70,7 +70,7 @@ var _ = Describe("lifecycle_utils", func() { }, }, } - volumes = make(map[string]appsv1alpha1.ComponentTemplateSpec) + volumes = make(map[string]kbappsv1.ComponentTemplateSpec) }) @@ -82,7 +82,7 @@ var _ = Describe("lifecycle_utils", func() { }) It("should succeed in normal test case, where one volume is added", func() { - volumes["my_config"] = appsv1alpha1.ComponentTemplateSpec{ + volumes["my_config"] = kbappsv1.ComponentTemplateSpec{ Name: "myConfig", TemplateRef: "myConfig", VolumeName: "myConfigVolume", @@ -94,12 +94,12 @@ var _ = Describe("lifecycle_utils", func() { }) It("should succeed in normal test case, where two volumes are added", func() { - volumes["my_config"] = appsv1alpha1.ComponentTemplateSpec{ + volumes["my_config"] = kbappsv1.ComponentTemplateSpec{ Name: "myConfig", TemplateRef: "myConfig", VolumeName: "myConfigVolume", } - volumes["my_config1"] = appsv1alpha1.ComponentTemplateSpec{ + volumes["my_config1"] = kbappsv1.ComponentTemplateSpec{ Name: "myConfig", TemplateRef: "myConfig", VolumeName: "myConfigVolume2", @@ -122,7 +122,7 @@ var _ = Describe("lifecycle_utils", func() { EmptyDir: &corev1.EmptyDirVolumeSource{}, }, }) - volumes[cmName] = appsv1alpha1.ComponentTemplateSpec{ + volumes[cmName] = kbappsv1.ComponentTemplateSpec{ Name: "configTplName", TemplateRef: "configTplName", VolumeName: replicaVolumeName, @@ -148,7 +148,7 @@ var _ = Describe("lifecycle_utils", func() { }, }) - volumes[cmName] = appsv1alpha1.ComponentTemplateSpec{ + volumes[cmName] = kbappsv1.ComponentTemplateSpec{ Name: "configTplName", TemplateRef: "configTplName", VolumeName: replicaVolumeName, @@ -170,7 +170,7 @@ var _ = Describe("lifecycle_utils", func() { func Test_buildVolumeMode(t *testing.T) { type args struct { configs []string - configSpec appsv1alpha1.ComponentTemplateSpec + configSpec kbappsv1.ComponentTemplateSpec } tests := []struct { name string @@ -180,7 +180,7 @@ func Test_buildVolumeMode(t *testing.T) { name: "config_test", args: args{ configs: []string{"config1", "config2"}, - configSpec: appsv1alpha1.ComponentTemplateSpec{ + configSpec: kbappsv1.ComponentTemplateSpec{ Name: "config1", DefaultMode: cfgutil.ToPointer(int32(0777)), }, @@ -190,7 +190,7 @@ func Test_buildVolumeMode(t *testing.T) { name: "config_test2", args: args{ configs: []string{"config1", "config2"}, - configSpec: appsv1alpha1.ComponentTemplateSpec{ + configSpec: kbappsv1.ComponentTemplateSpec{ Name: "config1", }, }, @@ -199,7 +199,7 @@ func Test_buildVolumeMode(t *testing.T) { name: "script_test", args: args{ configs: []string{"config1", "config2"}, - configSpec: appsv1alpha1.ComponentTemplateSpec{ + configSpec: kbappsv1.ComponentTemplateSpec{ Name: "script", DefaultMode: cfgutil.ToPointer(int32(0777)), }, @@ -209,7 +209,7 @@ func Test_buildVolumeMode(t *testing.T) { name: "script_test2", args: args{ configs: []string{"config1", "config2"}, - configSpec: appsv1alpha1.ComponentTemplateSpec{ + configSpec: kbappsv1.ComponentTemplateSpec{ Name: "script", }, }, From 6869989a4ed618887e6a560d0b551fe74d2bfc0e Mon Sep 17 00:00:00 2001 From: Leon Date: Fri, 6 Sep 2024 11:41:50 +0800 Subject: [PATCH 09/15] its v1 --- PROJECT | 12 + apis/workloads/v1/doc.go | 20 + apis/workloads/v1/groupversion_info.go | 41 + apis/workloads/v1/instanceset_conversion.go | 22 + apis/workloads/v1/instanceset_types.go | 777 + apis/workloads/v1/instanceset_webhook.go | 35 + apis/workloads/v1/register.go | 29 + apis/workloads/v1/zz_generated.deepcopy.go | 553 + .../v1alpha1/instanceset_conversion.go | 34 + cmd/manager/main.go | 6 + .../workloads.kubeblocks.io_instancesets.yaml | 13081 +++++++++++++++- config/samples/workloads_v1_instanceset.yaml | 12 + controllers/apps/cluster_plan_builder.go | 7 +- controllers/apps/component_controller.go | 2 +- controllers/apps/component_controller_test.go | 2 +- .../apps/component_hscale_volume_populator.go | 2 +- controllers/apps/component_utils.go | 6 +- controllers/apps/component_utils_test.go | 2 +- .../configuration/config_reconcile_wrapper.go | 2 +- .../configuration/config_related_helper.go | 2 +- controllers/apps/configuration/policy_util.go | 2 +- .../apps/configuration/policy_util_test.go | 2 +- .../apps/configuration/reconfigure_policy.go | 2 +- controllers/apps/configuration/suite_test.go | 6 +- .../apps/operations/ops_progress_util.go | 2 +- controllers/apps/operations/restart.go | 2 +- controllers/apps/operations/suite_test.go | 6 +- controllers/apps/opsrequest_controller.go | 6 +- .../apps/opsrequest_controller_test.go | 2 +- controllers/apps/suite_test.go | 6 +- controllers/apps/transform_types.go | 2 +- controllers/apps/transform_utils.go | 2 +- controllers/apps/transform_utils_test.go | 2 +- .../apps/transformer_cluster_backup_policy.go | 2 +- .../apps/transformer_component_deletion.go | 6 +- .../apps/transformer_component_rbac.go | 2 +- .../apps/transformer_component_rbac_test.go | 2 +- .../apps/transformer_component_service.go | 2 +- .../apps/transformer_component_status.go | 2 +- .../apps/transformer_component_vars.go | 2 +- .../apps/transformer_component_workload.go | 2 +- .../transformer_component_workload_upgrade.go | 2 +- .../experimental/reconciler_update_status.go | 2 +- .../reconciler_update_status_test.go | 2 +- controllers/experimental/suite_test.go | 2 +- controllers/experimental/tree_loader.go | 2 +- controllers/experimental/tree_loader_test.go | 2 +- controllers/k8score/event_controller_test.go | 2 +- controllers/k8score/suite_test.go | 2 +- .../workloads/instanceset_controller.go | 2 +- .../workloads/instanceset_controller_test.go | 2 +- controllers/workloads/suite_test.go | 4 +- .../workloads.kubeblocks.io_instancesets.yaml | 13081 +++++++++++++++- docs/developer_docs/api-reference/cluster.md | 2019 +++ .../builder/builder_instance_set.go | 2 +- .../builder/builder_instance_set_test.go | 2 +- pkg/controller/component/its_convertor.go | 2 +- pkg/controller/component/lifecycle/kbagent.go | 2 +- pkg/controller/component/vars.go | 2 +- pkg/controller/component/workload_utils.go | 2 +- pkg/controller/factory/builder.go | 2 +- pkg/controller/factory/builder_test.go | 2 +- .../handler/handler_builder_test.go | 2 +- pkg/controller/handler/suite_test.go | 2 +- .../instanceset/in_place_update_util.go | 2 +- .../instanceset/instance_template_util.go | 2 +- pkg/controller/instanceset/instance_util.go | 2 +- .../instanceset/instance_util_test.go | 2 +- pkg/controller/instanceset/object_builder.go | 2 +- .../instanceset/object_builder_test.go | 2 +- .../instanceset/pod_role_event_handler.go | 2 +- .../pod_role_event_handler_test.go | 2 +- .../reconciler_assistant_object.go | 2 +- .../reconciler_instance_alignment.go | 2 +- .../reconciler_instance_alignment_test.go | 2 +- .../instanceset/reconciler_revision_update.go | 2 +- .../reconciler_revision_update_test.go | 2 +- .../instanceset/reconciler_status.go | 2 +- .../instanceset/reconciler_status_test.go | 2 +- .../instanceset/reconciler_update.go | 2 +- .../instanceset/reconciler_update_test.go | 2 +- pkg/controller/instanceset/revision_util.go | 2 +- .../instanceset/revision_util_test.go | 2 +- pkg/controller/instanceset/suite_test.go | 2 +- pkg/controller/instanceset/tree_loader.go | 2 +- .../instanceset/tree_loader_test.go | 2 +- pkg/controller/instanceset/update_plan.go | 2 +- .../instanceset/update_plan_test.go | 2 +- pkg/controller/instanceset/utils.go | 2 +- pkg/controller/instanceset/utils_test.go | 2 +- pkg/controller/kubebuilderx/plan_builder.go | 2 +- .../kubebuilderx/plan_builder_test.go | 2 +- pkg/controllerutil/instance_set_utils.go | 2 +- pkg/generics/type.go | 2 +- .../apps/cluster_instance_set_test_util.go | 2 +- pkg/testutil/apps/instance_set_factoy.go | 2 +- pkg/testutil/k8s/instance_set_util.go | 2 +- 97 files changed, 29820 insertions(+), 99 deletions(-) create mode 100644 apis/workloads/v1/doc.go create mode 100644 apis/workloads/v1/groupversion_info.go create mode 100644 apis/workloads/v1/instanceset_conversion.go create mode 100644 apis/workloads/v1/instanceset_types.go create mode 100644 apis/workloads/v1/instanceset_webhook.go create mode 100644 apis/workloads/v1/register.go create mode 100644 apis/workloads/v1/zz_generated.deepcopy.go create mode 100644 apis/workloads/v1alpha1/instanceset_conversion.go create mode 100644 config/samples/workloads_v1_instanceset.yaml diff --git a/PROJECT b/PROJECT index 5f0b988bbc0..9da2eaaf381 100644 --- a/PROJECT +++ b/PROJECT @@ -142,6 +142,18 @@ resources: kind: InstanceSet path: github.com/apecloud/kubeblocks/apis/workloads/v1alpha1 version: v1alpha1 +- api: + crdVersion: v1 + namespaced: true + controller: true + domain: kubeblocks.io + group: workloads + kind: InstanceSet + path: github.com/apecloud/kubeblocks/apis/workloads/v1 + version: v1 + webhooks: + conversion: true + webhookVersion: v1 - api: crdVersion: v1 controller: true diff --git a/apis/workloads/v1/doc.go b/apis/workloads/v1/doc.go new file mode 100644 index 00000000000..3a374eed081 --- /dev/null +++ b/apis/workloads/v1/doc.go @@ -0,0 +1,20 @@ +/* +Copyright (C) 2022-2024 ApeCloud Co., Ltd + +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. +*/ + +// +k8s:deepcopy-gen=package,register +// +k8s:openapi-gen=true +// +groupName=workloads.kubeblocks.io +package v1 diff --git a/apis/workloads/v1/groupversion_info.go b/apis/workloads/v1/groupversion_info.go new file mode 100644 index 00000000000..61b08ee95f1 --- /dev/null +++ b/apis/workloads/v1/groupversion_info.go @@ -0,0 +1,41 @@ +/* +Copyright (C) 2022-2024 ApeCloud Co., Ltd + +This file is part of KubeBlocks project + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ + +// Package v1 contains API Schema definitions for the workloads v1 API group +// +kubebuilder:object:generate=true +// +groupName=workloads.kubeblocks.io +package v1 + +import ( + "k8s.io/apimachinery/pkg/runtime/schema" + "sigs.k8s.io/controller-runtime/pkg/scheme" +) + +var ( + // GroupVersion is group version used to register these objects + GroupVersion = schema.GroupVersion{Group: "workloads.kubeblocks.io", Version: "v1"} + + // SchemeBuilder is used to add go types to the GroupVersionKind scheme + SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion} + + // AddToScheme adds the types in this group-version to the given scheme. + AddToScheme = SchemeBuilder.AddToScheme +) + +const Kind = "InstanceSet" diff --git a/apis/workloads/v1/instanceset_conversion.go b/apis/workloads/v1/instanceset_conversion.go new file mode 100644 index 00000000000..150890e0211 --- /dev/null +++ b/apis/workloads/v1/instanceset_conversion.go @@ -0,0 +1,22 @@ +/* +Copyright (C) 2022-2024 ApeCloud Co., Ltd + +This file is part of KubeBlocks project + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ + +package v1 + +func (r *InstanceSet) Hub() {} diff --git a/apis/workloads/v1/instanceset_types.go b/apis/workloads/v1/instanceset_types.go new file mode 100644 index 00000000000..549674bc77d --- /dev/null +++ b/apis/workloads/v1/instanceset_types.go @@ -0,0 +1,777 @@ +/* +Copyright (C) 2022-2024 ApeCloud Co., Ltd + +This file is part of KubeBlocks project + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ + +package v1 + +import ( + appsv1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/intstr" +) + +// +genclient +// +kubebuilder:object:root=true +// +kubebuilder:subresource:status +// +kubebuilder:subresource:scale:specpath=.spec.replicas,statuspath=.status.replicas +// +kubebuilder:storageversion +// +kubebuilder:resource:categories={kubeblocks},shortName=its +// +kubebuilder:printcolumn:name="LEADER",type="string",JSONPath=".status.membersStatus[?(@.role.isLeader==true)].podName",description="leader instance name." +// +kubebuilder:printcolumn:name="READY",type="string",JSONPath=".status.readyReplicas",description="ready replicas." +// +kubebuilder:printcolumn:name="REPLICAS",type="string",JSONPath=".status.replicas",description="total replicas." +// +kubebuilder:printcolumn:name="AGE",type="date",JSONPath=".metadata.creationTimestamp" + +// InstanceSet is the Schema for the instancesets API. +type InstanceSet struct { + // The metadata for the type, like API version and kind. + metav1.TypeMeta `json:",inline"` + + // Contains the metadata for the particular object, such as name, namespace, labels, and annotations. + metav1.ObjectMeta `json:"metadata,omitempty"` + + // Defines the desired state of the state machine. It includes the configuration details for the state machine. + // + Spec InstanceSetSpec `json:"spec,omitempty"` + + // Represents the current information about the state machine. This data may be out of date. + // + Status InstanceSetStatus `json:"status,omitempty"` +} + +// +kubebuilder:object:root=true + +// InstanceSetList contains a list of InstanceSet +type InstanceSetList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []InstanceSet `json:"items"` +} + +func init() { + SchemeBuilder.Register(&InstanceSet{}, &InstanceSetList{}) +} + +// InstanceSetSpec defines the desired state of InstanceSet +type InstanceSetSpec struct { + // Specifies the desired number of replicas of the given Template. + // These replicas are instantiations of the same Template, with each having a consistent identity. + // Defaults to 1 if unspecified. + // +kubebuilder:default=1 + // +kubebuilder:validation:Minimum=0 + // +optional + Replicas *int32 `json:"replicas,omitempty"` + + // Specifies the desired Ordinals of the default template. + // The Ordinals used to specify the ordinal of the instance (pod) names to be generated under the default template. + // + // For example, if Ordinals is {ranges: [{start: 0, end: 1}], discrete: [7]}, + // then the instance names generated under the default template would be + // $(cluster.name)-$(component.name)-0、$(cluster.name)-$(component.name)-1 and $(cluster.name)-$(component.name)-7 + DefaultTemplateOrdinals Ordinals `json:"defaultTemplateOrdinals,omitempty"` + + // Defines the minimum number of seconds a newly created pod should be ready + // without any of its container crashing to be considered available. + // Defaults to 0, meaning the pod will be considered available as soon as it is ready. + // +kubebuilder:default=0 + // +kubebuilder:validation:Minimum=0 + // +optional + MinReadySeconds int32 `json:"minReadySeconds,omitempty"` + + // Represents a label query over pods that should match the desired replica count indicated by the `replica` field. + // It must match the labels defined in the pod template. + // More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors + Selector *metav1.LabelSelector `json:"selector"` + + // Defines the behavior of a service spec. + // Provides read-write service. + // https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status + // + // Note: This field will be removed in future version. + // + // +kubebuilder:pruning:PreserveUnknownFields + // +optional + Service *corev1.Service `json:"service,omitempty"` + + Template corev1.PodTemplateSpec `json:"template"` + + // Overrides values in default Template. + // + // Instance is the fundamental unit managed by KubeBlocks. + // It represents a Pod with additional objects such as PVCs, Services, ConfigMaps, etc. + // An InstanceSet manages instances with a total count of Replicas, + // and by default, all these instances are generated from the same template. + // The InstanceTemplate provides a way to override values in the default template, + // allowing the InstanceSet to manage instances from different templates. + // + // The naming convention for instances (pods) based on the InstanceSet Name, InstanceTemplate Name, and ordinal. + // The constructed instance name follows the pattern: $(instance_set.name)-$(template.name)-$(ordinal). + // By default, the ordinal starts from 0 for each InstanceTemplate. + // It is important to ensure that the Name of each InstanceTemplate is unique. + // + // The sum of replicas across all InstanceTemplates should not exceed the total number of Replicas specified for the InstanceSet. + // Any remaining replicas will be generated using the default template and will follow the default naming rules. + // + // +optional + // +patchMergeKey=name + // +patchStrategy=merge,retainKeys + // +listType=map + // +listMapKey=name + Instances []InstanceTemplate `json:"instances,omitempty" patchStrategy:"merge,retainKeys" patchMergeKey:"name"` + + // Specifies the names of instances to be transitioned to offline status. + // + // Marking an instance as offline results in the following: + // + // 1. The associated pod is stopped, and its PersistentVolumeClaim (PVC) is retained for potential + // future reuse or data recovery, but it is no longer actively used. + // 2. The ordinal number assigned to this instance is preserved, ensuring it remains unique + // and avoiding conflicts with new instances. + // + // Setting instances to offline allows for a controlled scale-in process, preserving their data and maintaining + // ordinal consistency within the cluster. + // Note that offline instances and their associated resources, such as PVCs, are not automatically deleted. + // The cluster administrator must manually manage the cleanup and removal of these resources when they are no longer needed. + // + // +optional + OfflineInstances []string `json:"offlineInstances,omitempty"` + + // Specifies a list of PersistentVolumeClaim templates that define the storage requirements for each replica. + // Each template specifies the desired characteristics of a persistent volume, such as storage class, + // size, and access modes. + // These templates are used to dynamically provision persistent volumes for replicas upon their creation. + // The final name of each PVC is generated by appending the pod's identifier to the name specified in volumeClaimTemplates[*].name. + // + // +optional + VolumeClaimTemplates []corev1.PersistentVolumeClaim `json:"volumeClaimTemplates,omitempty"` + + // Controls how pods are created during initial scale up, + // when replacing pods on nodes, or when scaling down. + // + // The default policy is `OrderedReady`, where pods are created in increasing order and the controller waits until each pod is ready before + // continuing. When scaling down, the pods are removed in the opposite order. + // The alternative policy is `Parallel` which will create pods in parallel + // to match the desired scale without waiting, and on scale down will delete + // all pods at once. + // + // Note: This field will be removed in future version. + // + // +optional + PodManagementPolicy appsv1.PodManagementPolicyType `json:"podManagementPolicy,omitempty"` + + // Controls the concurrency of pods during initial scale up, when replacing pods on nodes, + // or when scaling down. It only used when `PodManagementPolicy` is set to `Parallel`. + // The default Concurrency is 100%. + // + // +optional + ParallelPodManagementConcurrency *intstr.IntOrString `json:"parallelPodManagementConcurrency,omitempty"` + + // PodUpdatePolicy indicates how pods should be updated + // + // - `StrictInPlace` indicates that only allows in-place upgrades. + // Any attempt to modify other fields will be rejected. + // - `PreferInPlace` indicates that we will first attempt an in-place upgrade of the Pod. + // If that fails, it will fall back to the ReCreate, where pod will be recreated. + // Default value is "PreferInPlace" + // + // +optional + PodUpdatePolicy PodUpdatePolicyType `json:"podUpdatePolicy,omitempty"` + + // Indicates the StatefulSetUpdateStrategy that will be + // employed to update Pods in the InstanceSet when a revision is made to + // Template. + // UpdateStrategy.Type will be set to appsv1.OnDeleteStatefulSetStrategyType if MemberUpdateStrategy is not nil + // + // Note: This field will be removed in future version. + UpdateStrategy appsv1.StatefulSetUpdateStrategy `json:"updateStrategy,omitempty"` + + // A list of roles defined in the system. + // + // +optional + Roles []ReplicaRole `json:"roles,omitempty"` + + // Provides method to probe role. + // + // +optional + RoleProbe *RoleProbe `json:"roleProbe,omitempty"` + + // Provides actions to do membership dynamic reconfiguration. + // + // +optional + MembershipReconfiguration *MembershipReconfiguration `json:"membershipReconfiguration,omitempty"` + + // Members(Pods) update strategy. + // + // - serial: update Members one by one that guarantee minimum component unavailable time. + // - bestEffortParallel: update Members in parallel that guarantee minimum component un-writable time. + // - parallel: force parallel + // + // +kubebuilder:validation:Enum={Serial,BestEffortParallel,Parallel} + // +optional + MemberUpdateStrategy *MemberUpdateStrategy `json:"memberUpdateStrategy,omitempty"` + + // Indicates that the InstanceSet is paused, meaning the reconciliation of this InstanceSet object will be paused. + // +optional + Paused bool `json:"paused,omitempty"` + + // Credential used to connect to DB engine + // + // +optional + Credential *Credential `json:"credential,omitempty"` +} + +// InstanceSetStatus defines the observed state of InstanceSet +type InstanceSetStatus struct { + // observedGeneration is the most recent generation observed for this InstanceSet. It corresponds to the + // InstanceSet's generation, which is updated on mutation by the API Server. + // + // +optional + ObservedGeneration int64 `json:"observedGeneration,omitempty"` + + // replicas is the number of instances created by the InstanceSet controller. + Replicas int32 `json:"replicas"` + + // readyReplicas is the number of instances created for this InstanceSet with a Ready Condition. + ReadyReplicas int32 `json:"readyReplicas,omitempty"` + + // currentReplicas is the number of instances created by the InstanceSet controller from the InstanceSet version + // indicated by CurrentRevisions. + CurrentReplicas int32 `json:"currentReplicas,omitempty"` + + // updatedReplicas is the number of instances created by the InstanceSet controller from the InstanceSet version + // indicated by UpdateRevisions. + UpdatedReplicas int32 `json:"updatedReplicas,omitempty"` + + // currentRevision, if not empty, indicates the version of the InstanceSet used to generate instances in the + // sequence [0,currentReplicas). + CurrentRevision string `json:"currentRevision,omitempty"` + + // updateRevision, if not empty, indicates the version of the InstanceSet used to generate instances in the sequence + // [replicas-updatedReplicas,replicas) + UpdateRevision string `json:"updateRevision,omitempty"` + + // Represents the latest available observations of an instanceset's current state. + // Known .status.conditions.type are: "InstanceFailure", "InstanceReady" + // + // +optional + // +patchMergeKey=type + // +patchStrategy=merge + // +listType=map + // +listMapKey=type + Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type"` + + // Total number of available instances (ready for at least minReadySeconds) targeted by this InstanceSet. + // + // +optional + AvailableReplicas int32 `json:"availableReplicas"` + + // Defines the initial number of instances when the cluster is first initialized. + // This value is set to spec.Replicas at the time of object creation and remains constant thereafter. + // Used only when spec.roles set. + // + // +optional + InitReplicas int32 `json:"initReplicas"` + + // Represents the number of instances that have already reached the MembersStatus during the cluster initialization stage. + // This value remains constant once it equals InitReplicas. + // Used only when spec.roles set. + // + // +optional + ReadyInitReplicas int32 `json:"readyInitReplicas,omitempty"` + + // Provides the status of each member in the cluster. + // + // +optional + MembersStatus []MemberStatus `json:"membersStatus,omitempty"` + + // Indicates whether it is required for the InstanceSet to have at least one primary instance ready. + // + // +optional + ReadyWithoutPrimary bool `json:"readyWithoutPrimary,omitempty"` + + // currentRevisions, if not empty, indicates the old version of the InstanceSet used to generate the underlying workload. + // key is the pod name, value is the revision. + // + // +optional + CurrentRevisions map[string]string `json:"currentRevisions,omitempty"` + + // updateRevisions, if not empty, indicates the new version of the InstanceSet used to generate the underlying workload. + // key is the pod name, value is the revision. + // + // +optional + UpdateRevisions map[string]string `json:"updateRevisions,omitempty"` + + // TemplatesStatus represents status of each instance generated by InstanceTemplates + // +optional + TemplatesStatus []InstanceTemplateStatus `json:"templatesStatus,omitempty"` +} + +// Range represents a range with a start and an end value. +// It is used to define a continuous segment. +type Range struct { + Start int32 `json:"start"` + End int32 `json:"end"` +} + +// Ordinals represents a combination of continuous segments and individual values. +type Ordinals struct { + Ranges []Range `json:"ranges,omitempty"` + Discrete []int32 `json:"discrete,omitempty"` +} + +// InstanceTemplate allows customization of individual replica configurations within a Component, +// without altering the base component template defined in ClusterComponentSpec. +// It enables the application of distinct settings to specific instances (replicas), +// providing flexibility while maintaining a common configuration baseline. +type InstanceTemplate struct { + // Name specifies the unique name of the instance Pod created using this InstanceTemplate. + // This name is constructed by concatenating the component's name, the template's name, and the instance's ordinal + // using the pattern: $(cluster.name)-$(component.name)-$(template.name)-$(ordinal). Ordinals start from 0. + // The specified name overrides any default naming conventions or patterns. + // + // +kubebuilder:validation:MaxLength=54 + // +kubebuilder:validation:Pattern:=`^[a-z0-9]([a-z0-9\.\-]*[a-z0-9])?$` + // +kubebuilder:validation:Required + Name string `json:"name"` + + // Specifies the number of instances (Pods) to create from this InstanceTemplate. + // This field allows setting how many replicated instances of the component, + // with the specific overrides in the InstanceTemplate, are created. + // The default value is 1. A value of 0 disables instance creation. + // + // +kubebuilder:default=1 + // +kubebuilder:validation:Minimum=0 + // +optional + Replicas *int32 `json:"replicas,omitempty"` + + // Specifies the desired Ordinals of this InstanceTemplate. + // The Ordinals used to specify the ordinal of the instance (pod) names to be generated under this InstanceTemplate. + // + // For example, if Ordinals is {ranges: [{start: 0, end: 1}], discrete: [7]}, + // then the instance names generated under this InstanceTemplate would be + // $(cluster.name)-$(component.name)-$(template.name)-0、$(cluster.name)-$(component.name)-$(template.name)-1 and + // $(cluster.name)-$(component.name)-$(template.name)-7 + Ordinals Ordinals `json:"ordinals,omitempty"` + + // Specifies a map of key-value pairs to be merged into the Pod's existing annotations. + // Existing keys will have their values overwritten, while new keys will be added to the annotations. + // + // +optional + Annotations map[string]string `json:"annotations,omitempty"` + + // Specifies a map of key-value pairs that will be merged into the Pod's existing labels. + // Values for existing keys will be overwritten, and new keys will be added. + // + // +optional + Labels map[string]string `json:"labels,omitempty"` + + // Specifies an override for the first container's image in the pod. + // + // +optional + Image *string `json:"image,omitempty"` + + // Specifies the scheduling policy for the Component. + // + // +optional + SchedulingPolicy *SchedulingPolicy `json:"schedulingPolicy,omitempty"` + + // Specifies an override for the resource requirements of the first container in the Pod. + // This field allows for customizing resource allocation (CPU, memory, etc.) for the container. + // + // +optional + Resources *corev1.ResourceRequirements `json:"resources,omitempty"` + + // Defines Env to override. + // Add new or override existing envs. + // +optional + Env []corev1.EnvVar `json:"env,omitempty"` + + // Defines Volumes to override. + // Add new or override existing volumes. + // +optional + Volumes []corev1.Volume `json:"volumes,omitempty"` + + // Defines VolumeMounts to override. + // Add new or override existing volume mounts of the first container in the pod. + // +optional + VolumeMounts []corev1.VolumeMount `json:"volumeMounts,omitempty"` + + // Defines VolumeClaimTemplates to override. + // Add new or override existing volume claim templates. + // +optional + VolumeClaimTemplates []corev1.PersistentVolumeClaim `json:"volumeClaimTemplates,omitempty"` +} + +// SchedulingPolicy the scheduling policy. +// Deprecated: Unify with apps/v1alpha1.SchedulingPolicy +type SchedulingPolicy struct { + // If specified, the Pod will be dispatched by specified scheduler. + // If not specified, the Pod will be dispatched by default scheduler. + // + // +optional + SchedulerName string `json:"schedulerName,omitempty"` + + // NodeSelector is a selector which must be true for the Pod to fit on a node. + // Selector which must match a node's labels for the Pod to be scheduled on that node. + // More info: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ + // + // +optional + // +mapType=atomic + NodeSelector map[string]string `json:"nodeSelector,omitempty"` + + // NodeName is a request to schedule this Pod onto a specific node. If it is non-empty, + // the scheduler simply schedules this Pod onto that node, assuming that it fits resource + // requirements. + // + // +optional + NodeName string `json:"nodeName,omitempty"` + + // Specifies a group of affinity scheduling rules of the Cluster, including NodeAffinity, PodAffinity, and PodAntiAffinity. + // + // +optional + Affinity *corev1.Affinity `json:"affinity,omitempty"` + + // Allows Pods to be scheduled onto nodes with matching taints. + // Each toleration in the array allows the Pod to tolerate node taints based on + // specified `key`, `value`, `effect`, and `operator`. + // + // - The `key`, `value`, and `effect` identify the taint that the toleration matches. + // - The `operator` determines how the toleration matches the taint. + // + // Pods with matching tolerations are allowed to be scheduled on tainted nodes, typically reserved for specific purposes. + // + // +optional + Tolerations []corev1.Toleration `json:"tolerations,omitempty"` + + // TopologySpreadConstraints describes how a group of Pods ought to spread across topology + // domains. Scheduler will schedule Pods in a way which abides by the constraints. + // All topologySpreadConstraints are ANDed. + // + // +optional + TopologySpreadConstraints []corev1.TopologySpreadConstraint `json:"topologySpreadConstraints,omitempty"` +} + +type PodUpdatePolicyType string + +const ( + // StrictInPlacePodUpdatePolicyType indicates that only allows in-place upgrades. + // Any attempt to modify other fields will be rejected. + StrictInPlacePodUpdatePolicyType PodUpdatePolicyType = "StrictInPlace" + + // PreferInPlacePodUpdatePolicyType indicates that we will first attempt an in-place upgrade of the Pod. + // If that fails, it will fall back to the ReCreate, where pod will be recreated. + PreferInPlacePodUpdatePolicyType PodUpdatePolicyType = "PreferInPlace" +) + +type ReplicaRole struct { + + // Defines the role name of the replica. + // + // +kubebuilder:validation:Required + // +kubebuilder:default=leader + Name string `json:"name"` + + // Specifies the service capabilities of this member. + // + // +kubebuilder:validation:Required + // +kubebuilder:default=ReadWrite + // +kubebuilder:validation:Enum={None, Readonly, ReadWrite} + AccessMode AccessMode `json:"accessMode"` + + // Indicates if this member has voting rights. + // + // +kubebuilder:default=true + // +optional + CanVote bool `json:"canVote"` + + // Determines if this member is the leader. + // + // +kubebuilder:default=false + // +optional + IsLeader bool `json:"isLeader"` +} + +// AccessMode defines SVC access mode enums. +// +enum +type AccessMode string + +const ( + ReadWriteMode AccessMode = "ReadWrite" + ReadonlyMode AccessMode = "Readonly" + NoneMode AccessMode = "None" +) + +// RoleProbe defines how to observe role +type RoleProbe struct { + // Defines a custom method for role probing. + // Actions defined here are executed in series. + // Upon completion of all actions, the final output should be a single string representing the role name defined in spec.Roles. + // The latest [BusyBox](https://busybox.net/) image will be used if Image is not configured. + // Environment variables can be used in Command: + // - v_KB_ITS_LAST_STDOUT: stdout from the last action, watch for 'v_' prefix + // - KB_ITS_USERNAME: username part of the credential + // - KB_ITS_PASSWORD: password part of the credential + // + // +optional + CustomHandler []Action `json:"customHandler,omitempty"` + + // Specifies the number of seconds to wait after the container has started before initiating role probing. + // + // +kubebuilder:default=0 + // +kubebuilder:validation:Minimum=0 + // +optional + InitialDelaySeconds int32 `json:"initialDelaySeconds,omitempty"` + + // Specifies the number of seconds after which the probe times out. + // + // +kubebuilder:default=1 + // +kubebuilder:validation:Minimum=1 + // +optional + TimeoutSeconds int32 `json:"timeoutSeconds,omitempty"` + + // Specifies the frequency (in seconds) of probe execution. + // + // +kubebuilder:default=2 + // +kubebuilder:validation:Minimum=1 + // +optional + PeriodSeconds int32 `json:"periodSeconds,omitempty"` + + // Specifies the minimum number of consecutive successes for the probe to be considered successful after having failed. + // + // +kubebuilder:default=1 + // +kubebuilder:validation:Minimum=1 + // +optional + SuccessThreshold int32 `json:"successThreshold,omitempty"` + + // Specifies the minimum number of consecutive failures for the probe to be considered failed after having succeeded. + // + // +kubebuilder:default=3 + // +kubebuilder:validation:Minimum=1 + // +optional + FailureThreshold int32 `json:"failureThreshold,omitempty"` + + // Specifies the method for updating the pod role label. + // + // +kubebuilder:default=ReadinessProbeEventUpdate + // +kubebuilder:validation:Enum={ReadinessProbeEventUpdate, DirectAPIServerEventUpdate} + // +optional + RoleUpdateMechanism RoleUpdateMechanism `json:"roleUpdateMechanism,omitempty"` +} + +type Action struct { + // Refers to the utility image that contains the command which can be utilized to retrieve or process role information. + // + // +optional + Image string `json:"image,omitempty"` + + // A set of instructions that will be executed within the Container to retrieve or process role information. This field is required. + // + // +kubebuilder:validation:Required + Command []string `json:"command"` + + // Additional parameters used to perform specific statements. This field is optional. + // + // +optional + Args []string `json:"args,omitempty"` +} + +// RoleUpdateMechanism defines the way how pod role label being updated. +// +enum +type RoleUpdateMechanism string + +const ( + ReadinessProbeEventUpdate RoleUpdateMechanism = "ReadinessProbeEventUpdate" + DirectAPIServerEventUpdate RoleUpdateMechanism = "DirectAPIServerEventUpdate" +) + +type MembershipReconfiguration struct { + // Specifies the environment variables that can be used in all following Actions: + // - KB_ITS_USERNAME: Represents the username part of the credential + // - KB_ITS_PASSWORD: Represents the password part of the credential + // - KB_ITS_LEADER_HOST: Represents the leader host + // - KB_ITS_TARGET_HOST: Represents the target host + // - KB_ITS_SERVICE_PORT: Represents the service port + // + // Defines the action to perform a switchover. + // If the Image is not configured, the latest [BusyBox](https://busybox.net/) image will be used. + // + // +optional + SwitchoverAction *Action `json:"switchoverAction,omitempty"` + + // Defines the action to add a member. + // If the Image is not configured, the Image from the previous non-nil action will be used. + // + // +optional + MemberJoinAction *Action `json:"memberJoinAction,omitempty"` + + // Defines the action to remove a member. + // If the Image is not configured, the Image from the previous non-nil action will be used. + // + // +optional + MemberLeaveAction *Action `json:"memberLeaveAction,omitempty"` + + // Defines the action to trigger the new member to start log syncing. + // If the Image is not configured, the Image from the previous non-nil action will be used. + // + // +optional + LogSyncAction *Action `json:"logSyncAction,omitempty"` + + // Defines the action to inform the cluster that the new member can join voting now. + // If the Image is not configured, the Image from the previous non-nil action will be used. + // + // +optional + PromoteAction *Action `json:"promoteAction,omitempty"` +} + +// MemberUpdateStrategy defines Cluster Component update strategy. +// +enum +type MemberUpdateStrategy string + +const ( + SerialUpdateStrategy MemberUpdateStrategy = "Serial" + BestEffortParallelUpdateStrategy MemberUpdateStrategy = "BestEffortParallel" + ParallelUpdateStrategy MemberUpdateStrategy = "Parallel" +) + +type Credential struct { + // Defines the user's name for the credential. + // The corresponding environment variable will be KB_ITS_USERNAME. + // + // +kubebuilder:validation:Required + Username CredentialVar `json:"username"` + + // Represents the user's password for the credential. + // The corresponding environment variable will be KB_ITS_PASSWORD. + // + // +kubebuilder:validation:Required + Password CredentialVar `json:"password"` +} + +type CredentialVar struct { + // Specifies the value of the environment variable. This field is optional and defaults to an empty string. + // The value can include variable references in the format $(VAR_NAME) which will be expanded using previously defined environment variables in the container and any service environment variables. + // + // If a variable cannot be resolved, the reference in the input string will remain unchanged. + // Double $$ can be used to escape the $(VAR_NAME) syntax, resulting in a single $ and producing the string literal "$(VAR_NAME)". + // Escaped references will not be expanded, regardless of whether the variable exists or not. + // + // +optional + Value string `json:"value,omitempty"` + + // Defines the source for the environment variable's value. This field is optional and cannot be used if the 'Value' field is not empty. + // + // +optional + ValueFrom *corev1.EnvVarSource `json:"valueFrom,omitempty"` +} + +type MemberStatus struct { + // Represents the name of the pod. + // + // +kubebuilder:validation:Required + // +kubebuilder:default=Unknown + PodName string `json:"podName"` + + // Defines the role of the replica in the cluster. + // + // +optional + ReplicaRole *ReplicaRole `json:"role,omitempty"` +} + +// InstanceTemplateStatus aggregates the status of replicas for each InstanceTemplate +type InstanceTemplateStatus struct { + // Name, the name of the InstanceTemplate. + Name string `json:"name"` + + // Replicas is the number of replicas of the InstanceTemplate. + // +optional + Replicas int32 `json:"replicas,omitempty"` + + // ReadyReplicas is the number of Pods that have a Ready Condition. + // +optional + ReadyReplicas int32 `json:"readyReplicas,omitempty"` + + // AvailableReplicas is the number of Pods that ready for at least minReadySeconds. + // +optional + AvailableReplicas int32 `json:"availableReplicas,omitempty"` + + // currentReplicas is the number of instances created by the InstanceSet controller from the InstanceSet version + // indicated by CurrentRevisions. + CurrentReplicas int32 `json:"currentReplicas,omitempty"` + + // UpdatedReplicas is the number of Pods created by the InstanceSet controller from the InstanceSet version + // indicated by UpdateRevisions. + // +optional + UpdatedReplicas int32 `json:"updatedReplicas,omitempty"` +} + +type ConditionType string + +const ( + // InstanceReady is added in an instance set when at least one of its instances(pods) is in a Ready condition. + // ConditionStatus will be True if all its instances(pods) are in a Ready condition. + // Or, a NotReady reason with not ready instances encoded in the Message filed will be set. + InstanceReady ConditionType = "InstanceReady" + + // InstanceAvailable ConditionStatus will be True if all instances(pods) are in the ready condition + // and continue for "MinReadySeconds" seconds. Otherwise, it will be set to False. + InstanceAvailable ConditionType = "InstanceAvailable" + + // InstanceFailure is added in an instance set when at least one of its instances(pods) is in a `Failed` phase. + InstanceFailure ConditionType = "InstanceFailure" + + // InstanceUpdateRestricted represents a ConditionType that indicates updates to an InstanceSet are blocked(when the + // PodUpdatePolicy is set to StrictInPlace but the pods cannot be updated in-place). + InstanceUpdateRestricted ConditionType = "InstanceUpdateRestricted" +) + +const ( + // ReasonNotReady is a reason for condition InstanceReady. + ReasonNotReady = "NotReady" + + // ReasonReady is a reason for condition InstanceReady. + ReasonReady = "Ready" + + // ReasonNotAvailable is a reason for condition InstanceAvailable. + ReasonNotAvailable = "NotAvailable" + + // ReasonAvailable is a reason for condition InstanceAvailable. + ReasonAvailable = "Available" + + // ReasonInstanceFailure is a reason for condition InstanceFailure. + ReasonInstanceFailure = "InstanceFailure" + + // ReasonInstanceUpdateRestricted is a reason for condition InstanceUpdateRestricted. + ReasonInstanceUpdateRestricted = "InstanceUpdateRestricted" +) + +const defaultInstanceTemplateReplicas = 1 + +func (t *InstanceTemplate) GetName() string { + return t.Name +} + +func (t *InstanceTemplate) GetReplicas() int32 { + if t.Replicas != nil { + return *t.Replicas + } + return defaultInstanceTemplateReplicas +} + +func (t *InstanceTemplate) GetOrdinals() Ordinals { + return t.Ordinals +} diff --git a/apis/workloads/v1/instanceset_webhook.go b/apis/workloads/v1/instanceset_webhook.go new file mode 100644 index 00000000000..1a7b7d8e978 --- /dev/null +++ b/apis/workloads/v1/instanceset_webhook.go @@ -0,0 +1,35 @@ +/* +Copyright (C) 2022-2024 ApeCloud Co., Ltd + +This file is part of KubeBlocks project + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ + +package v1 + +import ( + ctrl "sigs.k8s.io/controller-runtime" +) + +// log is for logging in this package. +// var instancesetlog = logf.Log.WithName("instanceset-resource") + +func (r *InstanceSet) SetupWebhookWithManager(mgr ctrl.Manager) error { + return ctrl.NewWebhookManagedBy(mgr). + For(r). + Complete() +} + +// TODO(user): EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! diff --git a/apis/workloads/v1/register.go b/apis/workloads/v1/register.go new file mode 100644 index 00000000000..93633c70d4a --- /dev/null +++ b/apis/workloads/v1/register.go @@ -0,0 +1,29 @@ +/* +Copyright (C) 2022-2024 ApeCloud Co., Ltd + +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 v1 + +import ( + "k8s.io/apimachinery/pkg/runtime/schema" +) + +// SchemeGroupVersion is group version used to register these objects. +var SchemeGroupVersion = GroupVersion + +// Resource takes an unqualified resource and returns a Group qualified GroupResource +func Resource(resource string) schema.GroupResource { + return SchemeGroupVersion.WithResource(resource).GroupResource() +} diff --git a/apis/workloads/v1/zz_generated.deepcopy.go b/apis/workloads/v1/zz_generated.deepcopy.go new file mode 100644 index 00000000000..11c0d58e301 --- /dev/null +++ b/apis/workloads/v1/zz_generated.deepcopy.go @@ -0,0 +1,553 @@ +//go:build !ignore_autogenerated + +/* +Copyright (C) 2022-2024 ApeCloud Co., Ltd + +This file is part of KubeBlocks project + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ + +// Code generated by controller-gen. DO NOT EDIT. + +package v1 + +import ( + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/util/intstr" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Action) DeepCopyInto(out *Action) { + *out = *in + if in.Command != nil { + in, out := &in.Command, &out.Command + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.Args != nil { + in, out := &in.Args, &out.Args + *out = make([]string, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Action. +func (in *Action) DeepCopy() *Action { + if in == nil { + return nil + } + out := new(Action) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Credential) DeepCopyInto(out *Credential) { + *out = *in + in.Username.DeepCopyInto(&out.Username) + in.Password.DeepCopyInto(&out.Password) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Credential. +func (in *Credential) DeepCopy() *Credential { + if in == nil { + return nil + } + out := new(Credential) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CredentialVar) DeepCopyInto(out *CredentialVar) { + *out = *in + if in.ValueFrom != nil { + in, out := &in.ValueFrom, &out.ValueFrom + *out = new(corev1.EnvVarSource) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CredentialVar. +func (in *CredentialVar) DeepCopy() *CredentialVar { + if in == nil { + return nil + } + out := new(CredentialVar) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *InstanceSet) DeepCopyInto(out *InstanceSet) { + *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 InstanceSet. +func (in *InstanceSet) DeepCopy() *InstanceSet { + if in == nil { + return nil + } + out := new(InstanceSet) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *InstanceSet) 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 *InstanceSetList) DeepCopyInto(out *InstanceSetList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]InstanceSet, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InstanceSetList. +func (in *InstanceSetList) DeepCopy() *InstanceSetList { + if in == nil { + return nil + } + out := new(InstanceSetList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *InstanceSetList) 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 *InstanceSetSpec) DeepCopyInto(out *InstanceSetSpec) { + *out = *in + if in.Replicas != nil { + in, out := &in.Replicas, &out.Replicas + *out = new(int32) + **out = **in + } + in.DefaultTemplateOrdinals.DeepCopyInto(&out.DefaultTemplateOrdinals) + if in.Selector != nil { + in, out := &in.Selector, &out.Selector + *out = new(metav1.LabelSelector) + (*in).DeepCopyInto(*out) + } + if in.Service != nil { + in, out := &in.Service, &out.Service + *out = new(corev1.Service) + (*in).DeepCopyInto(*out) + } + in.Template.DeepCopyInto(&out.Template) + if in.Instances != nil { + in, out := &in.Instances, &out.Instances + *out = make([]InstanceTemplate, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.OfflineInstances != nil { + in, out := &in.OfflineInstances, &out.OfflineInstances + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.VolumeClaimTemplates != nil { + in, out := &in.VolumeClaimTemplates, &out.VolumeClaimTemplates + *out = make([]corev1.PersistentVolumeClaim, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.ParallelPodManagementConcurrency != nil { + in, out := &in.ParallelPodManagementConcurrency, &out.ParallelPodManagementConcurrency + *out = new(intstr.IntOrString) + **out = **in + } + in.UpdateStrategy.DeepCopyInto(&out.UpdateStrategy) + if in.Roles != nil { + in, out := &in.Roles, &out.Roles + *out = make([]ReplicaRole, len(*in)) + copy(*out, *in) + } + if in.RoleProbe != nil { + in, out := &in.RoleProbe, &out.RoleProbe + *out = new(RoleProbe) + (*in).DeepCopyInto(*out) + } + if in.MembershipReconfiguration != nil { + in, out := &in.MembershipReconfiguration, &out.MembershipReconfiguration + *out = new(MembershipReconfiguration) + (*in).DeepCopyInto(*out) + } + if in.MemberUpdateStrategy != nil { + in, out := &in.MemberUpdateStrategy, &out.MemberUpdateStrategy + *out = new(MemberUpdateStrategy) + **out = **in + } + if in.Credential != nil { + in, out := &in.Credential, &out.Credential + *out = new(Credential) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InstanceSetSpec. +func (in *InstanceSetSpec) DeepCopy() *InstanceSetSpec { + if in == nil { + return nil + } + out := new(InstanceSetSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *InstanceSetStatus) DeepCopyInto(out *InstanceSetStatus) { + *out = *in + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]metav1.Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.MembersStatus != nil { + in, out := &in.MembersStatus, &out.MembersStatus + *out = make([]MemberStatus, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.CurrentRevisions != nil { + in, out := &in.CurrentRevisions, &out.CurrentRevisions + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.UpdateRevisions != nil { + in, out := &in.UpdateRevisions, &out.UpdateRevisions + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.TemplatesStatus != nil { + in, out := &in.TemplatesStatus, &out.TemplatesStatus + *out = make([]InstanceTemplateStatus, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InstanceSetStatus. +func (in *InstanceSetStatus) DeepCopy() *InstanceSetStatus { + if in == nil { + return nil + } + out := new(InstanceSetStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *InstanceTemplate) DeepCopyInto(out *InstanceTemplate) { + *out = *in + if in.Replicas != nil { + in, out := &in.Replicas, &out.Replicas + *out = new(int32) + **out = **in + } + in.Ordinals.DeepCopyInto(&out.Ordinals) + if in.Annotations != nil { + in, out := &in.Annotations, &out.Annotations + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.Labels != nil { + in, out := &in.Labels, &out.Labels + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.Image != nil { + in, out := &in.Image, &out.Image + *out = new(string) + **out = **in + } + if in.SchedulingPolicy != nil { + in, out := &in.SchedulingPolicy, &out.SchedulingPolicy + *out = new(SchedulingPolicy) + (*in).DeepCopyInto(*out) + } + if in.Resources != nil { + in, out := &in.Resources, &out.Resources + *out = new(corev1.ResourceRequirements) + (*in).DeepCopyInto(*out) + } + if in.Env != nil { + in, out := &in.Env, &out.Env + *out = make([]corev1.EnvVar, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.Volumes != nil { + in, out := &in.Volumes, &out.Volumes + *out = make([]corev1.Volume, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.VolumeMounts != nil { + in, out := &in.VolumeMounts, &out.VolumeMounts + *out = make([]corev1.VolumeMount, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.VolumeClaimTemplates != nil { + in, out := &in.VolumeClaimTemplates, &out.VolumeClaimTemplates + *out = make([]corev1.PersistentVolumeClaim, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InstanceTemplate. +func (in *InstanceTemplate) DeepCopy() *InstanceTemplate { + if in == nil { + return nil + } + out := new(InstanceTemplate) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *InstanceTemplateStatus) DeepCopyInto(out *InstanceTemplateStatus) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InstanceTemplateStatus. +func (in *InstanceTemplateStatus) DeepCopy() *InstanceTemplateStatus { + if in == nil { + return nil + } + out := new(InstanceTemplateStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MemberStatus) DeepCopyInto(out *MemberStatus) { + *out = *in + if in.ReplicaRole != nil { + in, out := &in.ReplicaRole, &out.ReplicaRole + *out = new(ReplicaRole) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MemberStatus. +func (in *MemberStatus) DeepCopy() *MemberStatus { + if in == nil { + return nil + } + out := new(MemberStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MembershipReconfiguration) DeepCopyInto(out *MembershipReconfiguration) { + *out = *in + if in.SwitchoverAction != nil { + in, out := &in.SwitchoverAction, &out.SwitchoverAction + *out = new(Action) + (*in).DeepCopyInto(*out) + } + if in.MemberJoinAction != nil { + in, out := &in.MemberJoinAction, &out.MemberJoinAction + *out = new(Action) + (*in).DeepCopyInto(*out) + } + if in.MemberLeaveAction != nil { + in, out := &in.MemberLeaveAction, &out.MemberLeaveAction + *out = new(Action) + (*in).DeepCopyInto(*out) + } + if in.LogSyncAction != nil { + in, out := &in.LogSyncAction, &out.LogSyncAction + *out = new(Action) + (*in).DeepCopyInto(*out) + } + if in.PromoteAction != nil { + in, out := &in.PromoteAction, &out.PromoteAction + *out = new(Action) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MembershipReconfiguration. +func (in *MembershipReconfiguration) DeepCopy() *MembershipReconfiguration { + if in == nil { + return nil + } + out := new(MembershipReconfiguration) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Ordinals) DeepCopyInto(out *Ordinals) { + *out = *in + if in.Ranges != nil { + in, out := &in.Ranges, &out.Ranges + *out = make([]Range, len(*in)) + copy(*out, *in) + } + if in.Discrete != nil { + in, out := &in.Discrete, &out.Discrete + *out = make([]int32, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Ordinals. +func (in *Ordinals) DeepCopy() *Ordinals { + if in == nil { + return nil + } + out := new(Ordinals) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Range) DeepCopyInto(out *Range) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Range. +func (in *Range) DeepCopy() *Range { + if in == nil { + return nil + } + out := new(Range) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ReplicaRole) DeepCopyInto(out *ReplicaRole) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ReplicaRole. +func (in *ReplicaRole) DeepCopy() *ReplicaRole { + if in == nil { + return nil + } + out := new(ReplicaRole) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RoleProbe) DeepCopyInto(out *RoleProbe) { + *out = *in + if in.CustomHandler != nil { + in, out := &in.CustomHandler, &out.CustomHandler + *out = make([]Action, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RoleProbe. +func (in *RoleProbe) DeepCopy() *RoleProbe { + if in == nil { + return nil + } + out := new(RoleProbe) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SchedulingPolicy) DeepCopyInto(out *SchedulingPolicy) { + *out = *in + if in.NodeSelector != nil { + in, out := &in.NodeSelector, &out.NodeSelector + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.Affinity != nil { + in, out := &in.Affinity, &out.Affinity + *out = new(corev1.Affinity) + (*in).DeepCopyInto(*out) + } + if in.Tolerations != nil { + in, out := &in.Tolerations, &out.Tolerations + *out = make([]corev1.Toleration, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.TopologySpreadConstraints != nil { + in, out := &in.TopologySpreadConstraints, &out.TopologySpreadConstraints + *out = make([]corev1.TopologySpreadConstraint, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SchedulingPolicy. +func (in *SchedulingPolicy) DeepCopy() *SchedulingPolicy { + if in == nil { + return nil + } + out := new(SchedulingPolicy) + in.DeepCopyInto(out) + return out +} diff --git a/apis/workloads/v1alpha1/instanceset_conversion.go b/apis/workloads/v1alpha1/instanceset_conversion.go new file mode 100644 index 00000000000..5b7696ae75b --- /dev/null +++ b/apis/workloads/v1alpha1/instanceset_conversion.go @@ -0,0 +1,34 @@ +/* +Copyright (C) 2022-2024 ApeCloud Co., Ltd + +This file is part of KubeBlocks project + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ + +package v1alpha1 + +import ( + "sigs.k8s.io/controller-runtime/pkg/conversion" +) + +// ConvertTo converts this InstanceSet to the Hub version (v1). +func (r *InstanceSet) ConvertTo(dstRaw conversion.Hub) error { + return nil +} + +// ConvertFrom converts from the Hub version (v1) to this version. +func (r *InstanceSet) ConvertFrom(srcRaw conversion.Hub) error { + return nil +} diff --git a/cmd/manager/main.go b/cmd/manager/main.go index 115b0e78040..41c3bb4de93 100644 --- a/cmd/manager/main.go +++ b/cmd/manager/main.go @@ -56,6 +56,7 @@ import ( experimentalv1alpha1 "github.com/apecloud/kubeblocks/apis/experimental/v1alpha1" extensionsv1alpha1 "github.com/apecloud/kubeblocks/apis/extensions/v1alpha1" "github.com/apecloud/kubeblocks/apis/workloads/legacy" + workloadsv1 "github.com/apecloud/kubeblocks/apis/workloads/v1" workloadsv1alpha1 "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" appscontrollers "github.com/apecloud/kubeblocks/controllers/apps" "github.com/apecloud/kubeblocks/controllers/apps/configuration" @@ -110,6 +111,7 @@ func init() { utilruntime.Must(snapshotv1beta1.AddToScheme(scheme)) utilruntime.Must(extensionsv1alpha1.AddToScheme(scheme)) utilruntime.Must(workloadsv1alpha1.AddToScheme(scheme)) + utilruntime.Must(workloadsv1.AddToScheme(scheme)) utilruntime.Must(legacy.AddToScheme(scheme)) utilruntime.Must(apiextv1.AddToScheme(scheme)) utilruntime.Must(experimentalv1alpha1.AddToScheme(scheme)) @@ -545,6 +547,10 @@ func main() { setupLog.Error(err, "unable to create webhook", "webhook", "Component") os.Exit(1) } + if err = (&workloadsv1.InstanceSet{}).SetupWebhookWithManager(mgr); err != nil { + setupLog.Error(err, "unable to create webhook", "webhook", "InstanceSet") + os.Exit(1) + } if err = (&appsv1.ServiceDescriptor{}).SetupWebhookWithManager(mgr); err != nil { setupLog.Error(err, "unable to create webhook", "webhook", "ServiceDescriptor") os.Exit(1) diff --git a/config/crd/bases/workloads.kubeblocks.io_instancesets.yaml b/config/crd/bases/workloads.kubeblocks.io_instancesets.yaml index 85bfcf29ab5..ae79ae18c17 100644 --- a/config/crd/bases/workloads.kubeblocks.io_instancesets.yaml +++ b/config/crd/bases/workloads.kubeblocks.io_instancesets.yaml @@ -19,6 +19,13085 @@ spec: singular: instanceset scope: Namespaced versions: + - additionalPrinterColumns: + - description: leader instance name. + jsonPath: .status.membersStatus[?(@.role.isLeader==true)].podName + name: LEADER + type: string + - description: ready replicas. + jsonPath: .status.readyReplicas + name: READY + type: string + - description: total replicas. + jsonPath: .status.replicas + name: REPLICAS + type: string + - jsonPath: .metadata.creationTimestamp + name: AGE + type: date + name: v1 + schema: + openAPIV3Schema: + description: InstanceSet is the Schema for the instancesets 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: Defines the desired state of the state machine. It includes + the configuration details for the state machine. + properties: + credential: + description: Credential used to connect to DB engine + properties: + password: + description: |- + Represents the user's password for the credential. + The corresponding environment variable will be KB_ITS_PASSWORD. + properties: + value: + description: |- + Specifies the value of the environment variable. This field is optional and defaults to an empty string. + The value can include variable references in the format $(VAR_NAME) which will be expanded using previously defined environment variables in the container and any service environment variables. + + + If a variable cannot be resolved, the reference in the input string will remain unchanged. + Double $$ can be used to escape the $(VAR_NAME) syntax, resulting in a single $ and producing the string literal "$(VAR_NAME)". + Escaped references will not be expanded, regardless of whether the variable exists or not. + type: string + valueFrom: + description: Defines the source for the environment variable's + value. This field is optional and cannot be used if the + 'Value' field is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the FieldPath is + written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the specified + API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the exposed + resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in the pod's namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + username: + description: |- + Defines the user's name for the credential. + The corresponding environment variable will be KB_ITS_USERNAME. + properties: + value: + description: |- + Specifies the value of the environment variable. This field is optional and defaults to an empty string. + The value can include variable references in the format $(VAR_NAME) which will be expanded using previously defined environment variables in the container and any service environment variables. + + + If a variable cannot be resolved, the reference in the input string will remain unchanged. + Double $$ can be used to escape the $(VAR_NAME) syntax, resulting in a single $ and producing the string literal "$(VAR_NAME)". + Escaped references will not be expanded, regardless of whether the variable exists or not. + type: string + valueFrom: + description: Defines the source for the environment variable's + value. This field is optional and cannot be used if the + 'Value' field is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the FieldPath is + written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the specified + API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the exposed + resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in the pod's namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + required: + - password + - username + type: object + defaultTemplateOrdinals: + description: |- + Specifies the desired Ordinals of the default template. + The Ordinals used to specify the ordinal of the instance (pod) names to be generated under the default template. + + + For example, if Ordinals is {ranges: [{start: 0, end: 1}], discrete: [7]}, + then the instance names generated under the default template would be + $(cluster.name)-$(component.name)-0、$(cluster.name)-$(component.name)-1 and $(cluster.name)-$(component.name)-7 + properties: + discrete: + items: + format: int32 + type: integer + type: array + ranges: + items: + description: |- + Range represents a range with a start and an end value. + It is used to define a continuous segment. + properties: + end: + format: int32 + type: integer + start: + format: int32 + type: integer + required: + - end + - start + type: object + type: array + type: object + instances: + description: |- + Overrides values in default Template. + + + Instance is the fundamental unit managed by KubeBlocks. + It represents a Pod with additional objects such as PVCs, Services, ConfigMaps, etc. + An InstanceSet manages instances with a total count of Replicas, + and by default, all these instances are generated from the same template. + The InstanceTemplate provides a way to override values in the default template, + allowing the InstanceSet to manage instances from different templates. + + + The naming convention for instances (pods) based on the InstanceSet Name, InstanceTemplate Name, and ordinal. + The constructed instance name follows the pattern: $(instance_set.name)-$(template.name)-$(ordinal). + By default, the ordinal starts from 0 for each InstanceTemplate. + It is important to ensure that the Name of each InstanceTemplate is unique. + + + The sum of replicas across all InstanceTemplates should not exceed the total number of Replicas specified for the InstanceSet. + Any remaining replicas will be generated using the default template and will follow the default naming rules. + items: + description: |- + InstanceTemplate allows customization of individual replica configurations within a Component, + without altering the base component template defined in ClusterComponentSpec. + It enables the application of distinct settings to specific instances (replicas), + providing flexibility while maintaining a common configuration baseline. + properties: + annotations: + additionalProperties: + type: string + description: |- + Specifies a map of key-value pairs to be merged into the Pod's existing annotations. + Existing keys will have their values overwritten, while new keys will be added to the annotations. + type: object + env: + description: |- + Defines Env to override. + Add new or override existing envs. + items: + description: EnvVar represents an environment variable present + in a Container. + properties: + name: + description: Name of the environment variable. Must be + a C_IDENTIFIER. + type: string + value: + description: |- + Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in the container and + any service environment variables. If a variable cannot be resolved, + the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless of whether the variable + exists or not. + Defaults to "". + type: string + valueFrom: + description: Source for the environment variable's value. + Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap or + its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the + specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the + exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in the pod's + namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its + key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + image: + description: Specifies an override for the first container's + image in the pod. + type: string + labels: + additionalProperties: + type: string + description: |- + Specifies a map of key-value pairs that will be merged into the Pod's existing labels. + Values for existing keys will be overwritten, and new keys will be added. + type: object + name: + description: |- + Name specifies the unique name of the instance Pod created using this InstanceTemplate. + This name is constructed by concatenating the component's name, the template's name, and the instance's ordinal + using the pattern: $(cluster.name)-$(component.name)-$(template.name)-$(ordinal). Ordinals start from 0. + The specified name overrides any default naming conventions or patterns. + maxLength: 54 + pattern: ^[a-z0-9]([a-z0-9\.\-]*[a-z0-9])?$ + type: string + ordinals: + description: |- + Specifies the desired Ordinals of this InstanceTemplate. + The Ordinals used to specify the ordinal of the instance (pod) names to be generated under this InstanceTemplate. + + + For example, if Ordinals is {ranges: [{start: 0, end: 1}], discrete: [7]}, + then the instance names generated under this InstanceTemplate would be + $(cluster.name)-$(component.name)-$(template.name)-0、$(cluster.name)-$(component.name)-$(template.name)-1 and + $(cluster.name)-$(component.name)-$(template.name)-7 + properties: + discrete: + items: + format: int32 + type: integer + type: array + ranges: + items: + description: |- + Range represents a range with a start and an end value. + It is used to define a continuous segment. + properties: + end: + format: int32 + type: integer + start: + format: int32 + type: integer + required: + - end + - start + type: object + type: array + type: object + replicas: + default: 1 + description: |- + Specifies the number of instances (Pods) to create from this InstanceTemplate. + This field allows setting how many replicated instances of the component, + with the specific overrides in the InstanceTemplate, are created. + The default value is 1. A value of 0 disables instance creation. + format: int32 + minimum: 0 + type: integer + resources: + description: |- + Specifies an override for the resource requirements of the first container in the Pod. + This field allows for customizing resource allocation (CPU, memory, etc.) for the container. + properties: + claims: + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + + + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + + + This field is immutable. It can only be set for containers. + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + schedulingPolicy: + description: Specifies the scheduling policy for the Component. + properties: + affinity: + description: Specifies a group of affinity scheduling rules + of the Cluster, including NodeAffinity, PodAffinity, and + PodAntiAffinity. + properties: + nodeAffinity: + description: Describes node affinity scheduling rules + for the pod. + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node matches the corresponding matchExpressions; the + node(s) with the highest sum are the most preferred. + items: + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). + properties: + preference: + description: A node selector term, associated + with the corresponding weight. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that + the selector applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that + the selector applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + weight: + description: Weight associated with matching + the corresponding nodeSelectorTerm, in the + range 1-100. + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. + properties: + nodeSelectorTerms: + description: Required. A list of node selector + terms. The terms are ORed. + items: + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that + the selector applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that + the selector applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + type: array + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + description: Describes pod affinity scheduling rules + (e.g. co-locate this pod in the same node, zone, etc. + as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched + WeightedPodAffinityTerm fields are added per-node + to find the most preferred node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, + associated with the corresponding weight. + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a + list of label selector requirements. + The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. + Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a + list of label selector requirements. + The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: |- + weight associated with matching the corresponding podAffinityTerm, + in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. + items: + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. + Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + description: Describes pod anti-affinity scheduling + rules (e.g. avoid putting this pod in the same node, + zone, etc. as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the anti-affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched + WeightedPodAffinityTerm fields are added per-node + to find the most preferred node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, + associated with the corresponding weight. + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a + list of label selector requirements. + The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. + Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a + list of label selector requirements. + The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: |- + weight associated with matching the corresponding podAffinityTerm, + in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the anti-affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the anti-affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. + items: + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. + Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + nodeName: + description: |- + NodeName is a request to schedule this Pod onto a specific node. If it is non-empty, + the scheduler simply schedules this Pod onto that node, assuming that it fits resource + requirements. + type: string + nodeSelector: + additionalProperties: + type: string + description: |- + NodeSelector is a selector which must be true for the Pod to fit on a node. + Selector which must match a node's labels for the Pod to be scheduled on that node. + More info: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ + type: object + x-kubernetes-map-type: atomic + schedulerName: + description: |- + If specified, the Pod will be dispatched by specified scheduler. + If not specified, the Pod will be dispatched by default scheduler. + type: string + tolerations: + description: |- + Allows Pods to be scheduled onto nodes with matching taints. + Each toleration in the array allows the Pod to tolerate node taints based on + specified `key`, `value`, `effect`, and `operator`. + + + - The `key`, `value`, and `effect` identify the taint that the toleration matches. + - The `operator` determines how the toleration matches the taint. + + + Pods with matching tolerations are allowed to be scheduled on tainted nodes, typically reserved for specific purposes. + items: + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . + properties: + effect: + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. + type: string + operator: + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. + type: string + tolerationSeconds: + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. + format: int64 + type: integer + value: + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. + type: string + type: object + type: array + topologySpreadConstraints: + description: |- + TopologySpreadConstraints describes how a group of Pods ought to spread across topology + domains. Scheduler will schedule Pods in a way which abides by the constraints. + All topologySpreadConstraints are ANDed. + items: + description: TopologySpreadConstraint specifies how to + spread matching pods among the given topology. + properties: + labelSelector: + description: |- + LabelSelector is used to find matching pods. + Pods that match this label selector are counted to determine the number of pods + in their corresponding topology domain. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select the pods over which + spreading will be calculated. The keys are used to lookup values from the + incoming pod labels, those key-value labels are ANDed with labelSelector + to select the group of existing pods over which spreading will be calculated + for the incoming pod. The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + MatchLabelKeys cannot be set when LabelSelector isn't set. + Keys that don't exist in the incoming pod labels will + be ignored. A null or empty list means only match against labelSelector. + + + This is a beta field and requires the MatchLabelKeysInPodTopologySpread feature gate to be enabled (enabled by default). + items: + type: string + type: array + x-kubernetes-list-type: atomic + maxSkew: + description: |- + MaxSkew describes the degree to which pods may be unevenly distributed. + When `whenUnsatisfiable=DoNotSchedule`, it is the maximum permitted difference + between the number of matching pods in the target topology and the global minimum. + The global minimum is the minimum number of matching pods in an eligible domain + or zero if the number of eligible domains is less than MinDomains. + For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same + labelSelector spread as 2/2/1: + In this case, the global minimum is 1. + | zone1 | zone2 | zone3 | + | P P | P P | P | + - if MaxSkew is 1, incoming pod can only be scheduled to zone3 to become 2/2/2; + scheduling it onto zone1(zone2) would make the ActualSkew(3-1) on zone1(zone2) + violate MaxSkew(1). + - if MaxSkew is 2, incoming pod can be scheduled onto any zone. + When `whenUnsatisfiable=ScheduleAnyway`, it is used to give higher precedence + to topologies that satisfy it. + It's a required field. Default value is 1 and 0 is not allowed. + format: int32 + type: integer + minDomains: + description: |- + MinDomains indicates a minimum number of eligible domains. + When the number of eligible domains with matching topology keys is less than minDomains, + Pod Topology Spread treats "global minimum" as 0, and then the calculation of Skew is performed. + And when the number of eligible domains with matching topology keys equals or greater than minDomains, + this value has no effect on scheduling. + As a result, when the number of eligible domains is less than minDomains, + scheduler won't schedule more than maxSkew Pods to those domains. + If value is nil, the constraint behaves as if MinDomains is equal to 1. + Valid values are integers greater than 0. + When value is not nil, WhenUnsatisfiable must be DoNotSchedule. + + + For example, in a 3-zone cluster, MaxSkew is set to 2, MinDomains is set to 5 and pods with the same + labelSelector spread as 2/2/2: + | zone1 | zone2 | zone3 | + | P P | P P | P P | + The number of domains is less than 5(MinDomains), so "global minimum" is treated as 0. + In this situation, new pod with the same labelSelector cannot be scheduled, + because computed skew will be 3(3 - 0) if new Pod is scheduled to any of the three zones, + it will violate MaxSkew. + + + This is a beta field and requires the MinDomainsInPodTopologySpread feature gate to be enabled (enabled by default). + format: int32 + type: integer + nodeAffinityPolicy: + description: |- + NodeAffinityPolicy indicates how we will treat Pod's nodeAffinity/nodeSelector + when calculating pod topology spread skew. Options are: + - Honor: only nodes matching nodeAffinity/nodeSelector are included in the calculations. + - Ignore: nodeAffinity/nodeSelector are ignored. All nodes are included in the calculations. + + + If this value is nil, the behavior is equivalent to the Honor policy. + This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag. + type: string + nodeTaintsPolicy: + description: |- + NodeTaintsPolicy indicates how we will treat node taints when calculating + pod topology spread skew. Options are: + - Honor: nodes without taints, along with tainted nodes for which the incoming pod + has a toleration, are included. + - Ignore: node taints are ignored. All nodes are included. + + + If this value is nil, the behavior is equivalent to the Ignore policy. + This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag. + type: string + topologyKey: + description: |- + TopologyKey is the key of node labels. Nodes that have a label with this key + and identical values are considered to be in the same topology. + We consider each as a "bucket", and try to put balanced number + of pods into each bucket. + We define a domain as a particular instance of a topology. + Also, we define an eligible domain as a domain whose nodes meet the requirements of + nodeAffinityPolicy and nodeTaintsPolicy. + e.g. If TopologyKey is "kubernetes.io/hostname", each Node is a domain of that topology. + And, if TopologyKey is "topology.kubernetes.io/zone", each zone is a domain of that topology. + It's a required field. + type: string + whenUnsatisfiable: + description: |- + WhenUnsatisfiable indicates how to deal with a pod if it doesn't satisfy + the spread constraint. + - DoNotSchedule (default) tells the scheduler not to schedule it. + - ScheduleAnyway tells the scheduler to schedule the pod in any location, + but giving higher precedence to topologies that would help reduce the + skew. + A constraint is considered "Unsatisfiable" for an incoming pod + if and only if every possible node assignment for that pod would violate + "MaxSkew" on some topology. + For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same + labelSelector spread as 3/1/1: + | zone1 | zone2 | zone3 | + | P P P | P | P | + If WhenUnsatisfiable is set to DoNotSchedule, incoming pod can only be scheduled + to zone2(zone3) to become 3/2/1(3/1/2) as ActualSkew(2-1) on zone2(zone3) satisfies + MaxSkew(1). In other words, the cluster can still be imbalanced, but scheduler + won't make it *more* imbalanced. + It's a required field. + type: string + required: + - maxSkew + - topologyKey + - whenUnsatisfiable + type: object + type: array + type: object + volumeClaimTemplates: + description: |- + Defines VolumeClaimTemplates to override. + Add new or override existing volume claim templates. + items: + description: PersistentVolumeClaim is a user's request for + and claim to a persistent volume + 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: + description: |- + Standard object's metadata. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + description: |- + spec defines the desired characteristics of a volume requested by a pod author. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims + properties: + accessModes: + description: |- + accessModes contains the desired access modes the volume should have. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1 + items: + type: string + type: array + dataSource: + description: |- + dataSource field can be used to specify either: + * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) + * An existing PVC (PersistentVolumeClaim) + If the provisioner or an external controller can support the specified data source, + it will create a new volume based on the contents of the specified data source. + When the AnyVolumeDataSource feature gate is enabled, dataSource contents will be copied to dataSourceRef, + and dataSourceRef contents will be copied to dataSource when dataSourceRef.namespace is not specified. + If the namespace is specified, then dataSourceRef will not be copied to dataSource. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being + referenced + type: string + name: + description: Name is the name of resource being + referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + description: |- + dataSourceRef specifies the object from which to populate the volume with data, if a non-empty + volume is desired. This may be any object from a non-empty API group (non + core object) or a PersistentVolumeClaim object. + When this field is specified, volume binding will only succeed if the type of + the specified object matches some installed volume populator or dynamic + provisioner. + This field will replace the functionality of the dataSource field and as such + if both fields are non-empty, they must have the same value. For backwards + compatibility, when namespace isn't specified in dataSourceRef, + both fields (dataSource and dataSourceRef) will be set to the same + value automatically if one of them is empty and the other is non-empty. + When namespace is specified in dataSourceRef, + dataSource isn't set to the same value and must be empty. + There are three important differences between dataSource and dataSourceRef: + * While dataSource only allows two specific types of objects, dataSourceRef + allows any non-core object, as well as PersistentVolumeClaim objects. + * While dataSource ignores disallowed values (dropping them), dataSourceRef + preserves all values, and generates an error if a disallowed value is + specified. + * While dataSource only allows local objects, dataSourceRef allows objects + in any namespaces. + (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled. + (Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being + referenced + type: string + name: + description: Name is the name of resource being + referenced + type: string + namespace: + description: |- + Namespace is the namespace of resource being referenced + Note that when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details. + (Alpha) This field requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + type: string + required: + - kind + - name + type: object + resources: + description: |- + resources represents the minimum resources the volume should have. + If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements + that are lower than previous value but must still be higher than capacity recorded in the + status field of the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + selector: + description: selector is a label query over volumes + to consider for binding. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + description: |- + storageClassName is the name of the StorageClass required by the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1 + type: string + volumeAttributesClassName: + description: |- + volumeAttributesClassName may be used to set the VolumeAttributesClass used by this claim. + If specified, the CSI driver will create or update the volume with the attributes defined + in the corresponding VolumeAttributesClass. This has a different purpose than storageClassName, + it can be changed after the claim is created. An empty string value means that no VolumeAttributesClass + will be applied to the claim but it's not allowed to reset this field to empty string once it is set. + If unspecified and the PersistentVolumeClaim is unbound, the default VolumeAttributesClass + will be set by the persistentvolume controller if it exists. + If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be + set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource + exists. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#volumeattributesclass + (Alpha) Using this field requires the VolumeAttributesClass feature gate to be enabled. + type: string + volumeMode: + description: |- + volumeMode defines what type of volume is required by the claim. + Value of Filesystem is implied when not included in claim spec. + type: string + volumeName: + description: volumeName is the binding reference to + the PersistentVolume backing this claim. + type: string + type: object + status: + description: |- + status represents the current information/status of a persistent volume claim. + Read-only. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims + properties: + accessModes: + description: |- + accessModes contains the actual access modes the volume backing the PVC has. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1 + items: + type: string + type: array + allocatedResourceStatuses: + additionalProperties: + description: |- + When a controller receives persistentvolume claim update with ClaimResourceStatus for a resource + that it does not recognizes, then it should ignore that update and let other controllers + handle it. + type: string + description: "allocatedResourceStatuses stores status + of resource being resized for the given PVC.\nKey + names follow standard Kubernetes label syntax. Valid + values are either:\n\t* Un-prefixed keys:\n\t\t- + storage - the capacity of the volume.\n\t* Custom + resources must use implementation-defined prefixed + names such as \"example.com/my-custom-resource\"\nApart + from above values - keys that are unprefixed or + have kubernetes.io prefix are considered\nreserved + and hence may not be used.\n\n\nClaimResourceStatus + can be in any of following states:\n\t- ControllerResizeInProgress:\n\t\tState + set when resize controller starts resizing the volume + in control-plane.\n\t- ControllerResizeFailed:\n\t\tState + set when resize has failed in resize controller + with a terminal error.\n\t- NodeResizePending:\n\t\tState + set when resize controller has finished resizing + the volume but further resizing of\n\t\tvolume is + needed on the node.\n\t- NodeResizeInProgress:\n\t\tState + set when kubelet starts resizing the volume.\n\t- + NodeResizeFailed:\n\t\tState set when resizing has + failed in kubelet with a terminal error. Transient + errors don't set\n\t\tNodeResizeFailed.\nFor example: + if expanding a PVC for more capacity - this field + can be one of the following states:\n\t- pvc.status.allocatedResourceStatus['storage'] + = \"ControllerResizeInProgress\"\n - pvc.status.allocatedResourceStatus['storage'] + = \"ControllerResizeFailed\"\n - pvc.status.allocatedResourceStatus['storage'] + = \"NodeResizePending\"\n - pvc.status.allocatedResourceStatus['storage'] + = \"NodeResizeInProgress\"\n - pvc.status.allocatedResourceStatus['storage'] + = \"NodeResizeFailed\"\nWhen this field is not set, + it means that no resize operation is in progress + for the given PVC.\n\n\nA controller that receives + PVC update with previously unknown resourceName + or ClaimResourceStatus\nshould ignore the update + for the purpose it was designed. For example - a + controller that\nonly is responsible for resizing + capacity of the volume, should ignore PVC updates + that change other valid\nresources associated with + PVC.\n\n\nThis is an alpha field and requires enabling + RecoverVolumeExpansionFailure feature." + type: object + x-kubernetes-map-type: granular + allocatedResources: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: "allocatedResources tracks the resources + allocated to a PVC including its capacity.\nKey + names follow standard Kubernetes label syntax. Valid + values are either:\n\t* Un-prefixed keys:\n\t\t- + storage - the capacity of the volume.\n\t* Custom + resources must use implementation-defined prefixed + names such as \"example.com/my-custom-resource\"\nApart + from above values - keys that are unprefixed or + have kubernetes.io prefix are considered\nreserved + and hence may not be used.\n\n\nCapacity reported + here may be larger than the actual capacity when + a volume expansion operation\nis requested.\nFor + storage quota, the larger value from allocatedResources + and PVC.spec.resources is used.\nIf allocatedResources + is not set, PVC.spec.resources alone is used for + quota calculation.\nIf a volume expansion capacity + request is lowered, allocatedResources is only\nlowered + if there are no expansion operations in progress + and if the actual volume capacity\nis equal or lower + than the requested capacity.\n\n\nA controller that + receives PVC update with previously unknown resourceName\nshould + ignore the update for the purpose it was designed. + For example - a controller that\nonly is responsible + for resizing capacity of the volume, should ignore + PVC updates that change other valid\nresources associated + with PVC.\n\n\nThis is an alpha field and requires + enabling RecoverVolumeExpansionFailure feature." + type: object + capacity: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: capacity represents the actual resources + of the underlying volume. + type: object + conditions: + description: |- + conditions is the current Condition of persistent volume claim. If underlying persistent volume is being + resized then the Condition will be set to 'ResizeStarted'. + items: + description: PersistentVolumeClaimCondition contains + details about state of pvc + properties: + lastProbeTime: + description: lastProbeTime is the time we probed + the condition. + format: date-time + type: string + lastTransitionTime: + description: lastTransitionTime is the time + the condition transitioned from one status + to another. + format: date-time + type: string + message: + description: message is the human-readable message + indicating details about last transition. + type: string + reason: + description: |- + reason is a unique, this should be a short, machine understandable string that gives the reason + for condition's last transition. If it reports "ResizeStarted" that means the underlying + persistent volume is being resized. + type: string + status: + type: string + type: + description: PersistentVolumeClaimConditionType + is a valid value of PersistentVolumeClaimCondition.Type + type: string + required: + - status + - type + type: object + type: array + currentVolumeAttributesClassName: + description: |- + currentVolumeAttributesClassName is the current name of the VolumeAttributesClass the PVC is using. + When unset, there is no VolumeAttributeClass applied to this PersistentVolumeClaim + This is an alpha field and requires enabling VolumeAttributesClass feature. + type: string + modifyVolumeStatus: + description: |- + ModifyVolumeStatus represents the status object of ControllerModifyVolume operation. + When this is unset, there is no ModifyVolume operation being attempted. + This is an alpha field and requires enabling VolumeAttributesClass feature. + properties: + status: + description: "status is the status of the ControllerModifyVolume + operation. It can be in any of following states:\n + - Pending\n Pending indicates that the PersistentVolumeClaim + cannot be modified due to unmet requirements, + such as\n the specified VolumeAttributesClass + not existing.\n - InProgress\n InProgress + indicates that the volume is being modified.\n + - Infeasible\n Infeasible indicates that the + request has been rejected as invalid by the + CSI driver. To\n\t resolve the error, a valid + VolumeAttributesClass needs to be specified.\nNote: + New statuses can be added in the future. Consumers + should check for unknown statuses and fail appropriately." + type: string + targetVolumeAttributesClassName: + description: targetVolumeAttributesClassName is + the name of the VolumeAttributesClass the PVC + currently being reconciled + type: string + required: + - status + type: object + phase: + description: phase represents the current phase of + PersistentVolumeClaim. + type: string + type: object + type: object + type: array + volumeMounts: + description: |- + Defines VolumeMounts to override. + Add new or override existing volume mounts of the first container in the pod. + items: + description: VolumeMount describes a mounting of a Volume + within a container. + properties: + mountPath: + description: |- + Path within the container at which the volume should be mounted. Must + not contain ':'. + type: string + mountPropagation: + description: |- + mountPropagation determines how mounts are propagated from the host + to container and the other way around. + When not set, MountPropagationNone is used. + This field is beta in 1.10. + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: |- + Mounted read-only if true, read-write otherwise (false or unspecified). + Defaults to false. + type: boolean + subPath: + description: |- + Path within the volume from which the container's volume should be mounted. + Defaults to "" (volume's root). + type: string + subPathExpr: + description: |- + Expanded path within the volume from which the container's volume should be mounted. + Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment. + Defaults to "" (volume's root). + SubPathExpr and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + volumes: + description: |- + Defines Volumes to override. + Add new or override existing volumes. + items: + description: Volume represents a named volume in a pod that + may be accessed by any container in the pod. + properties: + awsElasticBlockStore: + description: |- + awsElasticBlockStore represents an AWS Disk resource that is attached to a + kubelet's host machine and then exposed to the pod. + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + properties: + fsType: + description: |- + fsType is the filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + partition: + description: |- + partition is the partition in the volume that you want to mount. + If omitted, the default is to mount by volume name. + Examples: For volume /dev/sda1, you specify the partition as "1". + Similarly, the volume partition for /dev/sda is "0" (or you can leave the property empty). + format: int32 + type: integer + readOnly: + description: |- + readOnly value true will force the readOnly setting in VolumeMounts. + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + type: boolean + volumeID: + description: |- + volumeID is unique ID of the persistent disk resource in AWS (Amazon EBS volume). + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + type: string + required: + - volumeID + type: object + azureDisk: + description: azureDisk represents an Azure Data Disk mount + on the host and bind mount to the pod. + properties: + cachingMode: + description: 'cachingMode is the Host Caching mode: + None, Read Only, Read Write.' + type: string + diskName: + description: diskName is the Name of the data disk + in the blob storage + type: string + diskURI: + description: diskURI is the URI of data disk in the + blob storage + type: string + fsType: + description: |- + fsType is Filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + kind: + description: 'kind expected values are Shared: multiple + blob disks per storage account Dedicated: single + blob disk per storage account Managed: azure managed + data disk (only in managed availability set). defaults + to shared' + type: string + readOnly: + description: |- + readOnly Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + description: azureFile represents an Azure File Service + mount on the host and bind mount to the pod. + properties: + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretName: + description: secretName is the name of secret that + contains Azure Storage Account Name and Key + type: string + shareName: + description: shareName is the azure share Name + type: string + required: + - secretName + - shareName + type: object + cephfs: + description: cephFS represents a Ceph FS mount on the + host that shares a pod's lifetime + properties: + monitors: + description: |- + monitors is Required: Monitors is a collection of Ceph monitors + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + items: + type: string + type: array + path: + description: 'path is Optional: Used as the mounted + root, rather than the full Ceph tree, default is + /' + type: string + readOnly: + description: |- + readOnly is Optional: Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + type: boolean + secretFile: + description: |- + secretFile is Optional: SecretFile is the path to key ring for User, default is /etc/ceph/user.secret + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + type: string + secretRef: + description: |- + secretRef is Optional: SecretRef is reference to the authentication secret for User, default is empty. + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + 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 + user: + description: |- + user is optional: User is the rados user name, default is admin + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + type: string + required: + - monitors + type: object + cinder: + description: |- + cinder represents a cinder volume attached and mounted on kubelets host machine. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + type: string + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + type: boolean + secretRef: + description: |- + secretRef is optional: points to a secret object containing parameters used to connect + to OpenStack. + 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 + volumeID: + description: |- + volumeID used to identify the volume in cinder. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + type: string + required: + - volumeID + type: object + configMap: + description: configMap represents a configMap that should + populate this volume + properties: + defaultMode: + description: |- + defaultMode is optional: mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + items: + description: |- + items if unspecified, each key-value pair in the Data field of the referenced + ConfigMap will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the ConfigMap, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within + a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + 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 + optional: + description: optional specify whether the ConfigMap + or its keys must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + csi: + description: csi (Container Storage Interface) represents + ephemeral storage that is handled by certain external + CSI drivers (Beta feature). + properties: + driver: + description: |- + driver is the name of the CSI driver that handles this volume. + Consult with your admin for the correct name as registered in the cluster. + type: string + fsType: + description: |- + fsType to mount. Ex. "ext4", "xfs", "ntfs". + If not provided, the empty value is passed to the associated CSI driver + which will determine the default filesystem to apply. + type: string + nodePublishSecretRef: + description: |- + nodePublishSecretRef is a reference to the secret object containing + sensitive information to pass to the CSI driver to complete the CSI + NodePublishVolume and NodeUnpublishVolume calls. + This field is optional, and may be empty if no secret is required. If the + secret object contains more than one secret, all secret references are passed. + 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 + readOnly: + description: |- + readOnly specifies a read-only configuration for the volume. + Defaults to false (read/write). + type: boolean + volumeAttributes: + additionalProperties: + type: string + description: |- + volumeAttributes stores driver-specific properties that are passed to the CSI + driver. Consult your driver's documentation for supported values. + type: object + required: + - driver + type: object + downwardAPI: + description: downwardAPI represents downward API about + the pod that should populate this volume + properties: + defaultMode: + description: |- + Optional: mode bits to use on created files by default. Must be a + Optional: mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + items: + description: Items is a list of downward API volume + file + items: + description: DownwardAPIVolumeFile represents information + to create the file containing the pod field + properties: + fieldRef: + description: 'Required: Selects a field of the + pod: only annotations, labels, name and namespace + are supported.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select + in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + description: |- + Optional: mode bits used to set permissions on this file, must be an octal value + between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: 'Required: Path is the relative + path name of the file to be created. Must + not be absolute or contain the ''..'' path. + Must be utf-8 encoded. The first item of the + relative path must not start with ''..''' + type: string + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported. + properties: + containerName: + description: 'Container name: required for + volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format + of the exposed resources, defaults to + "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + type: object + emptyDir: + description: |- + emptyDir represents a temporary directory that shares a pod's lifetime. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir + properties: + medium: + description: |- + medium represents what type of storage medium should back this directory. + The default is "" which means to use the node's default medium. + Must be an empty string (default) or Memory. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + description: |- + sizeLimit is the total amount of local storage required for this EmptyDir volume. + The size limit is also applicable for memory medium. + The maximum usage on memory medium EmptyDir would be the minimum value between + the SizeLimit specified here and the sum of memory limits of all containers in a pod. + The default is nil which means that the limit is undefined. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + description: |- + ephemeral represents a volume that is handled by a cluster storage driver. + The volume's lifecycle is tied to the pod that defines it - it will be created before the pod starts, + and deleted when the pod is removed. + + + Use this if: + a) the volume is only needed while the pod runs, + b) features of normal volumes like restoring from snapshot or capacity + tracking are needed, + c) the storage driver is specified through a storage class, and + d) the storage driver supports dynamic volume provisioning through + a PersistentVolumeClaim (see EphemeralVolumeSource for more + information on the connection between this volume type + and PersistentVolumeClaim). + + + Use PersistentVolumeClaim or one of the vendor-specific + APIs for volumes that persist for longer than the lifecycle + of an individual pod. + + + Use CSI for light-weight local ephemeral volumes if the CSI driver is meant to + be used that way - see the documentation of the driver for + more information. + + + A pod can use both types of ephemeral volumes and + persistent volumes at the same time. + properties: + volumeClaimTemplate: + description: |- + Will be used to create a stand-alone PVC to provision the volume. + The pod in which this EphemeralVolumeSource is embedded will be the + owner of the PVC, i.e. the PVC will be deleted together with the + pod. The name of the PVC will be `-` where + `` is the name from the `PodSpec.Volumes` array + entry. Pod validation will reject the pod if the concatenated name + is not valid for a PVC (for example, too long). + + + An existing PVC with that name that is not owned by the pod + will *not* be used for the pod to avoid using an unrelated + volume by mistake. Starting the pod is then blocked until + the unrelated PVC is removed. If such a pre-created PVC is + meant to be used by the pod, the PVC has to updated with an + owner reference to the pod once the pod exists. Normally + this should not be necessary, but it may be useful when + manually reconstructing a broken cluster. + + + This field is read-only and no changes will be made by Kubernetes + to the PVC after it has been created. + + + Required, must not be nil. + properties: + metadata: + description: |- + May contain labels and annotations that will be copied into the PVC + when creating it. No other fields are allowed and will be rejected during + validation. + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + description: |- + The specification for the PersistentVolumeClaim. The entire content is + copied unchanged into the PVC that gets created from this + template. The same fields as in a PersistentVolumeClaim + are also valid here. + properties: + accessModes: + description: |- + accessModes contains the desired access modes the volume should have. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1 + items: + type: string + type: array + dataSource: + description: |- + dataSource field can be used to specify either: + * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) + * An existing PVC (PersistentVolumeClaim) + If the provisioner or an external controller can support the specified data source, + it will create a new volume based on the contents of the specified data source. + When the AnyVolumeDataSource feature gate is enabled, dataSource contents will be copied to dataSourceRef, + and dataSourceRef contents will be copied to dataSource when dataSourceRef.namespace is not specified. + If the namespace is specified, then dataSourceRef will not be copied to dataSource. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource + being referenced + type: string + name: + description: Name is the name of resource + being referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + description: |- + dataSourceRef specifies the object from which to populate the volume with data, if a non-empty + volume is desired. This may be any object from a non-empty API group (non + core object) or a PersistentVolumeClaim object. + When this field is specified, volume binding will only succeed if the type of + the specified object matches some installed volume populator or dynamic + provisioner. + This field will replace the functionality of the dataSource field and as such + if both fields are non-empty, they must have the same value. For backwards + compatibility, when namespace isn't specified in dataSourceRef, + both fields (dataSource and dataSourceRef) will be set to the same + value automatically if one of them is empty and the other is non-empty. + When namespace is specified in dataSourceRef, + dataSource isn't set to the same value and must be empty. + There are three important differences between dataSource and dataSourceRef: + * While dataSource only allows two specific types of objects, dataSourceRef + allows any non-core object, as well as PersistentVolumeClaim objects. + * While dataSource ignores disallowed values (dropping them), dataSourceRef + preserves all values, and generates an error if a disallowed value is + specified. + * While dataSource only allows local objects, dataSourceRef allows objects + in any namespaces. + (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled. + (Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource + being referenced + type: string + name: + description: Name is the name of resource + being referenced + type: string + namespace: + description: |- + Namespace is the namespace of resource being referenced + Note that when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details. + (Alpha) This field requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + type: string + required: + - kind + - name + type: object + resources: + description: |- + resources represents the minimum resources the volume should have. + If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements + that are lower than previous value but must still be higher than capacity recorded in the + status field of the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + selector: + description: selector is a label query over + volumes to consider for binding. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + description: |- + storageClassName is the name of the StorageClass required by the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1 + type: string + volumeAttributesClassName: + description: |- + volumeAttributesClassName may be used to set the VolumeAttributesClass used by this claim. + If specified, the CSI driver will create or update the volume with the attributes defined + in the corresponding VolumeAttributesClass. This has a different purpose than storageClassName, + it can be changed after the claim is created. An empty string value means that no VolumeAttributesClass + will be applied to the claim but it's not allowed to reset this field to empty string once it is set. + If unspecified and the PersistentVolumeClaim is unbound, the default VolumeAttributesClass + will be set by the persistentvolume controller if it exists. + If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be + set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource + exists. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#volumeattributesclass + (Alpha) Using this field requires the VolumeAttributesClass feature gate to be enabled. + type: string + volumeMode: + description: |- + volumeMode defines what type of volume is required by the claim. + Value of Filesystem is implied when not included in claim spec. + type: string + volumeName: + description: volumeName is the binding reference + to the PersistentVolume backing this claim. + type: string + type: object + required: + - spec + type: object + type: object + fc: + description: fc represents a Fibre Channel resource that + is attached to a kubelet's host machine and then exposed + to the pod. + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + lun: + description: 'lun is Optional: FC target lun number' + format: int32 + type: integer + readOnly: + description: |- + readOnly is Optional: Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + targetWWNs: + description: 'targetWWNs is Optional: FC target worldwide + names (WWNs)' + items: + type: string + type: array + wwids: + description: |- + wwids Optional: FC volume world wide identifiers (wwids) + Either wwids or combination of targetWWNs and lun must be set, but not both simultaneously. + items: + type: string + type: array + type: object + flexVolume: + description: |- + flexVolume represents a generic volume resource that is + provisioned/attached using an exec based plugin. + properties: + driver: + description: driver is the name of the driver to use + for this volume. + type: string + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". The default filesystem depends on FlexVolume script. + type: string + options: + additionalProperties: + type: string + description: 'options is Optional: this field holds + extra command options if any.' + type: object + readOnly: + description: |- + readOnly is Optional: defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: |- + secretRef is Optional: secretRef is reference to the secret object containing + sensitive information to pass to the plugin scripts. This may be + empty if no secret object is specified. If the secret object + contains more than one secret, all secrets are passed to the plugin + scripts. + 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 + required: + - driver + type: object + flocker: + description: flocker represents a Flocker volume attached + to a kubelet's host machine. This depends on the Flocker + control service being running + properties: + datasetName: + description: |- + datasetName is Name of the dataset stored as metadata -> name on the dataset for Flocker + should be considered as deprecated + type: string + datasetUUID: + description: datasetUUID is the UUID of the dataset. + This is unique identifier of a Flocker dataset + type: string + type: object + gcePersistentDisk: + description: |- + gcePersistentDisk represents a GCE Disk resource that is attached to a + kubelet's host machine and then exposed to the pod. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + properties: + fsType: + description: |- + fsType is filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + partition: + description: |- + partition is the partition in the volume that you want to mount. + If omitted, the default is to mount by volume name. + Examples: For volume /dev/sda1, you specify the partition as "1". + Similarly, the volume partition for /dev/sda is "0" (or you can leave the property empty). + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + format: int32 + type: integer + pdName: + description: |- + pdName is unique name of the PD resource in GCE. Used to identify the disk in GCE. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + type: string + readOnly: + description: |- + readOnly here will force the ReadOnly setting in VolumeMounts. + Defaults to false. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + type: boolean + required: + - pdName + type: object + gitRepo: + description: |- + gitRepo represents a git repository at a particular revision. + DEPRECATED: GitRepo is deprecated. To provision a container with a git repo, mount an + EmptyDir into an InitContainer that clones the repo using git, then mount the EmptyDir + into the Pod's container. + properties: + directory: + description: |- + directory is the target directory name. + Must not contain or start with '..'. If '.' is supplied, the volume directory will be the + git repository. Otherwise, if specified, the volume will contain the git repository in + the subdirectory with the given name. + type: string + repository: + description: repository is the URL + type: string + revision: + description: revision is the commit hash for the specified + revision. + type: string + required: + - repository + type: object + glusterfs: + description: |- + glusterfs represents a Glusterfs mount on the host that shares a pod's lifetime. + More info: https://examples.k8s.io/volumes/glusterfs/README.md + properties: + endpoints: + description: |- + endpoints is the endpoint name that details Glusterfs topology. + More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod + type: string + path: + description: |- + path is the Glusterfs volume path. + More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod + type: string + readOnly: + description: |- + readOnly here will force the Glusterfs volume to be mounted with read-only permissions. + Defaults to false. + More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod + type: boolean + required: + - endpoints + - path + type: object + hostPath: + description: |- + hostPath represents a pre-existing file or directory on the host + machine that is directly exposed to the container. This is generally + used for system agents or other privileged things that are allowed + to see the host machine. Most containers will NOT need this. + More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + --- + TODO(jonesdl) We need to restrict who can use host directory mounts and who can/can not + mount host directories as read/write. + properties: + path: + description: |- + path of the directory on the host. + If the path is a symlink, it will follow the link to the real path. + More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + type: string + type: + description: |- + type for HostPath Volume + Defaults to "" + More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + type: string + required: + - path + type: object + iscsi: + description: |- + iscsi represents an ISCSI Disk resource that is attached to a + kubelet's host machine and then exposed to the pod. + More info: https://examples.k8s.io/volumes/iscsi/README.md + properties: + chapAuthDiscovery: + description: chapAuthDiscovery defines whether support + iSCSI Discovery CHAP authentication + type: boolean + chapAuthSession: + description: chapAuthSession defines whether support + iSCSI Session CHAP authentication + type: boolean + fsType: + description: |- + fsType is the filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#iscsi + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + initiatorName: + description: |- + initiatorName is the custom iSCSI Initiator Name. + If initiatorName is specified with iscsiInterface simultaneously, new iSCSI interface + : will be created for the connection. + type: string + iqn: + description: iqn is the target iSCSI Qualified Name. + type: string + iscsiInterface: + description: |- + iscsiInterface is the interface Name that uses an iSCSI transport. + Defaults to 'default' (tcp). + type: string + lun: + description: lun represents iSCSI Target Lun number. + format: int32 + type: integer + portals: + description: |- + portals is the iSCSI Target Portal List. The portal is either an IP or ip_addr:port if the port + is other than default (typically TCP ports 860 and 3260). + items: + type: string + type: array + readOnly: + description: |- + readOnly here will force the ReadOnly setting in VolumeMounts. + Defaults to false. + type: boolean + secretRef: + description: secretRef is the CHAP Secret for iSCSI + target and initiator authentication + 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 + targetPortal: + description: |- + targetPortal is iSCSI Target Portal. The Portal is either an IP or ip_addr:port if the port + is other than default (typically TCP ports 860 and 3260). + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + description: |- + name of the volume. + Must be a DNS_LABEL and unique within the pod. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + nfs: + description: |- + nfs represents an NFS mount on the host that shares a pod's lifetime + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + properties: + path: + description: |- + path that is exported by the NFS server. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + type: string + readOnly: + description: |- + readOnly here will force the NFS export to be mounted with read-only permissions. + Defaults to false. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + type: boolean + server: + description: |- + server is the hostname or IP address of the NFS server. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + description: |- + persistentVolumeClaimVolumeSource represents a reference to a + PersistentVolumeClaim in the same namespace. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims + properties: + claimName: + description: |- + claimName is the name of a PersistentVolumeClaim in the same namespace as the pod using this volume. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims + type: string + readOnly: + description: |- + readOnly Will force the ReadOnly setting in VolumeMounts. + Default false. + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + description: photonPersistentDisk represents a PhotonController + persistent disk attached and mounted on kubelets host + machine + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + pdID: + description: pdID is the ID that identifies Photon + Controller persistent disk + type: string + required: + - pdID + type: object + portworxVolume: + description: portworxVolume represents a portworx volume + attached and mounted on kubelets host machine + properties: + fsType: + description: |- + fSType represents the filesystem type to mount + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs". Implicitly inferred to be "ext4" if unspecified. + type: string + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + volumeID: + description: volumeID uniquely identifies a Portworx + volume + type: string + required: + - volumeID + type: object + projected: + description: projected items for all in one resources + secrets, configmaps, and downward API + properties: + defaultMode: + description: |- + defaultMode are the mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + sources: + description: sources is the list of volume projections + items: + description: Projection that may be projected along + with other supported volume types + properties: + clusterTrustBundle: + description: |- + ClusterTrustBundle allows a pod to access the `.spec.trustBundle` field + of ClusterTrustBundle objects in an auto-updating file. + + + Alpha, gated by the ClusterTrustBundleProjection feature gate. + + + ClusterTrustBundle objects can either be selected by name, or by the + combination of signer name and a label selector. + + + Kubelet performs aggressive normalization of the PEM contents written + into the pod filesystem. Esoteric PEM features such as inter-block + comments and block headers are stripped. Certificates are deduplicated. + The ordering of certificates within the file is arbitrary, and Kubelet + may change the order over time. + properties: + labelSelector: + description: |- + Select all ClusterTrustBundles that match this label selector. Only has + effect if signerName is set. Mutually-exclusive with name. If unset, + interpreted as "match nothing". If set but empty, interpreted as "match + everything". + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + name: + description: |- + Select a single ClusterTrustBundle by object name. Mutually-exclusive + with signerName and labelSelector. + type: string + optional: + description: |- + If true, don't block pod startup if the referenced ClusterTrustBundle(s) + aren't available. If using name, then the named ClusterTrustBundle is + allowed not to exist. If using signerName, then the combination of + signerName and labelSelector is allowed to match zero + ClusterTrustBundles. + type: boolean + path: + description: Relative path from the volume + root to write the bundle. + type: string + signerName: + description: |- + Select all ClusterTrustBundles that match this signer name. + Mutually-exclusive with name. The contents of all selected + ClusterTrustBundles will be unified and deduplicated. + type: string + required: + - path + type: object + configMap: + description: configMap information about the + configMap data to project + properties: + items: + description: |- + items if unspecified, each key-value pair in the Data field of the referenced + ConfigMap will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the ConfigMap, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path + within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + 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 + optional: + description: optional specify whether the + ConfigMap or its keys must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + downwardAPI: + description: downwardAPI information about the + downwardAPI data to project + properties: + items: + description: Items is a list of DownwardAPIVolume + file + items: + description: DownwardAPIVolumeFile represents + information to create the file containing + the pod field + properties: + fieldRef: + description: 'Required: Selects a + field of the pod: only annotations, + labels, name and namespace are supported.' + properties: + apiVersion: + description: Version of the schema + the FieldPath is written in + terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field + to select in the specified API + version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + description: |- + Optional: mode bits used to set permissions on this file, must be an octal value + between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: 'Required: Path is the + relative path name of the file to + be created. Must not be absolute + or contain the ''..'' path. Must + be utf-8 encoded. The first item + of the relative path must not start + with ''..''' + type: string + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported. + properties: + containerName: + description: 'Container name: + required for volumes, optional + for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output + format of the exposed resources, + defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource + to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + type: object + secret: + description: secret information about the secret + data to project + properties: + items: + description: |- + items if unspecified, each key-value pair in the Data field of the referenced + Secret will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the Secret, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path + within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + 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 + optional: + description: optional field specify whether + the Secret or its key must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + serviceAccountToken: + description: serviceAccountToken is information + about the serviceAccountToken data to project + properties: + audience: + description: |- + audience is the intended audience of the token. A recipient of a token + must identify itself with an identifier specified in the audience of the + token, and otherwise should reject the token. The audience defaults to the + identifier of the apiserver. + type: string + expirationSeconds: + description: |- + expirationSeconds is the requested duration of validity of the service + account token. As the token approaches expiration, the kubelet volume + plugin will proactively rotate the service account token. The kubelet will + start trying to rotate the token if the token is older than 80 percent of + its time to live or if the token is older than 24 hours.Defaults to 1 hour + and must be at least 10 minutes. + format: int64 + type: integer + path: + description: |- + path is the path relative to the mount point of the file to project the + token into. + type: string + required: + - path + type: object + type: object + type: array + type: object + quobyte: + description: quobyte represents a Quobyte mount on the + host that shares a pod's lifetime + properties: + group: + description: |- + group to map volume access to + Default is no group + type: string + readOnly: + description: |- + readOnly here will force the Quobyte volume to be mounted with read-only permissions. + Defaults to false. + type: boolean + registry: + description: |- + registry represents a single or multiple Quobyte Registry services + specified as a string as host:port pair (multiple entries are separated with commas) + which acts as the central registry for volumes + type: string + tenant: + description: |- + tenant owning the given Quobyte volume in the Backend + Used with dynamically provisioned Quobyte volumes, value is set by the plugin + type: string + user: + description: |- + user to map volume access to + Defaults to serivceaccount user + type: string + volume: + description: volume is a string that references an + already created Quobyte volume by name. + type: string + required: + - registry + - volume + type: object + rbd: + description: |- + rbd represents a Rados Block Device mount on the host that shares a pod's lifetime. + More info: https://examples.k8s.io/volumes/rbd/README.md + properties: + fsType: + description: |- + fsType is the filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#rbd + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + image: + description: |- + image is the rados image name. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + keyring: + description: |- + keyring is the path to key ring for RBDUser. + Default is /etc/ceph/keyring. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + monitors: + description: |- + monitors is a collection of Ceph monitors. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + items: + type: string + type: array + pool: + description: |- + pool is the rados pool name. + Default is rbd. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + readOnly: + description: |- + readOnly here will force the ReadOnly setting in VolumeMounts. + Defaults to false. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: boolean + secretRef: + description: |- + secretRef is name of the authentication secret for RBDUser. If provided + overrides keyring. + Default is nil. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + 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 + user: + description: |- + user is the rados user name. + Default is admin. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + required: + - image + - monitors + type: object + scaleIO: + description: scaleIO represents a ScaleIO persistent volume + attached and mounted on Kubernetes nodes. + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". + Default is "xfs". + type: string + gateway: + description: gateway is the host address of the ScaleIO + API Gateway. + type: string + protectionDomain: + description: protectionDomain is the name of the ScaleIO + Protection Domain for the configured storage. + type: string + readOnly: + description: |- + readOnly Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: |- + secretRef references to the secret for ScaleIO user and other + sensitive information. If this is not provided, Login operation will fail. + 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 + sslEnabled: + description: sslEnabled Flag enable/disable SSL communication + with Gateway, default false + type: boolean + storageMode: + description: |- + storageMode indicates whether the storage for a volume should be ThickProvisioned or ThinProvisioned. + Default is ThinProvisioned. + type: string + storagePool: + description: storagePool is the ScaleIO Storage Pool + associated with the protection domain. + type: string + system: + description: system is the name of the storage system + as configured in ScaleIO. + type: string + volumeName: + description: |- + volumeName is the name of a volume already created in the ScaleIO system + that is associated with this volume source. + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + description: |- + secret represents a secret that should populate this volume. + More info: https://kubernetes.io/docs/concepts/storage/volumes#secret + properties: + defaultMode: + description: |- + defaultMode is Optional: mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values + for mode bits. Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + items: + description: |- + items If unspecified, each key-value pair in the Data field of the referenced + Secret will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the Secret, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within + a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + optional: + description: optional field specify whether the Secret + or its keys must be defined + type: boolean + secretName: + description: |- + secretName is the name of the secret in the pod's namespace to use. + More info: https://kubernetes.io/docs/concepts/storage/volumes#secret + type: string + type: object + storageos: + description: storageOS represents a StorageOS volume attached + and mounted on Kubernetes nodes. + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: |- + secretRef specifies the secret to use for obtaining the StorageOS API + credentials. If not specified, default values will be attempted. + 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 + volumeName: + description: |- + volumeName is the human-readable name of the StorageOS volume. Volume + names are only unique within a namespace. + type: string + volumeNamespace: + description: |- + volumeNamespace specifies the scope of the volume within StorageOS. If no + namespace is specified then the Pod's namespace will be used. This allows the + Kubernetes name scoping to be mirrored within StorageOS for tighter integration. + Set VolumeName to any name to override the default behaviour. + Set to "default" if you are not using namespaces within StorageOS. + Namespaces that do not pre-exist within StorageOS will be created. + type: string + type: object + vsphereVolume: + description: vsphereVolume represents a vSphere volume + attached and mounted on kubelets host machine + properties: + fsType: + description: |- + fsType is filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + storagePolicyID: + description: storagePolicyID is the storage Policy + Based Management (SPBM) profile ID associated with + the StoragePolicyName. + type: string + storagePolicyName: + description: storagePolicyName is the storage Policy + Based Management (SPBM) profile name. + type: string + volumePath: + description: volumePath is the path that identifies + vSphere volume vmdk + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + memberUpdateStrategy: + description: |- + Members(Pods) update strategy. + + + - serial: update Members one by one that guarantee minimum component unavailable time. + - bestEffortParallel: update Members in parallel that guarantee minimum component un-writable time. + - parallel: force parallel + enum: + - Serial + - BestEffortParallel + - Parallel + type: string + membershipReconfiguration: + description: Provides actions to do membership dynamic reconfiguration. + properties: + logSyncAction: + description: |- + Defines the action to trigger the new member to start log syncing. + If the Image is not configured, the Image from the previous non-nil action will be used. + properties: + args: + description: Additional parameters used to perform specific + statements. This field is optional. + items: + type: string + type: array + command: + description: A set of instructions that will be executed within + the Container to retrieve or process role information. This + field is required. + items: + type: string + type: array + image: + description: Refers to the utility image that contains the + command which can be utilized to retrieve or process role + information. + type: string + required: + - command + type: object + memberJoinAction: + description: |- + Defines the action to add a member. + If the Image is not configured, the Image from the previous non-nil action will be used. + properties: + args: + description: Additional parameters used to perform specific + statements. This field is optional. + items: + type: string + type: array + command: + description: A set of instructions that will be executed within + the Container to retrieve or process role information. This + field is required. + items: + type: string + type: array + image: + description: Refers to the utility image that contains the + command which can be utilized to retrieve or process role + information. + type: string + required: + - command + type: object + memberLeaveAction: + description: |- + Defines the action to remove a member. + If the Image is not configured, the Image from the previous non-nil action will be used. + properties: + args: + description: Additional parameters used to perform specific + statements. This field is optional. + items: + type: string + type: array + command: + description: A set of instructions that will be executed within + the Container to retrieve or process role information. This + field is required. + items: + type: string + type: array + image: + description: Refers to the utility image that contains the + command which can be utilized to retrieve or process role + information. + type: string + required: + - command + type: object + promoteAction: + description: |- + Defines the action to inform the cluster that the new member can join voting now. + If the Image is not configured, the Image from the previous non-nil action will be used. + properties: + args: + description: Additional parameters used to perform specific + statements. This field is optional. + items: + type: string + type: array + command: + description: A set of instructions that will be executed within + the Container to retrieve or process role information. This + field is required. + items: + type: string + type: array + image: + description: Refers to the utility image that contains the + command which can be utilized to retrieve or process role + information. + type: string + required: + - command + type: object + switchoverAction: + description: |- + Specifies the environment variables that can be used in all following Actions: + - KB_ITS_USERNAME: Represents the username part of the credential + - KB_ITS_PASSWORD: Represents the password part of the credential + - KB_ITS_LEADER_HOST: Represents the leader host + - KB_ITS_TARGET_HOST: Represents the target host + - KB_ITS_SERVICE_PORT: Represents the service port + + + Defines the action to perform a switchover. + If the Image is not configured, the latest [BusyBox](https://busybox.net/) image will be used. + properties: + args: + description: Additional parameters used to perform specific + statements. This field is optional. + items: + type: string + type: array + command: + description: A set of instructions that will be executed within + the Container to retrieve or process role information. This + field is required. + items: + type: string + type: array + image: + description: Refers to the utility image that contains the + command which can be utilized to retrieve or process role + information. + type: string + required: + - command + type: object + type: object + minReadySeconds: + default: 0 + description: |- + Defines the minimum number of seconds a newly created pod should be ready + without any of its container crashing to be considered available. + Defaults to 0, meaning the pod will be considered available as soon as it is ready. + format: int32 + minimum: 0 + type: integer + offlineInstances: + description: |- + Specifies the names of instances to be transitioned to offline status. + + + Marking an instance as offline results in the following: + + + 1. The associated pod is stopped, and its PersistentVolumeClaim (PVC) is retained for potential + future reuse or data recovery, but it is no longer actively used. + 2. The ordinal number assigned to this instance is preserved, ensuring it remains unique + and avoiding conflicts with new instances. + + + Setting instances to offline allows for a controlled scale-in process, preserving their data and maintaining + ordinal consistency within the cluster. + Note that offline instances and their associated resources, such as PVCs, are not automatically deleted. + The cluster administrator must manually manage the cleanup and removal of these resources when they are no longer needed. + items: + type: string + type: array + parallelPodManagementConcurrency: + anyOf: + - type: integer + - type: string + description: |- + Controls the concurrency of pods during initial scale up, when replacing pods on nodes, + or when scaling down. It only used when `PodManagementPolicy` is set to `Parallel`. + The default Concurrency is 100%. + x-kubernetes-int-or-string: true + paused: + description: Indicates that the InstanceSet is paused, meaning the + reconciliation of this InstanceSet object will be paused. + type: boolean + podManagementPolicy: + description: |- + Controls how pods are created during initial scale up, + when replacing pods on nodes, or when scaling down. + + + The default policy is `OrderedReady`, where pods are created in increasing order and the controller waits until each pod is ready before + continuing. When scaling down, the pods are removed in the opposite order. + The alternative policy is `Parallel` which will create pods in parallel + to match the desired scale without waiting, and on scale down will delete + all pods at once. + + + Note: This field will be removed in future version. + type: string + podUpdatePolicy: + description: |- + PodUpdatePolicy indicates how pods should be updated + + + - `StrictInPlace` indicates that only allows in-place upgrades. + Any attempt to modify other fields will be rejected. + - `PreferInPlace` indicates that we will first attempt an in-place upgrade of the Pod. + If that fails, it will fall back to the ReCreate, where pod will be recreated. + Default value is "PreferInPlace" + type: string + replicas: + default: 1 + description: |- + Specifies the desired number of replicas of the given Template. + These replicas are instantiations of the same Template, with each having a consistent identity. + Defaults to 1 if unspecified. + format: int32 + minimum: 0 + type: integer + roleProbe: + description: Provides method to probe role. + properties: + customHandler: + description: |- + Defines a custom method for role probing. + Actions defined here are executed in series. + Upon completion of all actions, the final output should be a single string representing the role name defined in spec.Roles. + The latest [BusyBox](https://busybox.net/) image will be used if Image is not configured. + Environment variables can be used in Command: + - v_KB_ITS_LAST_STDOUT: stdout from the last action, watch for 'v_' prefix + - KB_ITS_USERNAME: username part of the credential + - KB_ITS_PASSWORD: password part of the credential + items: + properties: + args: + description: Additional parameters used to perform specific + statements. This field is optional. + items: + type: string + type: array + command: + description: A set of instructions that will be executed + within the Container to retrieve or process role information. + This field is required. + items: + type: string + type: array + image: + description: Refers to the utility image that contains the + command which can be utilized to retrieve or process role + information. + type: string + required: + - command + type: object + type: array + failureThreshold: + default: 3 + description: Specifies the minimum number of consecutive failures + for the probe to be considered failed after having succeeded. + format: int32 + minimum: 1 + type: integer + initialDelaySeconds: + default: 0 + description: Specifies the number of seconds to wait after the + container has started before initiating role probing. + format: int32 + minimum: 0 + type: integer + periodSeconds: + default: 2 + description: Specifies the frequency (in seconds) of probe execution. + format: int32 + minimum: 1 + type: integer + roleUpdateMechanism: + default: ReadinessProbeEventUpdate + description: Specifies the method for updating the pod role label. + enum: + - ReadinessProbeEventUpdate + - DirectAPIServerEventUpdate + type: string + successThreshold: + default: 1 + description: Specifies the minimum number of consecutive successes + for the probe to be considered successful after having failed. + format: int32 + minimum: 1 + type: integer + timeoutSeconds: + default: 1 + description: Specifies the number of seconds after which the probe + times out. + format: int32 + minimum: 1 + type: integer + type: object + roles: + description: A list of roles defined in the system. + items: + properties: + accessMode: + default: ReadWrite + description: Specifies the service capabilities of this member. + enum: + - None + - Readonly + - ReadWrite + type: string + canVote: + default: true + description: Indicates if this member has voting rights. + type: boolean + isLeader: + default: false + description: Determines if this member is the leader. + type: boolean + name: + default: leader + description: Defines the role name of the replica. + type: string + required: + - accessMode + - name + type: object + type: array + selector: + description: |- + Represents a label query over pods that should match the desired replica count indicated by the `replica` field. + It must match the labels defined in the pod template. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. + The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + service: + description: |- + Defines the behavior of a service spec. + Provides read-write service. + https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status + + + Note: This field will be removed in future version. + 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: + description: |- + Standard object's metadata. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + description: |- + Spec defines the behavior of a service. + https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status + properties: + allocateLoadBalancerNodePorts: + description: |- + allocateLoadBalancerNodePorts defines if NodePorts will be automatically + allocated for services with type LoadBalancer. Default is "true". It + may be set to "false" if the cluster load-balancer does not rely on + NodePorts. If the caller requests specific NodePorts (by specifying a + value), those requests will be respected, regardless of this field. + This field may only be set for services with type LoadBalancer and will + be cleared if the type is changed to any other type. + type: boolean + clusterIP: + description: |- + clusterIP is the IP address of the service and is usually assigned + randomly. If an address is specified manually, is in-range (as per + system configuration), and is not in use, it will be allocated to the + service; otherwise creation of the service will fail. This field may not + be changed through updates unless the type field is also being changed + to ExternalName (which requires this field to be blank) or the type + field is being changed from ExternalName (in which case this field may + optionally be specified, as describe above). Valid values are "None", + empty string (""), or a valid IP address. Setting this to "None" makes a + "headless service" (no virtual IP), which is useful when direct endpoint + connections are preferred and proxying is not required. Only applies to + types ClusterIP, NodePort, and LoadBalancer. If this field is specified + when creating a Service of type ExternalName, creation will fail. This + field will be wiped when updating a Service to type ExternalName. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + type: string + clusterIPs: + description: |- + ClusterIPs is a list of IP addresses assigned to this service, and are + usually assigned randomly. If an address is specified manually, is + in-range (as per system configuration), and is not in use, it will be + allocated to the service; otherwise creation of the service will fail. + This field may not be changed through updates unless the type field is + also being changed to ExternalName (which requires this field to be + empty) or the type field is being changed from ExternalName (in which + case this field may optionally be specified, as describe above). Valid + values are "None", empty string (""), or a valid IP address. Setting + this to "None" makes a "headless service" (no virtual IP), which is + useful when direct endpoint connections are preferred and proxying is + not required. Only applies to types ClusterIP, NodePort, and + LoadBalancer. If this field is specified when creating a Service of type + ExternalName, creation will fail. This field will be wiped when updating + a Service to type ExternalName. If this field is not specified, it will + be initialized from the clusterIP field. If this field is specified, + clients must ensure that clusterIPs[0] and clusterIP have the same + value. + + + This field may hold a maximum of two entries (dual-stack IPs, in either order). + These IPs must correspond to the values of the ipFamilies field. Both + clusterIPs and ipFamilies are governed by the ipFamilyPolicy field. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalIPs: + description: |- + externalIPs is a list of IP addresses for which nodes in the cluster + will also accept traffic for this service. These IPs are not managed by + Kubernetes. The user is responsible for ensuring that traffic arrives + at a node with this IP. A common example is external load-balancers + that are not part of the Kubernetes system. + items: + type: string + type: array + externalName: + description: |- + externalName is the external reference that discovery mechanisms will + return as an alias for this service (e.g. a DNS CNAME record). No + proxying will be involved. Must be a lowercase RFC-1123 hostname + (https://tools.ietf.org/html/rfc1123) and requires `type` to be "ExternalName". + type: string + externalTrafficPolicy: + description: |- + externalTrafficPolicy describes how nodes distribute service traffic they + receive on one of the Service's "externally-facing" addresses (NodePorts, + ExternalIPs, and LoadBalancer IPs). If set to "Local", the proxy will configure + the service in a way that assumes that external load balancers will take care + of balancing the service traffic between nodes, and so each node will deliver + traffic only to the node-local endpoints of the service, without masquerading + the client source IP. (Traffic mistakenly sent to a node with no endpoints will + be dropped.) The default value, "Cluster", uses the standard behavior of + routing to all endpoints evenly (possibly modified by topology and other + features). Note that traffic sent to an External IP or LoadBalancer IP from + within the cluster will always get "Cluster" semantics, but clients sending to + a NodePort from within the cluster may need to take traffic policy into account + when picking a node. + type: string + healthCheckNodePort: + description: |- + healthCheckNodePort specifies the healthcheck nodePort for the service. + This only applies when type is set to LoadBalancer and + externalTrafficPolicy is set to Local. If a value is specified, is + in-range, and is not in use, it will be used. If not specified, a value + will be automatically allocated. External systems (e.g. load-balancers) + can use this port to determine if a given node holds endpoints for this + service or not. If this field is specified when creating a Service + which does not need it, creation will fail. This field will be wiped + when updating a Service to no longer need it (e.g. changing type). + This field cannot be updated once set. + format: int32 + type: integer + internalTrafficPolicy: + description: |- + InternalTrafficPolicy describes how nodes distribute service traffic they + receive on the ClusterIP. If set to "Local", the proxy will assume that pods + only want to talk to endpoints of the service on the same node as the pod, + dropping the traffic if there are no local endpoints. The default value, + "Cluster", uses the standard behavior of routing to all endpoints evenly + (possibly modified by topology and other features). + type: string + ipFamilies: + description: |- + IPFamilies is a list of IP families (e.g. IPv4, IPv6) assigned to this + service. This field is usually assigned automatically based on cluster + configuration and the ipFamilyPolicy field. If this field is specified + manually, the requested family is available in the cluster, + and ipFamilyPolicy allows it, it will be used; otherwise creation of + the service will fail. This field is conditionally mutable: it allows + for adding or removing a secondary IP family, but it does not allow + changing the primary IP family of the Service. Valid values are "IPv4" + and "IPv6". This field only applies to Services of types ClusterIP, + NodePort, and LoadBalancer, and does apply to "headless" services. + This field will be wiped when updating a Service to type ExternalName. + + + This field may hold a maximum of two entries (dual-stack families, in + either order). These families must correspond to the values of the + clusterIPs field, if specified. Both clusterIPs and ipFamilies are + governed by the ipFamilyPolicy field. + items: + description: |- + IPFamily represents the IP Family (IPv4 or IPv6). This type is used + to express the family of an IP expressed by a type (e.g. service.spec.ipFamilies). + type: string + type: array + x-kubernetes-list-type: atomic + ipFamilyPolicy: + description: |- + IPFamilyPolicy represents the dual-stack-ness requested or required by + this Service. If there is no value provided, then this field will be set + to SingleStack. Services can be "SingleStack" (a single IP family), + "PreferDualStack" (two IP families on dual-stack configured clusters or + a single IP family on single-stack clusters), or "RequireDualStack" + (two IP families on dual-stack configured clusters, otherwise fail). The + ipFamilies and clusterIPs fields depend on the value of this field. This + field will be wiped when updating a service to type ExternalName. + type: string + loadBalancerClass: + description: |- + loadBalancerClass is the class of the load balancer implementation this Service belongs to. + If specified, the value of this field must be a label-style identifier, with an optional prefix, + e.g. "internal-vip" or "example.com/internal-vip". Unprefixed names are reserved for end-users. + This field can only be set when the Service type is 'LoadBalancer'. If not set, the default load + balancer implementation is used, today this is typically done through the cloud provider integration, + but should apply for any default implementation. If set, it is assumed that a load balancer + implementation is watching for Services with a matching class. Any default load balancer + implementation (e.g. cloud providers) should ignore Services that set this field. + This field can only be set when creating or updating a Service to type 'LoadBalancer'. + Once set, it can not be changed. This field will be wiped when a service is updated to a non 'LoadBalancer' type. + type: string + loadBalancerIP: + description: |- + Only applies to Service Type: LoadBalancer. + This feature depends on whether the underlying cloud-provider supports specifying + the loadBalancerIP when a load balancer is created. + This field will be ignored if the cloud-provider does not support the feature. + Deprecated: This field was under-specified and its meaning varies across implementations. + Using it is non-portable and it may not support dual-stack. + Users are encouraged to use implementation-specific annotations when available. + type: string + loadBalancerSourceRanges: + description: |- + If specified and supported by the platform, this will restrict traffic through the cloud-provider + load-balancer will be restricted to the specified client IPs. This field will be ignored if the + cloud-provider does not support the feature." + More info: https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/ + items: + type: string + type: array + ports: + description: |- + The list of ports that are exposed by this service. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + items: + description: ServicePort contains information on service's + port. + properties: + appProtocol: + description: |- + The application protocol for this port. + This is used as a hint for implementations to offer richer behavior for protocols that they understand. + This field follows standard Kubernetes label syntax. + Valid values are either: + + + * Un-prefixed protocol names - reserved for IANA standard service names (as per + RFC-6335 and https://www.iana.org/assignments/service-names). + + + * Kubernetes-defined prefixed names: + * 'kubernetes.io/h2c' - HTTP/2 prior knowledge over cleartext as described in https://www.rfc-editor.org/rfc/rfc9113.html#name-starting-http-2-with-prior- + * 'kubernetes.io/ws' - WebSocket over cleartext as described in https://www.rfc-editor.org/rfc/rfc6455 + * 'kubernetes.io/wss' - WebSocket over TLS as described in https://www.rfc-editor.org/rfc/rfc6455 + + + * Other protocols should use implementation-defined prefixed names such as + mycompany.com/my-custom-protocol. + type: string + name: + description: |- + The name of this port within the service. This must be a DNS_LABEL. + All ports within a ServiceSpec must have unique names. When considering + the endpoints for a Service, this must match the 'name' field in the + EndpointPort. + Optional if only one ServicePort is defined on this service. + type: string + nodePort: + description: |- + The port on each node on which this service is exposed when type is + NodePort or LoadBalancer. Usually assigned by the system. If a value is + specified, in-range, and not in use it will be used, otherwise the + operation will fail. If not specified, a port will be allocated if this + Service requires one. If this field is specified when creating a + Service which does not need it, creation will fail. This field will be + wiped when updating a Service to no longer need it (e.g. changing type + from NodePort to ClusterIP). + More info: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport + format: int32 + type: integer + port: + description: The port that will be exposed by this service. + format: int32 + type: integer + protocol: + default: TCP + description: |- + The IP protocol for this port. Supports "TCP", "UDP", and "SCTP". + Default is TCP. + type: string + targetPort: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the pods targeted by the service. + Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + If this is a string, it will be looked up as a named port in the + target Pod's container ports. If this is not specified, the value + of the 'port' field is used (an identity map). + This field is ignored for services with clusterIP=None, and should be + omitted or set equal to the 'port' field. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#defining-a-service + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-map-keys: + - port + - protocol + x-kubernetes-list-type: map + publishNotReadyAddresses: + description: |- + publishNotReadyAddresses indicates that any agent which deals with endpoints for this + Service should disregard any indications of ready/not-ready. + The primary use case for setting this field is for a StatefulSet's Headless Service to + propagate SRV DNS records for its Pods for the purpose of peer discovery. + The Kubernetes controllers that generate Endpoints and EndpointSlice resources for + Services interpret this to mean that all endpoints are considered "ready" even if the + Pods themselves are not. Agents which consume only Kubernetes generated endpoints + through the Endpoints or EndpointSlice resources can safely assume this behavior. + type: boolean + selector: + additionalProperties: + type: string + description: |- + Route service traffic to pods with label keys and values matching this + selector. If empty or not present, the service is assumed to have an + external process managing its endpoints, which Kubernetes will not + modify. Only applies to types ClusterIP, NodePort, and LoadBalancer. + Ignored if type is ExternalName. + More info: https://kubernetes.io/docs/concepts/services-networking/service/ + type: object + x-kubernetes-map-type: atomic + sessionAffinity: + description: |- + Supports "ClientIP" and "None". Used to maintain session affinity. + Enable client IP based session affinity. + Must be ClientIP or None. + Defaults to None. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + type: string + sessionAffinityConfig: + description: sessionAffinityConfig contains the configurations + of session affinity. + properties: + clientIP: + description: clientIP contains the configurations of Client + IP based session affinity. + properties: + timeoutSeconds: + description: |- + timeoutSeconds specifies the seconds of ClientIP type session sticky time. + The value must be >0 && <=86400(for 1 day) if ServiceAffinity == "ClientIP". + Default value is 10800(for 3 hours). + format: int32 + type: integer + type: object + type: object + type: + description: |- + type determines how the Service is exposed. Defaults to ClusterIP. Valid + options are ExternalName, ClusterIP, NodePort, and LoadBalancer. + "ClusterIP" allocates a cluster-internal IP address for load-balancing + to endpoints. Endpoints are determined by the selector or if that is not + specified, by manual construction of an Endpoints object or + EndpointSlice objects. If clusterIP is "None", no virtual IP is + allocated and the endpoints are published as a set of endpoints rather + than a virtual IP. + "NodePort" builds on ClusterIP and allocates a port on every node which + routes to the same endpoints as the clusterIP. + "LoadBalancer" builds on NodePort and creates an external load-balancer + (if supported in the current cloud) which routes to the same endpoints + as the clusterIP. + "ExternalName" aliases this service to the specified externalName. + Several other fields do not apply to ExternalName services. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types + type: string + type: object + status: + description: |- + Most recently observed status of the service. + Populated by the system. + Read-only. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status + properties: + conditions: + description: Current service state + items: + description: "Condition contains details for one aspect + of the current state of this API Resource.\n---\nThis + struct is intended for direct use as an array at the field + path .status.conditions. For example,\n\n\n\ttype FooStatus + struct{\n\t // Represents the observations of a foo's + current state.\n\t // Known .status.conditions.type + are: \"Available\", \"Progressing\", and \"Degraded\"\n\t + \ // +patchMergeKey=type\n\t // +patchStrategy=merge\n\t + \ // +listType=map\n\t // +listMapKey=type\n\t Conditions + []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" + patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t + \ // other fields\n\t}" + 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 + loadBalancer: + description: |- + LoadBalancer contains the current status of the load-balancer, + if one is present. + properties: + ingress: + description: |- + Ingress is a list containing ingress points for the load-balancer. + Traffic intended for the service should be sent to these ingress points. + items: + description: |- + LoadBalancerIngress represents the status of a load-balancer ingress point: + traffic intended for the service should be sent to an ingress point. + properties: + hostname: + description: |- + Hostname is set for load-balancer ingress points that are DNS based + (typically AWS load-balancers) + type: string + ip: + description: |- + IP is set for load-balancer ingress points that are IP based + (typically GCE or OpenStack load-balancers) + type: string + ipMode: + description: |- + IPMode specifies how the load-balancer IP behaves, and may only be specified when the ip field is specified. + Setting this to "VIP" indicates that traffic is delivered to the node with + the destination set to the load-balancer's IP and port. + Setting this to "Proxy" indicates that traffic is delivered to the node or pod with + the destination set to the node's IP and node port or the pod's IP and port. + Service implementations may use this information to adjust traffic routing. + type: string + ports: + description: |- + Ports is a list of records of service ports + If used, every port defined in the service should have an entry in it + items: + properties: + error: + description: |- + Error is to record the problem with the service port + The format of the error shall comply with the following rules: + - built-in error values shall be specified in this file and those shall use + CamelCase names + - cloud provider specific error values must have names that comply with the + format foo.example.com/CamelCase. + --- + 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 + port: + description: Port is the port number of the + service port of which status is recorded + here + format: int32 + type: integer + protocol: + default: TCP + description: |- + Protocol is the protocol of the service port of which status is recorded here + The supported values are: "TCP", "UDP", "SCTP" + type: string + required: + - port + - protocol + type: object + type: array + x-kubernetes-list-type: atomic + type: object + type: array + type: object + type: object + type: object + x-kubernetes-preserve-unknown-fields: true + template: + description: PodTemplateSpec describes the data a pod should have + when created from a template + properties: + metadata: + description: |- + Standard object's metadata. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + description: |- + Specification of the desired behavior of the pod. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status + properties: + activeDeadlineSeconds: + description: |- + Optional duration in seconds the pod may be active on the node relative to + StartTime before the system will actively try to mark it failed and kill associated containers. + Value must be a positive integer. + format: int64 + type: integer + affinity: + description: If specified, the pod's scheduling constraints + properties: + nodeAffinity: + description: Describes node affinity scheduling rules + for the pod. + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node matches the corresponding matchExpressions; the + node(s) with the highest sum are the most preferred. + items: + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). + properties: + preference: + description: A node selector term, associated + with the corresponding weight. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that the + selector applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that the + selector applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + weight: + description: Weight associated with matching + the corresponding nodeSelectorTerm, in the + range 1-100. + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. + properties: + nodeSelectorTerms: + description: Required. A list of node selector + terms. The terms are ORed. + items: + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that the + selector applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that the + selector applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + type: array + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + description: Describes pod affinity scheduling rules (e.g. + co-locate this pod in the same node, zone, etc. as some + other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred + node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, + associated with the corresponding weight. + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. + Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: |- + weight associated with matching the corresponding podAffinityTerm, + in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. + items: + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. + Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + description: Describes pod anti-affinity scheduling rules + (e.g. avoid putting this pod in the same node, zone, + etc. as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the anti-affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred + node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, + associated with the corresponding weight. + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. + Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: |- + weight associated with matching the corresponding podAffinityTerm, + in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the anti-affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the anti-affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. + items: + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. + Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + automountServiceAccountToken: + description: AutomountServiceAccountToken indicates whether + a service account token should be automatically mounted. + type: boolean + containers: + description: |- + List of containers belonging to the pod. + Containers cannot currently be added or removed. + There must be at least one container in a Pod. + Cannot be updated. + items: + description: A single application container that you want + to run within a pod. + properties: + args: + description: |- + Arguments to the entrypoint. + The container image's CMD is used if this is not provided. + Variable references $(VAR_NAME) are expanded using the container's environment. If a variable + cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will + produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless + of whether the variable exists or not. Cannot be updated. + More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell + items: + type: string + type: array + command: + description: |- + Entrypoint array. Not executed within a shell. + The container image's ENTRYPOINT is used if this is not provided. + Variable references $(VAR_NAME) are expanded using the container's environment. If a variable + cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will + produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless + of whether the variable exists or not. Cannot be updated. + More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell + items: + type: string + type: array + env: + description: |- + List of environment variables to set in the container. + Cannot be updated. + items: + description: EnvVar represents an environment variable + present in a Container. + properties: + name: + description: Name of the environment variable. + Must be a C_IDENTIFIER. + type: string + value: + description: |- + Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in the container and + any service environment variables. If a variable cannot be resolved, + the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless of whether the variable + exists or not. + Defaults to "". + type: string + valueFrom: + description: Source for the environment variable's + value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the + FieldPath is written in terms of, defaults + to "v1". + type: string + fieldPath: + description: Path of the field to select + in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required + for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format + of the exposed resources, defaults to + "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in + the pod's namespace + properties: + key: + description: The key of the secret to + select from. Must be a valid secret + key. + type: string + 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 + optional: + description: Specify whether the Secret + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + envFrom: + description: |- + List of sources to populate environment variables in the container. + The keys defined within a source must be a C_IDENTIFIER. All invalid keys + will be reported as an event when the container is starting. When a key exists in multiple + sources, the value associated with the last source will take precedence. + Values defined by an Env with a duplicate key will take precedence. + Cannot be updated. + items: + description: EnvFromSource represents the source of + a set of ConfigMaps + properties: + configMapRef: + description: The ConfigMap to select from + 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 + optional: + description: Specify whether the ConfigMap + must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + description: An optional identifier to prepend + to each key in the ConfigMap. Must be a C_IDENTIFIER. + type: string + secretRef: + description: The Secret to select from + 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 + optional: + description: Specify whether the Secret must + be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + image: + description: |- + Container image name. + More info: https://kubernetes.io/docs/concepts/containers/images + This field is optional to allow higher level config management to default or override + container images in workload controllers like Deployments and StatefulSets. + type: string + imagePullPolicy: + description: |- + Image pull policy. + One of Always, Never, IfNotPresent. + Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/containers/images#updating-images + type: string + lifecycle: + description: |- + Actions that the management system should take in response to container lifecycle events. + Cannot be updated. + properties: + postStart: + description: |- + PostStart is called immediately after a container is created. If the handler fails, + the container is terminated and restarted according to its restart policy. + Other management of the container blocks until the hook completes. + More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the + request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP + server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + sleep: + description: Sleep represents the duration that + the container should sleep before being terminated. + properties: + seconds: + description: Seconds is the number of seconds + to sleep. + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + description: |- + Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept + for the backward compatibility. There are no validation of this field and + lifecycle hooks will fail in runtime when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + description: |- + PreStop is called immediately before a container is terminated due to an + API request or management event such as liveness/startup probe failure, + preemption, resource contention, etc. The handler is not called if the + container crashes or exits. The Pod's termination grace period countdown begins before the + PreStop hook is executed. Regardless of the outcome of the handler, the + container will eventually terminate within the Pod's termination grace + period (unless delayed by finalizers). Other management of the container blocks until the hook completes + or until the termination grace period is reached. + More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the + request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP + server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + sleep: + description: Sleep represents the duration that + the container should sleep before being terminated. + properties: + seconds: + description: Seconds is the number of seconds + to sleep. + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + description: |- + Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept + for the backward compatibility. There are no validation of this field and + lifecycle hooks will fail in runtime when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + description: |- + Periodic probe of container liveness. + Container will be restarted if the probe fails. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving + a GRPC port. + properties: + port: + description: Port number of the gRPC service. + Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + name: + description: |- + Name of the container specified as a DNS_LABEL. + Each container in a pod must have a unique name (DNS_LABEL). + Cannot be updated. + type: string + ports: + description: |- + List of ports to expose from the container. Not specifying a port here + DOES NOT prevent that port from being exposed. Any port which is + listening on the default "0.0.0.0" address inside a container will be + accessible from the network. + Modifying this array with strategic merge patch may corrupt the data. + For more information See https://github.com/kubernetes/kubernetes/issues/108255. + Cannot be updated. + items: + description: ContainerPort represents a network port + in a single container. + properties: + containerPort: + description: |- + Number of port to expose on the pod's IP address. + This must be a valid port number, 0 < x < 65536. + format: int32 + type: integer + hostIP: + description: What host IP to bind the external + port to. + type: string + hostPort: + description: |- + Number of port to expose on the host. + If specified, this must be a valid port number, 0 < x < 65536. + If HostNetwork is specified, this must match ContainerPort. + Most containers do not need this. + format: int32 + type: integer + name: + description: |- + If specified, this must be an IANA_SVC_NAME and unique within the pod. Each + named port in a pod must have a unique name. Name for the port that can be + referred to by services. + type: string + protocol: + default: TCP + description: |- + Protocol for port. Must be UDP, TCP, or SCTP. + Defaults to "TCP". + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + description: |- + Periodic probe of container service readiness. + Container will be removed from service endpoints if the probe fails. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving + a GRPC port. + properties: + port: + description: Port number of the gRPC service. + Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + resizePolicy: + description: Resources resize policy for the container. + items: + description: ContainerResizePolicy represents resource + resize policy for the container. + properties: + resourceName: + description: |- + Name of the resource to which this resource resize policy applies. + Supported values: cpu, memory. + type: string + restartPolicy: + description: |- + Restart policy to apply when specified resource is resized. + If not specified, it defaults to NotRequired. + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + description: |- + Compute Resources required by this container. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + properties: + claims: + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + + + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + + + This field is immutable. It can only be set for containers. + items: + description: ResourceClaim references one entry + in PodSpec.ResourceClaims. + properties: + name: + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + restartPolicy: + description: |- + RestartPolicy defines the restart behavior of individual containers in a pod. + This field may only be set for init containers, and the only allowed value is "Always". + For non-init containers or when this field is not specified, + the restart behavior is defined by the Pod's restart policy and the container type. + Setting the RestartPolicy as "Always" for the init container will have the following effect: + this init container will be continually restarted on + exit until all regular containers have terminated. Once all regular + containers have completed, all init containers with restartPolicy "Always" + will be shut down. This lifecycle differs from normal init containers and + is often referred to as a "sidecar" container. Although this init + container still starts in the init container sequence, it does not wait + for the container to complete before proceeding to the next init + container. Instead, the next init container starts immediately after this + init container is started, or after any startupProbe has successfully + completed. + type: string + securityContext: + description: |- + SecurityContext defines the security options the container should be run with. + If set, the fields of SecurityContext override the equivalent fields of PodSecurityContext. + More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ + properties: + allowPrivilegeEscalation: + description: |- + AllowPrivilegeEscalation controls whether a process can gain more + privileges than its parent process. This bool directly controls if + the no_new_privs flag will be set on the container process. + AllowPrivilegeEscalation is true always when the container is: + 1) run as Privileged + 2) has CAP_SYS_ADMIN + Note that this field cannot be set when spec.os.name is windows. + type: boolean + capabilities: + description: |- + The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the container runtime. + Note that this field cannot be set when spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + type: object + privileged: + description: |- + Run container in privileged mode. + Processes in privileged containers are essentially equivalent to root on the host. + Defaults to false. + Note that this field cannot be set when spec.os.name is windows. + type: boolean + procMount: + description: |- + procMount denotes the type of proc mount to use for the containers. + The default is DefaultProcMount which uses the container runtime defaults for + readonly paths and masked paths. + This requires the ProcMountType feature flag to be enabled. + Note that this field cannot be set when spec.os.name is windows. + type: string + readOnlyRootFilesystem: + description: |- + Whether this container has a read-only root filesystem. + Default is false. + Note that this field cannot be set when spec.os.name is windows. + type: boolean + runAsGroup: + description: |- + The GID to run the entrypoint of the container process. + Uses runtime default if unset. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: |- + Indicates that the container must run as a non-root user. + If true, the Kubelet will validate the image at runtime to ensure that it + does not run as UID 0 (root) and fail to start the container if it does. + If unset or false, no such validation will be performed. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: |- + The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: |- + The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random SELinux context for each + container. May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that + applies to the container. + type: string + role: + description: Role is a SELinux role label that + applies to the container. + type: string + type: + description: Type is a SELinux type label that + applies to the container. + type: string + user: + description: User is a SELinux user label that + applies to the container. + type: string + type: object + seccompProfile: + description: |- + The seccomp options to use by this container. If seccomp options are + provided at both the pod & container level, the container options + override the pod options. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile defined in a file on the node should be used. + The profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be set for any other type. + type: string + type: + description: |- + type indicates which kind of seccomp profile will be applied. + Valid options are: + + + Localhost - a profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile should be used. + Unconfined - no profile should be applied. + type: string + required: + - type + type: object + windowsOptions: + description: |- + The Windows specific settings applied to all containers. + If unspecified, the options from the PodSecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: |- + GMSACredentialSpec is where the GMSA admission webhook + (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the + GMSA credential spec named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name + of the GMSA credential spec to use. + type: string + hostProcess: + description: |- + HostProcess determines if a container should be run as a 'Host Process' container. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: |- + The UserName in Windows to run the entrypoint of the container process. + Defaults to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: string + type: object + type: object + startupProbe: + description: |- + StartupProbe indicates that the Pod has successfully initialized. + If specified, no other probes are executed until this completes successfully. + If this probe fails, the Pod will be restarted, just as if the livenessProbe failed. + This can be used to provide different probe parameters at the beginning of a Pod's lifecycle, + when it might take a long time to load data or warm a cache, than during steady-state operation. + This cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving + a GRPC port. + properties: + port: + description: Port number of the gRPC service. + Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + stdin: + description: |- + Whether this container should allocate a buffer for stdin in the container runtime. If this + is not set, reads from stdin in the container will always result in EOF. + Default is false. + type: boolean + stdinOnce: + description: |- + Whether the container runtime should close the stdin channel after it has been opened by + a single attach. When stdin is true the stdin stream will remain open across multiple attach + sessions. If stdinOnce is set to true, stdin is opened on container start, is empty until the + first client attaches to stdin, and then remains open and accepts data until the client disconnects, + at which time stdin is closed and remains closed until the container is restarted. If this + flag is false, a container processes that reads from stdin will never receive an EOF. + Default is false + type: boolean + terminationMessagePath: + description: |- + Optional: Path at which the file to which the container's termination message + will be written is mounted into the container's filesystem. + Message written is intended to be brief final status, such as an assertion failure message. + Will be truncated by the node if greater than 4096 bytes. The total message length across + all containers will be limited to 12kb. + Defaults to /dev/termination-log. + Cannot be updated. + type: string + terminationMessagePolicy: + description: |- + Indicate how the termination message should be populated. File will use the contents of + terminationMessagePath to populate the container status message on both success and failure. + FallbackToLogsOnError will use the last chunk of container log output if the termination + message file is empty and the container exited with an error. + The log output is limited to 2048 bytes or 80 lines, whichever is smaller. + Defaults to File. + Cannot be updated. + type: string + tty: + description: |- + Whether this container should allocate a TTY for itself, also requires 'stdin' to be true. + Default is false. + type: boolean + volumeDevices: + description: volumeDevices is the list of block devices + to be used by the container. + items: + description: volumeDevice describes a mapping of a + raw block device within a container. + properties: + devicePath: + description: devicePath is the path inside of + the container that the device will be mapped + to. + type: string + name: + description: name must match the name of a persistentVolumeClaim + in the pod + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + description: |- + Pod volumes to mount into the container's filesystem. + Cannot be updated. + items: + description: VolumeMount describes a mounting of a + Volume within a container. + properties: + mountPath: + description: |- + Path within the container at which the volume should be mounted. Must + not contain ':'. + type: string + mountPropagation: + description: |- + mountPropagation determines how mounts are propagated from the host + to container and the other way around. + When not set, MountPropagationNone is used. + This field is beta in 1.10. + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: |- + Mounted read-only if true, read-write otherwise (false or unspecified). + Defaults to false. + type: boolean + subPath: + description: |- + Path within the volume from which the container's volume should be mounted. + Defaults to "" (volume's root). + type: string + subPathExpr: + description: |- + Expanded path within the volume from which the container's volume should be mounted. + Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment. + Defaults to "" (volume's root). + SubPathExpr and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + description: |- + Container's working directory. + If not specified, the container runtime's default will be used, which + might be configured in the container image. + Cannot be updated. + type: string + required: + - name + type: object + type: array + dnsConfig: + description: |- + Specifies the DNS parameters of a pod. + Parameters specified here will be merged to the generated DNS + configuration based on DNSPolicy. + properties: + nameservers: + description: |- + A list of DNS name server IP addresses. + This will be appended to the base nameservers generated from DNSPolicy. + Duplicated nameservers will be removed. + items: + type: string + type: array + options: + description: |- + A list of DNS resolver options. + This will be merged with the base options generated from DNSPolicy. + Duplicated entries will be removed. Resolution options given in Options + will override those that appear in the base DNSPolicy. + items: + description: PodDNSConfigOption defines DNS resolver + options of a pod. + properties: + name: + description: Required. + type: string + value: + type: string + type: object + type: array + searches: + description: |- + A list of DNS search domains for host-name lookup. + This will be appended to the base search paths generated from DNSPolicy. + Duplicated search paths will be removed. + items: + type: string + type: array + type: object + dnsPolicy: + description: |- + Set DNS policy for the pod. + Defaults to "ClusterFirst". + Valid values are 'ClusterFirstWithHostNet', 'ClusterFirst', 'Default' or 'None'. + DNS parameters given in DNSConfig will be merged with the policy selected with DNSPolicy. + To have DNS options set along with hostNetwork, you have to specify DNS policy + explicitly to 'ClusterFirstWithHostNet'. + type: string + enableServiceLinks: + description: |- + EnableServiceLinks indicates whether information about services should be injected into pod's + environment variables, matching the syntax of Docker links. + Optional: Defaults to true. + type: boolean + ephemeralContainers: + description: |- + List of ephemeral containers run in this pod. Ephemeral containers may be run in an existing + pod to perform user-initiated actions such as debugging. This list cannot be specified when + creating a pod, and it cannot be modified by updating the pod spec. In order to add an + ephemeral container to an existing pod, use the pod's ephemeralcontainers subresource. + items: + description: |- + An EphemeralContainer is a temporary container that you may add to an existing Pod for + user-initiated activities such as debugging. Ephemeral containers have no resource or + scheduling guarantees, and they will not be restarted when they exit or when a Pod is + removed or restarted. The kubelet may evict a Pod if an ephemeral container causes the + Pod to exceed its resource allocation. + + + To add an ephemeral container, use the ephemeralcontainers subresource of an existing + Pod. Ephemeral containers may not be removed or restarted. + properties: + args: + description: |- + Arguments to the entrypoint. + The image's CMD is used if this is not provided. + Variable references $(VAR_NAME) are expanded using the container's environment. If a variable + cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will + produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless + of whether the variable exists or not. Cannot be updated. + More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell + items: + type: string + type: array + command: + description: |- + Entrypoint array. Not executed within a shell. + The image's ENTRYPOINT is used if this is not provided. + Variable references $(VAR_NAME) are expanded using the container's environment. If a variable + cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will + produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless + of whether the variable exists or not. Cannot be updated. + More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell + items: + type: string + type: array + env: + description: |- + List of environment variables to set in the container. + Cannot be updated. + items: + description: EnvVar represents an environment variable + present in a Container. + properties: + name: + description: Name of the environment variable. + Must be a C_IDENTIFIER. + type: string + value: + description: |- + Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in the container and + any service environment variables. If a variable cannot be resolved, + the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless of whether the variable + exists or not. + Defaults to "". + type: string + valueFrom: + description: Source for the environment variable's + value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the + FieldPath is written in terms of, defaults + to "v1". + type: string + fieldPath: + description: Path of the field to select + in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required + for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format + of the exposed resources, defaults to + "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in + the pod's namespace + properties: + key: + description: The key of the secret to + select from. Must be a valid secret + key. + type: string + 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 + optional: + description: Specify whether the Secret + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + envFrom: + description: |- + List of sources to populate environment variables in the container. + The keys defined within a source must be a C_IDENTIFIER. All invalid keys + will be reported as an event when the container is starting. When a key exists in multiple + sources, the value associated with the last source will take precedence. + Values defined by an Env with a duplicate key will take precedence. + Cannot be updated. + items: + description: EnvFromSource represents the source of + a set of ConfigMaps + properties: + configMapRef: + description: The ConfigMap to select from + 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 + optional: + description: Specify whether the ConfigMap + must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + description: An optional identifier to prepend + to each key in the ConfigMap. Must be a C_IDENTIFIER. + type: string + secretRef: + description: The Secret to select from + 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 + optional: + description: Specify whether the Secret must + be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + image: + description: |- + Container image name. + More info: https://kubernetes.io/docs/concepts/containers/images + type: string + imagePullPolicy: + description: |- + Image pull policy. + One of Always, Never, IfNotPresent. + Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/containers/images#updating-images + type: string + lifecycle: + description: Lifecycle is not allowed for ephemeral + containers. + properties: + postStart: + description: |- + PostStart is called immediately after a container is created. If the handler fails, + the container is terminated and restarted according to its restart policy. + Other management of the container blocks until the hook completes. + More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the + request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP + server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + sleep: + description: Sleep represents the duration that + the container should sleep before being terminated. + properties: + seconds: + description: Seconds is the number of seconds + to sleep. + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + description: |- + Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept + for the backward compatibility. There are no validation of this field and + lifecycle hooks will fail in runtime when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + description: |- + PreStop is called immediately before a container is terminated due to an + API request or management event such as liveness/startup probe failure, + preemption, resource contention, etc. The handler is not called if the + container crashes or exits. The Pod's termination grace period countdown begins before the + PreStop hook is executed. Regardless of the outcome of the handler, the + container will eventually terminate within the Pod's termination grace + period (unless delayed by finalizers). Other management of the container blocks until the hook completes + or until the termination grace period is reached. + More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the + request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP + server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + sleep: + description: Sleep represents the duration that + the container should sleep before being terminated. + properties: + seconds: + description: Seconds is the number of seconds + to sleep. + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + description: |- + Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept + for the backward compatibility. There are no validation of this field and + lifecycle hooks will fail in runtime when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + description: Probes are not allowed for ephemeral containers. + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving + a GRPC port. + properties: + port: + description: Port number of the gRPC service. + Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + name: + description: |- + Name of the ephemeral container specified as a DNS_LABEL. + This name must be unique among all containers, init containers and ephemeral containers. + type: string + ports: + description: Ports are not allowed for ephemeral containers. + items: + description: ContainerPort represents a network port + in a single container. + properties: + containerPort: + description: |- + Number of port to expose on the pod's IP address. + This must be a valid port number, 0 < x < 65536. + format: int32 + type: integer + hostIP: + description: What host IP to bind the external + port to. + type: string + hostPort: + description: |- + Number of port to expose on the host. + If specified, this must be a valid port number, 0 < x < 65536. + If HostNetwork is specified, this must match ContainerPort. + Most containers do not need this. + format: int32 + type: integer + name: + description: |- + If specified, this must be an IANA_SVC_NAME and unique within the pod. Each + named port in a pod must have a unique name. Name for the port that can be + referred to by services. + type: string + protocol: + default: TCP + description: |- + Protocol for port. Must be UDP, TCP, or SCTP. + Defaults to "TCP". + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + description: Probes are not allowed for ephemeral containers. + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving + a GRPC port. + properties: + port: + description: Port number of the gRPC service. + Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + resizePolicy: + description: Resources resize policy for the container. + items: + description: ContainerResizePolicy represents resource + resize policy for the container. + properties: + resourceName: + description: |- + Name of the resource to which this resource resize policy applies. + Supported values: cpu, memory. + type: string + restartPolicy: + description: |- + Restart policy to apply when specified resource is resized. + If not specified, it defaults to NotRequired. + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + description: |- + Resources are not allowed for ephemeral containers. Ephemeral containers use spare resources + already allocated to the pod. + properties: + claims: + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + + + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + + + This field is immutable. It can only be set for containers. + items: + description: ResourceClaim references one entry + in PodSpec.ResourceClaims. + properties: + name: + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + restartPolicy: + description: |- + Restart policy for the container to manage the restart behavior of each + container within a pod. + This may only be set for init containers. You cannot set this field on + ephemeral containers. + type: string + securityContext: + description: |- + Optional: SecurityContext defines the security options the ephemeral container should be run with. + If set, the fields of SecurityContext override the equivalent fields of PodSecurityContext. + properties: + allowPrivilegeEscalation: + description: |- + AllowPrivilegeEscalation controls whether a process can gain more + privileges than its parent process. This bool directly controls if + the no_new_privs flag will be set on the container process. + AllowPrivilegeEscalation is true always when the container is: + 1) run as Privileged + 2) has CAP_SYS_ADMIN + Note that this field cannot be set when spec.os.name is windows. + type: boolean + capabilities: + description: |- + The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the container runtime. + Note that this field cannot be set when spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + type: object + privileged: + description: |- + Run container in privileged mode. + Processes in privileged containers are essentially equivalent to root on the host. + Defaults to false. + Note that this field cannot be set when spec.os.name is windows. + type: boolean + procMount: + description: |- + procMount denotes the type of proc mount to use for the containers. + The default is DefaultProcMount which uses the container runtime defaults for + readonly paths and masked paths. + This requires the ProcMountType feature flag to be enabled. + Note that this field cannot be set when spec.os.name is windows. + type: string + readOnlyRootFilesystem: + description: |- + Whether this container has a read-only root filesystem. + Default is false. + Note that this field cannot be set when spec.os.name is windows. + type: boolean + runAsGroup: + description: |- + The GID to run the entrypoint of the container process. + Uses runtime default if unset. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: |- + Indicates that the container must run as a non-root user. + If true, the Kubelet will validate the image at runtime to ensure that it + does not run as UID 0 (root) and fail to start the container if it does. + If unset or false, no such validation will be performed. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: |- + The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: |- + The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random SELinux context for each + container. May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that + applies to the container. + type: string + role: + description: Role is a SELinux role label that + applies to the container. + type: string + type: + description: Type is a SELinux type label that + applies to the container. + type: string + user: + description: User is a SELinux user label that + applies to the container. + type: string + type: object + seccompProfile: + description: |- + The seccomp options to use by this container. If seccomp options are + provided at both the pod & container level, the container options + override the pod options. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile defined in a file on the node should be used. + The profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be set for any other type. + type: string + type: + description: |- + type indicates which kind of seccomp profile will be applied. + Valid options are: + + + Localhost - a profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile should be used. + Unconfined - no profile should be applied. + type: string + required: + - type + type: object + windowsOptions: + description: |- + The Windows specific settings applied to all containers. + If unspecified, the options from the PodSecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: |- + GMSACredentialSpec is where the GMSA admission webhook + (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the + GMSA credential spec named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name + of the GMSA credential spec to use. + type: string + hostProcess: + description: |- + HostProcess determines if a container should be run as a 'Host Process' container. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: |- + The UserName in Windows to run the entrypoint of the container process. + Defaults to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: string + type: object + type: object + startupProbe: + description: Probes are not allowed for ephemeral containers. + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving + a GRPC port. + properties: + port: + description: Port number of the gRPC service. + Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + stdin: + description: |- + Whether this container should allocate a buffer for stdin in the container runtime. If this + is not set, reads from stdin in the container will always result in EOF. + Default is false. + type: boolean + stdinOnce: + description: |- + Whether the container runtime should close the stdin channel after it has been opened by + a single attach. When stdin is true the stdin stream will remain open across multiple attach + sessions. If stdinOnce is set to true, stdin is opened on container start, is empty until the + first client attaches to stdin, and then remains open and accepts data until the client disconnects, + at which time stdin is closed and remains closed until the container is restarted. If this + flag is false, a container processes that reads from stdin will never receive an EOF. + Default is false + type: boolean + targetContainerName: + description: |- + If set, the name of the container from PodSpec that this ephemeral container targets. + The ephemeral container will be run in the namespaces (IPC, PID, etc) of this container. + If not set then the ephemeral container uses the namespaces configured in the Pod spec. + + + The container runtime must implement support for this feature. If the runtime does not + support namespace targeting then the result of setting this field is undefined. + type: string + terminationMessagePath: + description: |- + Optional: Path at which the file to which the container's termination message + will be written is mounted into the container's filesystem. + Message written is intended to be brief final status, such as an assertion failure message. + Will be truncated by the node if greater than 4096 bytes. The total message length across + all containers will be limited to 12kb. + Defaults to /dev/termination-log. + Cannot be updated. + type: string + terminationMessagePolicy: + description: |- + Indicate how the termination message should be populated. File will use the contents of + terminationMessagePath to populate the container status message on both success and failure. + FallbackToLogsOnError will use the last chunk of container log output if the termination + message file is empty and the container exited with an error. + The log output is limited to 2048 bytes or 80 lines, whichever is smaller. + Defaults to File. + Cannot be updated. + type: string + tty: + description: |- + Whether this container should allocate a TTY for itself, also requires 'stdin' to be true. + Default is false. + type: boolean + volumeDevices: + description: volumeDevices is the list of block devices + to be used by the container. + items: + description: volumeDevice describes a mapping of a + raw block device within a container. + properties: + devicePath: + description: devicePath is the path inside of + the container that the device will be mapped + to. + type: string + name: + description: name must match the name of a persistentVolumeClaim + in the pod + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + description: |- + Pod volumes to mount into the container's filesystem. Subpath mounts are not allowed for ephemeral containers. + Cannot be updated. + items: + description: VolumeMount describes a mounting of a + Volume within a container. + properties: + mountPath: + description: |- + Path within the container at which the volume should be mounted. Must + not contain ':'. + type: string + mountPropagation: + description: |- + mountPropagation determines how mounts are propagated from the host + to container and the other way around. + When not set, MountPropagationNone is used. + This field is beta in 1.10. + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: |- + Mounted read-only if true, read-write otherwise (false or unspecified). + Defaults to false. + type: boolean + subPath: + description: |- + Path within the volume from which the container's volume should be mounted. + Defaults to "" (volume's root). + type: string + subPathExpr: + description: |- + Expanded path within the volume from which the container's volume should be mounted. + Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment. + Defaults to "" (volume's root). + SubPathExpr and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + description: |- + Container's working directory. + If not specified, the container runtime's default will be used, which + might be configured in the container image. + Cannot be updated. + type: string + required: + - name + type: object + type: array + hostAliases: + description: |- + HostAliases is an optional list of hosts and IPs that will be injected into the pod's hosts + file if specified. This is only valid for non-hostNetwork pods. + items: + description: |- + HostAlias holds the mapping between IP and hostnames that will be injected as an entry in the + pod's hosts file. + properties: + hostnames: + description: Hostnames for the above IP address. + items: + type: string + type: array + ip: + description: IP address of the host file entry. + type: string + type: object + type: array + hostIPC: + description: |- + Use the host's ipc namespace. + Optional: Default to false. + type: boolean + hostNetwork: + description: |- + Host networking requested for this pod. Use the host's network namespace. + If this option is set, the ports that will be used must be specified. + Default to false. + type: boolean + hostPID: + description: |- + Use the host's pid namespace. + Optional: Default to false. + type: boolean + hostUsers: + description: |- + Use the host's user namespace. + Optional: Default to true. + If set to true or not present, the pod will be run in the host user namespace, useful + for when the pod needs a feature only available to the host user namespace, such as + loading a kernel module with CAP_SYS_MODULE. + When set to false, a new userns is created for the pod. Setting false is useful for + mitigating container breakout vulnerabilities even allowing users to run their + containers as root without actually having root privileges on the host. + This field is alpha-level and is only honored by servers that enable the UserNamespacesSupport feature. + type: boolean + hostname: + description: |- + Specifies the hostname of the Pod + If not specified, the pod's hostname will be set to a system-defined value. + type: string + imagePullSecrets: + description: |- + ImagePullSecrets is an optional list of references to secrets in the same namespace to use for pulling any of the images used by this PodSpec. + If specified, these secrets will be passed to individual puller implementations for them to use. + More info: https://kubernetes.io/docs/concepts/containers/images#specifying-imagepullsecrets-on-a-pod + items: + 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? + type: string + type: object + x-kubernetes-map-type: atomic + type: array + initContainers: + description: |- + List of initialization containers belonging to the pod. + Init containers are executed in order prior to containers being started. If any + init container fails, the pod is considered to have failed and is handled according + to its restartPolicy. The name for an init container or normal container must be + unique among all containers. + Init containers may not have Lifecycle actions, Readiness probes, Liveness probes, or Startup probes. + The resourceRequirements of an init container are taken into account during scheduling + by finding the highest request/limit for each resource type, and then using the max of + of that value or the sum of the normal containers. Limits are applied to init containers + in a similar fashion. + Init containers cannot currently be added or removed. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/init-containers/ + items: + description: A single application container that you want + to run within a pod. + properties: + args: + description: |- + Arguments to the entrypoint. + The container image's CMD is used if this is not provided. + Variable references $(VAR_NAME) are expanded using the container's environment. If a variable + cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will + produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless + of whether the variable exists or not. Cannot be updated. + More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell + items: + type: string + type: array + command: + description: |- + Entrypoint array. Not executed within a shell. + The container image's ENTRYPOINT is used if this is not provided. + Variable references $(VAR_NAME) are expanded using the container's environment. If a variable + cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will + produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless + of whether the variable exists or not. Cannot be updated. + More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell + items: + type: string + type: array + env: + description: |- + List of environment variables to set in the container. + Cannot be updated. + items: + description: EnvVar represents an environment variable + present in a Container. + properties: + name: + description: Name of the environment variable. + Must be a C_IDENTIFIER. + type: string + value: + description: |- + Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in the container and + any service environment variables. If a variable cannot be resolved, + the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless of whether the variable + exists or not. + Defaults to "". + type: string + valueFrom: + description: Source for the environment variable's + value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the + FieldPath is written in terms of, defaults + to "v1". + type: string + fieldPath: + description: Path of the field to select + in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required + for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format + of the exposed resources, defaults to + "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in + the pod's namespace + properties: + key: + description: The key of the secret to + select from. Must be a valid secret + key. + type: string + 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 + optional: + description: Specify whether the Secret + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + envFrom: + description: |- + List of sources to populate environment variables in the container. + The keys defined within a source must be a C_IDENTIFIER. All invalid keys + will be reported as an event when the container is starting. When a key exists in multiple + sources, the value associated with the last source will take precedence. + Values defined by an Env with a duplicate key will take precedence. + Cannot be updated. + items: + description: EnvFromSource represents the source of + a set of ConfigMaps + properties: + configMapRef: + description: The ConfigMap to select from + 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 + optional: + description: Specify whether the ConfigMap + must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + description: An optional identifier to prepend + to each key in the ConfigMap. Must be a C_IDENTIFIER. + type: string + secretRef: + description: The Secret to select from + 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 + optional: + description: Specify whether the Secret must + be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + image: + description: |- + Container image name. + More info: https://kubernetes.io/docs/concepts/containers/images + This field is optional to allow higher level config management to default or override + container images in workload controllers like Deployments and StatefulSets. + type: string + imagePullPolicy: + description: |- + Image pull policy. + One of Always, Never, IfNotPresent. + Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/containers/images#updating-images + type: string + lifecycle: + description: |- + Actions that the management system should take in response to container lifecycle events. + Cannot be updated. + properties: + postStart: + description: |- + PostStart is called immediately after a container is created. If the handler fails, + the container is terminated and restarted according to its restart policy. + Other management of the container blocks until the hook completes. + More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the + request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP + server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + sleep: + description: Sleep represents the duration that + the container should sleep before being terminated. + properties: + seconds: + description: Seconds is the number of seconds + to sleep. + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + description: |- + Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept + for the backward compatibility. There are no validation of this field and + lifecycle hooks will fail in runtime when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + description: |- + PreStop is called immediately before a container is terminated due to an + API request or management event such as liveness/startup probe failure, + preemption, resource contention, etc. The handler is not called if the + container crashes or exits. The Pod's termination grace period countdown begins before the + PreStop hook is executed. Regardless of the outcome of the handler, the + container will eventually terminate within the Pod's termination grace + period (unless delayed by finalizers). Other management of the container blocks until the hook completes + or until the termination grace period is reached. + More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the + request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP + server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + sleep: + description: Sleep represents the duration that + the container should sleep before being terminated. + properties: + seconds: + description: Seconds is the number of seconds + to sleep. + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + description: |- + Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept + for the backward compatibility. There are no validation of this field and + lifecycle hooks will fail in runtime when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + description: |- + Periodic probe of container liveness. + Container will be restarted if the probe fails. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving + a GRPC port. + properties: + port: + description: Port number of the gRPC service. + Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + name: + description: |- + Name of the container specified as a DNS_LABEL. + Each container in a pod must have a unique name (DNS_LABEL). + Cannot be updated. + type: string + ports: + description: |- + List of ports to expose from the container. Not specifying a port here + DOES NOT prevent that port from being exposed. Any port which is + listening on the default "0.0.0.0" address inside a container will be + accessible from the network. + Modifying this array with strategic merge patch may corrupt the data. + For more information See https://github.com/kubernetes/kubernetes/issues/108255. + Cannot be updated. + items: + description: ContainerPort represents a network port + in a single container. + properties: + containerPort: + description: |- + Number of port to expose on the pod's IP address. + This must be a valid port number, 0 < x < 65536. + format: int32 + type: integer + hostIP: + description: What host IP to bind the external + port to. + type: string + hostPort: + description: |- + Number of port to expose on the host. + If specified, this must be a valid port number, 0 < x < 65536. + If HostNetwork is specified, this must match ContainerPort. + Most containers do not need this. + format: int32 + type: integer + name: + description: |- + If specified, this must be an IANA_SVC_NAME and unique within the pod. Each + named port in a pod must have a unique name. Name for the port that can be + referred to by services. + type: string + protocol: + default: TCP + description: |- + Protocol for port. Must be UDP, TCP, or SCTP. + Defaults to "TCP". + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + description: |- + Periodic probe of container service readiness. + Container will be removed from service endpoints if the probe fails. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving + a GRPC port. + properties: + port: + description: Port number of the gRPC service. + Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + resizePolicy: + description: Resources resize policy for the container. + items: + description: ContainerResizePolicy represents resource + resize policy for the container. + properties: + resourceName: + description: |- + Name of the resource to which this resource resize policy applies. + Supported values: cpu, memory. + type: string + restartPolicy: + description: |- + Restart policy to apply when specified resource is resized. + If not specified, it defaults to NotRequired. + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + description: |- + Compute Resources required by this container. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + properties: + claims: + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + + + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + + + This field is immutable. It can only be set for containers. + items: + description: ResourceClaim references one entry + in PodSpec.ResourceClaims. + properties: + name: + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + restartPolicy: + description: |- + RestartPolicy defines the restart behavior of individual containers in a pod. + This field may only be set for init containers, and the only allowed value is "Always". + For non-init containers or when this field is not specified, + the restart behavior is defined by the Pod's restart policy and the container type. + Setting the RestartPolicy as "Always" for the init container will have the following effect: + this init container will be continually restarted on + exit until all regular containers have terminated. Once all regular + containers have completed, all init containers with restartPolicy "Always" + will be shut down. This lifecycle differs from normal init containers and + is often referred to as a "sidecar" container. Although this init + container still starts in the init container sequence, it does not wait + for the container to complete before proceeding to the next init + container. Instead, the next init container starts immediately after this + init container is started, or after any startupProbe has successfully + completed. + type: string + securityContext: + description: |- + SecurityContext defines the security options the container should be run with. + If set, the fields of SecurityContext override the equivalent fields of PodSecurityContext. + More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ + properties: + allowPrivilegeEscalation: + description: |- + AllowPrivilegeEscalation controls whether a process can gain more + privileges than its parent process. This bool directly controls if + the no_new_privs flag will be set on the container process. + AllowPrivilegeEscalation is true always when the container is: + 1) run as Privileged + 2) has CAP_SYS_ADMIN + Note that this field cannot be set when spec.os.name is windows. + type: boolean + capabilities: + description: |- + The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the container runtime. + Note that this field cannot be set when spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + type: object + privileged: + description: |- + Run container in privileged mode. + Processes in privileged containers are essentially equivalent to root on the host. + Defaults to false. + Note that this field cannot be set when spec.os.name is windows. + type: boolean + procMount: + description: |- + procMount denotes the type of proc mount to use for the containers. + The default is DefaultProcMount which uses the container runtime defaults for + readonly paths and masked paths. + This requires the ProcMountType feature flag to be enabled. + Note that this field cannot be set when spec.os.name is windows. + type: string + readOnlyRootFilesystem: + description: |- + Whether this container has a read-only root filesystem. + Default is false. + Note that this field cannot be set when spec.os.name is windows. + type: boolean + runAsGroup: + description: |- + The GID to run the entrypoint of the container process. + Uses runtime default if unset. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: |- + Indicates that the container must run as a non-root user. + If true, the Kubelet will validate the image at runtime to ensure that it + does not run as UID 0 (root) and fail to start the container if it does. + If unset or false, no such validation will be performed. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: |- + The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: |- + The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random SELinux context for each + container. May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that + applies to the container. + type: string + role: + description: Role is a SELinux role label that + applies to the container. + type: string + type: + description: Type is a SELinux type label that + applies to the container. + type: string + user: + description: User is a SELinux user label that + applies to the container. + type: string + type: object + seccompProfile: + description: |- + The seccomp options to use by this container. If seccomp options are + provided at both the pod & container level, the container options + override the pod options. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile defined in a file on the node should be used. + The profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be set for any other type. + type: string + type: + description: |- + type indicates which kind of seccomp profile will be applied. + Valid options are: + + + Localhost - a profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile should be used. + Unconfined - no profile should be applied. + type: string + required: + - type + type: object + windowsOptions: + description: |- + The Windows specific settings applied to all containers. + If unspecified, the options from the PodSecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: |- + GMSACredentialSpec is where the GMSA admission webhook + (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the + GMSA credential spec named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name + of the GMSA credential spec to use. + type: string + hostProcess: + description: |- + HostProcess determines if a container should be run as a 'Host Process' container. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: |- + The UserName in Windows to run the entrypoint of the container process. + Defaults to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: string + type: object + type: object + startupProbe: + description: |- + StartupProbe indicates that the Pod has successfully initialized. + If specified, no other probes are executed until this completes successfully. + If this probe fails, the Pod will be restarted, just as if the livenessProbe failed. + This can be used to provide different probe parameters at the beginning of a Pod's lifecycle, + when it might take a long time to load data or warm a cache, than during steady-state operation. + This cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving + a GRPC port. + properties: + port: + description: Port number of the gRPC service. + Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + stdin: + description: |- + Whether this container should allocate a buffer for stdin in the container runtime. If this + is not set, reads from stdin in the container will always result in EOF. + Default is false. + type: boolean + stdinOnce: + description: |- + Whether the container runtime should close the stdin channel after it has been opened by + a single attach. When stdin is true the stdin stream will remain open across multiple attach + sessions. If stdinOnce is set to true, stdin is opened on container start, is empty until the + first client attaches to stdin, and then remains open and accepts data until the client disconnects, + at which time stdin is closed and remains closed until the container is restarted. If this + flag is false, a container processes that reads from stdin will never receive an EOF. + Default is false + type: boolean + terminationMessagePath: + description: |- + Optional: Path at which the file to which the container's termination message + will be written is mounted into the container's filesystem. + Message written is intended to be brief final status, such as an assertion failure message. + Will be truncated by the node if greater than 4096 bytes. The total message length across + all containers will be limited to 12kb. + Defaults to /dev/termination-log. + Cannot be updated. + type: string + terminationMessagePolicy: + description: |- + Indicate how the termination message should be populated. File will use the contents of + terminationMessagePath to populate the container status message on both success and failure. + FallbackToLogsOnError will use the last chunk of container log output if the termination + message file is empty and the container exited with an error. + The log output is limited to 2048 bytes or 80 lines, whichever is smaller. + Defaults to File. + Cannot be updated. + type: string + tty: + description: |- + Whether this container should allocate a TTY for itself, also requires 'stdin' to be true. + Default is false. + type: boolean + volumeDevices: + description: volumeDevices is the list of block devices + to be used by the container. + items: + description: volumeDevice describes a mapping of a + raw block device within a container. + properties: + devicePath: + description: devicePath is the path inside of + the container that the device will be mapped + to. + type: string + name: + description: name must match the name of a persistentVolumeClaim + in the pod + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + description: |- + Pod volumes to mount into the container's filesystem. + Cannot be updated. + items: + description: VolumeMount describes a mounting of a + Volume within a container. + properties: + mountPath: + description: |- + Path within the container at which the volume should be mounted. Must + not contain ':'. + type: string + mountPropagation: + description: |- + mountPropagation determines how mounts are propagated from the host + to container and the other way around. + When not set, MountPropagationNone is used. + This field is beta in 1.10. + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: |- + Mounted read-only if true, read-write otherwise (false or unspecified). + Defaults to false. + type: boolean + subPath: + description: |- + Path within the volume from which the container's volume should be mounted. + Defaults to "" (volume's root). + type: string + subPathExpr: + description: |- + Expanded path within the volume from which the container's volume should be mounted. + Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment. + Defaults to "" (volume's root). + SubPathExpr and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + description: |- + Container's working directory. + If not specified, the container runtime's default will be used, which + might be configured in the container image. + Cannot be updated. + type: string + required: + - name + type: object + type: array + nodeName: + description: |- + NodeName is a request to schedule this pod onto a specific node. If it is non-empty, + the scheduler simply schedules this pod onto that node, assuming that it fits resource + requirements. + type: string + nodeSelector: + additionalProperties: + type: string + description: |- + NodeSelector is a selector which must be true for the pod to fit on a node. + Selector which must match a node's labels for the pod to be scheduled on that node. + More info: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ + type: object + x-kubernetes-map-type: atomic + os: + description: |- + Specifies the OS of the containers in the pod. + Some pod and container fields are restricted if this is set. + + + If the OS field is set to linux, the following fields must be unset: + -securityContext.windowsOptions + + + If the OS field is set to windows, following fields must be unset: + - spec.hostPID + - spec.hostIPC + - spec.hostUsers + - spec.securityContext.seLinuxOptions + - spec.securityContext.seccompProfile + - spec.securityContext.fsGroup + - spec.securityContext.fsGroupChangePolicy + - spec.securityContext.sysctls + - spec.shareProcessNamespace + - spec.securityContext.runAsUser + - spec.securityContext.runAsGroup + - spec.securityContext.supplementalGroups + - spec.containers[*].securityContext.seLinuxOptions + - spec.containers[*].securityContext.seccompProfile + - spec.containers[*].securityContext.capabilities + - spec.containers[*].securityContext.readOnlyRootFilesystem + - spec.containers[*].securityContext.privileged + - spec.containers[*].securityContext.allowPrivilegeEscalation + - spec.containers[*].securityContext.procMount + - spec.containers[*].securityContext.runAsUser + - spec.containers[*].securityContext.runAsGroup + properties: + name: + description: |- + Name is the name of the operating system. The currently supported values are linux and windows. + Additional value may be defined in future and can be one of: + https://github.com/opencontainers/runtime-spec/blob/master/config.md#platform-specific-configuration + Clients should expect to handle additional values and treat unrecognized values in this field as os: null + type: string + required: + - name + type: object + overhead: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Overhead represents the resource overhead associated with running a pod for a given RuntimeClass. + This field will be autopopulated at admission time by the RuntimeClass admission controller. If + the RuntimeClass admission controller is enabled, overhead must not be set in Pod create requests. + The RuntimeClass admission controller will reject Pod create requests which have the overhead already + set. If RuntimeClass is configured and selected in the PodSpec, Overhead will be set to the value + defined in the corresponding RuntimeClass, otherwise it will remain unset and treated as zero. + More info: https://git.k8s.io/enhancements/keps/sig-node/688-pod-overhead/README.md + type: object + preemptionPolicy: + description: |- + PreemptionPolicy is the Policy for preempting pods with lower priority. + One of Never, PreemptLowerPriority. + Defaults to PreemptLowerPriority if unset. + type: string + priority: + description: |- + The priority value. Various system components use this field to find the + priority of the pod. When Priority Admission Controller is enabled, it + prevents users from setting this field. The admission controller populates + this field from PriorityClassName. + The higher the value, the higher the priority. + format: int32 + type: integer + priorityClassName: + description: |- + If specified, indicates the pod's priority. "system-node-critical" and + "system-cluster-critical" are two special keywords which indicate the + highest priorities with the former being the highest priority. Any other + name must be defined by creating a PriorityClass object with that name. + If not specified, the pod priority will be default or zero if there is no + default. + type: string + readinessGates: + description: |- + If specified, all readiness gates will be evaluated for pod readiness. + A pod is ready when all its containers are ready AND + all conditions specified in the readiness gates have status equal to "True" + More info: https://git.k8s.io/enhancements/keps/sig-network/580-pod-readiness-gates + items: + description: PodReadinessGate contains the reference to + a pod condition + properties: + conditionType: + description: ConditionType refers to a condition in + the pod's condition list with matching type. + type: string + required: + - conditionType + type: object + type: array + resourceClaims: + description: |- + ResourceClaims defines which ResourceClaims must be allocated + and reserved before the Pod is allowed to start. The resources + will be made available to those containers which consume them + by name. + + + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + + + This field is immutable. + items: + description: |- + PodResourceClaim references exactly one ResourceClaim through a ClaimSource. + It adds a name to it that uniquely identifies the ResourceClaim inside the Pod. + Containers that need access to the ResourceClaim reference it with this name. + properties: + name: + description: |- + Name uniquely identifies this resource claim inside the pod. + This must be a DNS_LABEL. + type: string + source: + description: Source describes where to find the ResourceClaim. + properties: + resourceClaimName: + description: |- + ResourceClaimName is the name of a ResourceClaim object in the same + namespace as this pod. + type: string + resourceClaimTemplateName: + description: |- + ResourceClaimTemplateName is the name of a ResourceClaimTemplate + object in the same namespace as this pod. + + + The template will be used to create a new ResourceClaim, which will + be bound to this pod. When this pod is deleted, the ResourceClaim + will also be deleted. The pod name and resource name, along with a + generated component, will be used to form a unique name for the + ResourceClaim, which will be recorded in pod.status.resourceClaimStatuses. + + + This field is immutable and no changes will be made to the + corresponding ResourceClaim by the control plane after creating the + ResourceClaim. + type: string + type: object + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + restartPolicy: + description: |- + Restart policy for all containers within the pod. + One of Always, OnFailure, Never. In some contexts, only a subset of those values may be permitted. + Default to Always. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#restart-policy + type: string + runtimeClassName: + description: |- + RuntimeClassName refers to a RuntimeClass object in the node.k8s.io group, which should be used + to run this pod. If no RuntimeClass resource matches the named class, the pod will not be run. + If unset or empty, the "legacy" RuntimeClass will be used, which is an implicit class with an + empty definition that uses the default runtime handler. + More info: https://git.k8s.io/enhancements/keps/sig-node/585-runtime-class + type: string + schedulerName: + description: |- + If specified, the pod will be dispatched by specified scheduler. + If not specified, the pod will be dispatched by default scheduler. + type: string + schedulingGates: + description: |- + SchedulingGates is an opaque list of values that if specified will block scheduling the pod. + If schedulingGates is not empty, the pod will stay in the SchedulingGated state and the + scheduler will not attempt to schedule the pod. + + + SchedulingGates can only be set at pod creation time, and be removed only afterwards. + + + This is a beta feature enabled by the PodSchedulingReadiness feature gate. + items: + description: PodSchedulingGate is associated to a Pod to + guard its scheduling. + properties: + name: + description: |- + Name of the scheduling gate. + Each scheduling gate must have a unique name field. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + securityContext: + description: |- + SecurityContext holds pod-level security attributes and common container settings. + Optional: Defaults to empty. See type description for default values of each field. + properties: + fsGroup: + description: |- + A special supplemental group that applies to all containers in a pod. + Some volume types allow the Kubelet to change the ownership of that volume + to be owned by the pod: + + + 1. The owning GID will be the FSGroup + 2. The setgid bit is set (new files created in the volume will be owned by FSGroup) + 3. The permission bits are OR'd with rw-rw---- + + + If unset, the Kubelet will not modify the ownership and permissions of any volume. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + fsGroupChangePolicy: + description: |- + fsGroupChangePolicy defines behavior of changing ownership and permission of the volume + before being exposed inside Pod. This field will only apply to + volume types which support fsGroup based ownership(and permissions). + It will have no effect on ephemeral volume types such as: secret, configmaps + and emptydir. + Valid values are "OnRootMismatch" and "Always". If not specified, "Always" is used. + Note that this field cannot be set when spec.os.name is windows. + type: string + runAsGroup: + description: |- + The GID to run the entrypoint of the container process. + Uses runtime default if unset. + May also be set in SecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence + for that container. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: |- + Indicates that the container must run as a non-root user. + If true, the Kubelet will validate the image at runtime to ensure that it + does not run as UID 0 (root) and fail to start the container if it does. + If unset or false, no such validation will be performed. + May also be set in SecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: |- + The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in SecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence + for that container. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: |- + The SELinux context to be applied to all containers. + If unspecified, the container runtime will allocate a random SELinux context for each + container. May also be set in SecurityContext. If set in + both SecurityContext and PodSecurityContext, the value specified in SecurityContext + takes precedence for that container. + Note that this field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies + to the container. + type: string + role: + description: Role is a SELinux role label that applies + to the container. + type: string + type: + description: Type is a SELinux type label that applies + to the container. + type: string + user: + description: User is a SELinux user label that applies + to the container. + type: string + type: object + seccompProfile: + description: |- + The seccomp options to use by the containers in this pod. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile defined in a file on the node should be used. + The profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be set for any other type. + type: string + type: + description: |- + type indicates which kind of seccomp profile will be applied. + Valid options are: + + + Localhost - a profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile should be used. + Unconfined - no profile should be applied. + type: string + required: + - type + type: object + supplementalGroups: + description: |- + A list of groups applied to the first process run in each container, in addition + to the container's primary GID, the fsGroup (if specified), and group memberships + defined in the container image for the uid of the container process. If unspecified, + no additional groups are added to any container. Note that group memberships + defined in the container image for the uid of the container process are still effective, + even if they are not included in this list. + Note that this field cannot be set when spec.os.name is windows. + items: + format: int64 + type: integer + type: array + sysctls: + description: |- + Sysctls hold a list of namespaced sysctls used for the pod. Pods with unsupported + sysctls (by the container runtime) might fail to launch. + Note that this field cannot be set when spec.os.name is windows. + items: + description: Sysctl defines a kernel parameter to be + set + properties: + name: + description: Name of a property to set + type: string + value: + description: Value of a property to set + type: string + required: + - name + - value + type: object + type: array + windowsOptions: + description: |- + The Windows specific settings applied to all containers. + If unspecified, the options within a container's SecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: |- + GMSACredentialSpec is where the GMSA admission webhook + (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the + GMSA credential spec named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of + the GMSA credential spec to use. + type: string + hostProcess: + description: |- + HostProcess determines if a container should be run as a 'Host Process' container. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: |- + The UserName in Windows to run the entrypoint of the container process. + Defaults to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: string + type: object + type: object + serviceAccount: + description: |- + DeprecatedServiceAccount is a depreciated alias for ServiceAccountName. + Deprecated: Use serviceAccountName instead. + type: string + serviceAccountName: + description: |- + ServiceAccountName is the name of the ServiceAccount to use to run this pod. + More info: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/ + type: string + setHostnameAsFQDN: + description: |- + If true the pod's hostname will be configured as the pod's FQDN, rather than the leaf name (the default). + In Linux containers, this means setting the FQDN in the hostname field of the kernel (the nodename field of struct utsname). + In Windows containers, this means setting the registry value of hostname for the registry key HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters to FQDN. + If a pod does not have FQDN, this has no effect. + Default to false. + type: boolean + shareProcessNamespace: + description: |- + Share a single process namespace between all of the containers in a pod. + When this is set containers will be able to view and signal processes from other containers + in the same pod, and the first process in each container will not be assigned PID 1. + HostPID and ShareProcessNamespace cannot both be set. + Optional: Default to false. + type: boolean + subdomain: + description: |- + If specified, the fully qualified Pod hostname will be "...svc.". + If not specified, the pod will not have a domainname at all. + type: string + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully. May be decreased in delete request. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + If this value is nil, the default grace period will be used instead. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + Defaults to 30 seconds. + format: int64 + type: integer + tolerations: + description: If specified, the pod's tolerations. + items: + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . + properties: + effect: + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. + type: string + operator: + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. + type: string + tolerationSeconds: + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. + format: int64 + type: integer + value: + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. + type: string + type: object + type: array + topologySpreadConstraints: + description: |- + TopologySpreadConstraints describes how a group of pods ought to spread across topology + domains. Scheduler will schedule pods in a way which abides by the constraints. + All topologySpreadConstraints are ANDed. + items: + description: TopologySpreadConstraint specifies how to spread + matching pods among the given topology. + properties: + labelSelector: + description: |- + LabelSelector is used to find matching pods. + Pods that match this label selector are counted to determine the number of pods + in their corresponding topology domain. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select the pods over which + spreading will be calculated. The keys are used to lookup values from the + incoming pod labels, those key-value labels are ANDed with labelSelector + to select the group of existing pods over which spreading will be calculated + for the incoming pod. The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + MatchLabelKeys cannot be set when LabelSelector isn't set. + Keys that don't exist in the incoming pod labels will + be ignored. A null or empty list means only match against labelSelector. + + + This is a beta field and requires the MatchLabelKeysInPodTopologySpread feature gate to be enabled (enabled by default). + items: + type: string + type: array + x-kubernetes-list-type: atomic + maxSkew: + description: |- + MaxSkew describes the degree to which pods may be unevenly distributed. + When `whenUnsatisfiable=DoNotSchedule`, it is the maximum permitted difference + between the number of matching pods in the target topology and the global minimum. + The global minimum is the minimum number of matching pods in an eligible domain + or zero if the number of eligible domains is less than MinDomains. + For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same + labelSelector spread as 2/2/1: + In this case, the global minimum is 1. + | zone1 | zone2 | zone3 | + | P P | P P | P | + - if MaxSkew is 1, incoming pod can only be scheduled to zone3 to become 2/2/2; + scheduling it onto zone1(zone2) would make the ActualSkew(3-1) on zone1(zone2) + violate MaxSkew(1). + - if MaxSkew is 2, incoming pod can be scheduled onto any zone. + When `whenUnsatisfiable=ScheduleAnyway`, it is used to give higher precedence + to topologies that satisfy it. + It's a required field. Default value is 1 and 0 is not allowed. + format: int32 + type: integer + minDomains: + description: |- + MinDomains indicates a minimum number of eligible domains. + When the number of eligible domains with matching topology keys is less than minDomains, + Pod Topology Spread treats "global minimum" as 0, and then the calculation of Skew is performed. + And when the number of eligible domains with matching topology keys equals or greater than minDomains, + this value has no effect on scheduling. + As a result, when the number of eligible domains is less than minDomains, + scheduler won't schedule more than maxSkew Pods to those domains. + If value is nil, the constraint behaves as if MinDomains is equal to 1. + Valid values are integers greater than 0. + When value is not nil, WhenUnsatisfiable must be DoNotSchedule. + + + For example, in a 3-zone cluster, MaxSkew is set to 2, MinDomains is set to 5 and pods with the same + labelSelector spread as 2/2/2: + | zone1 | zone2 | zone3 | + | P P | P P | P P | + The number of domains is less than 5(MinDomains), so "global minimum" is treated as 0. + In this situation, new pod with the same labelSelector cannot be scheduled, + because computed skew will be 3(3 - 0) if new Pod is scheduled to any of the three zones, + it will violate MaxSkew. + + + This is a beta field and requires the MinDomainsInPodTopologySpread feature gate to be enabled (enabled by default). + format: int32 + type: integer + nodeAffinityPolicy: + description: |- + NodeAffinityPolicy indicates how we will treat Pod's nodeAffinity/nodeSelector + when calculating pod topology spread skew. Options are: + - Honor: only nodes matching nodeAffinity/nodeSelector are included in the calculations. + - Ignore: nodeAffinity/nodeSelector are ignored. All nodes are included in the calculations. + + + If this value is nil, the behavior is equivalent to the Honor policy. + This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag. + type: string + nodeTaintsPolicy: + description: |- + NodeTaintsPolicy indicates how we will treat node taints when calculating + pod topology spread skew. Options are: + - Honor: nodes without taints, along with tainted nodes for which the incoming pod + has a toleration, are included. + - Ignore: node taints are ignored. All nodes are included. + + + If this value is nil, the behavior is equivalent to the Ignore policy. + This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag. + type: string + topologyKey: + description: |- + TopologyKey is the key of node labels. Nodes that have a label with this key + and identical values are considered to be in the same topology. + We consider each as a "bucket", and try to put balanced number + of pods into each bucket. + We define a domain as a particular instance of a topology. + Also, we define an eligible domain as a domain whose nodes meet the requirements of + nodeAffinityPolicy and nodeTaintsPolicy. + e.g. If TopologyKey is "kubernetes.io/hostname", each Node is a domain of that topology. + And, if TopologyKey is "topology.kubernetes.io/zone", each zone is a domain of that topology. + It's a required field. + type: string + whenUnsatisfiable: + description: |- + WhenUnsatisfiable indicates how to deal with a pod if it doesn't satisfy + the spread constraint. + - DoNotSchedule (default) tells the scheduler not to schedule it. + - ScheduleAnyway tells the scheduler to schedule the pod in any location, + but giving higher precedence to topologies that would help reduce the + skew. + A constraint is considered "Unsatisfiable" for an incoming pod + if and only if every possible node assignment for that pod would violate + "MaxSkew" on some topology. + For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same + labelSelector spread as 3/1/1: + | zone1 | zone2 | zone3 | + | P P P | P | P | + If WhenUnsatisfiable is set to DoNotSchedule, incoming pod can only be scheduled + to zone2(zone3) to become 3/2/1(3/1/2) as ActualSkew(2-1) on zone2(zone3) satisfies + MaxSkew(1). In other words, the cluster can still be imbalanced, but scheduler + won't make it *more* imbalanced. + It's a required field. + type: string + required: + - maxSkew + - topologyKey + - whenUnsatisfiable + type: object + type: array + x-kubernetes-list-map-keys: + - topologyKey + - whenUnsatisfiable + x-kubernetes-list-type: map + volumes: + description: |- + List of volumes that can be mounted by containers belonging to the pod. + More info: https://kubernetes.io/docs/concepts/storage/volumes + items: + description: Volume represents a named volume in a pod that + may be accessed by any container in the pod. + properties: + awsElasticBlockStore: + description: |- + awsElasticBlockStore represents an AWS Disk resource that is attached to a + kubelet's host machine and then exposed to the pod. + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + properties: + fsType: + description: |- + fsType is the filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + partition: + description: |- + partition is the partition in the volume that you want to mount. + If omitted, the default is to mount by volume name. + Examples: For volume /dev/sda1, you specify the partition as "1". + Similarly, the volume partition for /dev/sda is "0" (or you can leave the property empty). + format: int32 + type: integer + readOnly: + description: |- + readOnly value true will force the readOnly setting in VolumeMounts. + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + type: boolean + volumeID: + description: |- + volumeID is unique ID of the persistent disk resource in AWS (Amazon EBS volume). + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + type: string + required: + - volumeID + type: object + azureDisk: + description: azureDisk represents an Azure Data Disk + mount on the host and bind mount to the pod. + properties: + cachingMode: + description: 'cachingMode is the Host Caching mode: + None, Read Only, Read Write.' + type: string + diskName: + description: diskName is the Name of the data disk + in the blob storage + type: string + diskURI: + description: diskURI is the URI of data disk in + the blob storage + type: string + fsType: + description: |- + fsType is Filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + kind: + description: 'kind expected values are Shared: multiple + blob disks per storage account Dedicated: single + blob disk per storage account Managed: azure + managed data disk (only in managed availability + set). defaults to shared' + type: string + readOnly: + description: |- + readOnly Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + description: azureFile represents an Azure File Service + mount on the host and bind mount to the pod. + properties: + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretName: + description: secretName is the name of secret that + contains Azure Storage Account Name and Key + type: string + shareName: + description: shareName is the azure share Name + type: string + required: + - secretName + - shareName + type: object + cephfs: + description: cephFS represents a Ceph FS mount on the + host that shares a pod's lifetime + properties: + monitors: + description: |- + monitors is Required: Monitors is a collection of Ceph monitors + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + items: + type: string + type: array + path: + description: 'path is Optional: Used as the mounted + root, rather than the full Ceph tree, default + is /' + type: string + readOnly: + description: |- + readOnly is Optional: Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + type: boolean + secretFile: + description: |- + secretFile is Optional: SecretFile is the path to key ring for User, default is /etc/ceph/user.secret + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + type: string + secretRef: + description: |- + secretRef is Optional: SecretRef is reference to the authentication secret for User, default is empty. + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + 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 + user: + description: |- + user is optional: User is the rados user name, default is admin + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + type: string + required: + - monitors + type: object + cinder: + description: |- + cinder represents a cinder volume attached and mounted on kubelets host machine. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + type: string + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + type: boolean + secretRef: + description: |- + secretRef is optional: points to a secret object containing parameters used to connect + to OpenStack. + 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 + volumeID: + description: |- + volumeID used to identify the volume in cinder. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + type: string + required: + - volumeID + type: object + configMap: + description: configMap represents a configMap that should + populate this volume + properties: + defaultMode: + description: |- + defaultMode is optional: mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + items: + description: |- + items if unspecified, each key-value pair in the Data field of the referenced + ConfigMap will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the ConfigMap, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within + a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + 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 + optional: + description: optional specify whether the ConfigMap + or its keys must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + csi: + description: csi (Container Storage Interface) represents + ephemeral storage that is handled by certain external + CSI drivers (Beta feature). + properties: + driver: + description: |- + driver is the name of the CSI driver that handles this volume. + Consult with your admin for the correct name as registered in the cluster. + type: string + fsType: + description: |- + fsType to mount. Ex. "ext4", "xfs", "ntfs". + If not provided, the empty value is passed to the associated CSI driver + which will determine the default filesystem to apply. + type: string + nodePublishSecretRef: + description: |- + nodePublishSecretRef is a reference to the secret object containing + sensitive information to pass to the CSI driver to complete the CSI + NodePublishVolume and NodeUnpublishVolume calls. + This field is optional, and may be empty if no secret is required. If the + secret object contains more than one secret, all secret references are passed. + 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 + readOnly: + description: |- + readOnly specifies a read-only configuration for the volume. + Defaults to false (read/write). + type: boolean + volumeAttributes: + additionalProperties: + type: string + description: |- + volumeAttributes stores driver-specific properties that are passed to the CSI + driver. Consult your driver's documentation for supported values. + type: object + required: + - driver + type: object + downwardAPI: + description: downwardAPI represents downward API about + the pod that should populate this volume + properties: + defaultMode: + description: |- + Optional: mode bits to use on created files by default. Must be a + Optional: mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + items: + description: Items is a list of downward API volume + file + items: + description: DownwardAPIVolumeFile represents + information to create the file containing the + pod field + properties: + fieldRef: + description: 'Required: Selects a field of + the pod: only annotations, labels, name + and namespace are supported.' + properties: + apiVersion: + description: Version of the schema the + FieldPath is written in terms of, defaults + to "v1". + type: string + fieldPath: + description: Path of the field to select + in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + description: |- + Optional: mode bits used to set permissions on this file, must be an octal value + between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: 'Required: Path is the relative + path name of the file to be created. Must + not be absolute or contain the ''..'' path. + Must be utf-8 encoded. The first item of + the relative path must not start with ''..''' + type: string + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported. + properties: + containerName: + description: 'Container name: required + for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format + of the exposed resources, defaults to + "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + type: object + emptyDir: + description: |- + emptyDir represents a temporary directory that shares a pod's lifetime. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir + properties: + medium: + description: |- + medium represents what type of storage medium should back this directory. + The default is "" which means to use the node's default medium. + Must be an empty string (default) or Memory. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + description: |- + sizeLimit is the total amount of local storage required for this EmptyDir volume. + The size limit is also applicable for memory medium. + The maximum usage on memory medium EmptyDir would be the minimum value between + the SizeLimit specified here and the sum of memory limits of all containers in a pod. + The default is nil which means that the limit is undefined. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + description: |- + ephemeral represents a volume that is handled by a cluster storage driver. + The volume's lifecycle is tied to the pod that defines it - it will be created before the pod starts, + and deleted when the pod is removed. + + + Use this if: + a) the volume is only needed while the pod runs, + b) features of normal volumes like restoring from snapshot or capacity + tracking are needed, + c) the storage driver is specified through a storage class, and + d) the storage driver supports dynamic volume provisioning through + a PersistentVolumeClaim (see EphemeralVolumeSource for more + information on the connection between this volume type + and PersistentVolumeClaim). + + + Use PersistentVolumeClaim or one of the vendor-specific + APIs for volumes that persist for longer than the lifecycle + of an individual pod. + + + Use CSI for light-weight local ephemeral volumes if the CSI driver is meant to + be used that way - see the documentation of the driver for + more information. + + + A pod can use both types of ephemeral volumes and + persistent volumes at the same time. + properties: + volumeClaimTemplate: + description: |- + Will be used to create a stand-alone PVC to provision the volume. + The pod in which this EphemeralVolumeSource is embedded will be the + owner of the PVC, i.e. the PVC will be deleted together with the + pod. The name of the PVC will be `-` where + `` is the name from the `PodSpec.Volumes` array + entry. Pod validation will reject the pod if the concatenated name + is not valid for a PVC (for example, too long). + + + An existing PVC with that name that is not owned by the pod + will *not* be used for the pod to avoid using an unrelated + volume by mistake. Starting the pod is then blocked until + the unrelated PVC is removed. If such a pre-created PVC is + meant to be used by the pod, the PVC has to updated with an + owner reference to the pod once the pod exists. Normally + this should not be necessary, but it may be useful when + manually reconstructing a broken cluster. + + + This field is read-only and no changes will be made by Kubernetes + to the PVC after it has been created. + + + Required, must not be nil. + properties: + metadata: + description: |- + May contain labels and annotations that will be copied into the PVC + when creating it. No other fields are allowed and will be rejected during + validation. + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + description: |- + The specification for the PersistentVolumeClaim. The entire content is + copied unchanged into the PVC that gets created from this + template. The same fields as in a PersistentVolumeClaim + are also valid here. + properties: + accessModes: + description: |- + accessModes contains the desired access modes the volume should have. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1 + items: + type: string + type: array + dataSource: + description: |- + dataSource field can be used to specify either: + * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) + * An existing PVC (PersistentVolumeClaim) + If the provisioner or an external controller can support the specified data source, + it will create a new volume based on the contents of the specified data source. + When the AnyVolumeDataSource feature gate is enabled, dataSource contents will be copied to dataSourceRef, + and dataSourceRef contents will be copied to dataSource when dataSourceRef.namespace is not specified. + If the namespace is specified, then dataSourceRef will not be copied to dataSource. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource + being referenced + type: string + name: + description: Name is the name of resource + being referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + description: |- + dataSourceRef specifies the object from which to populate the volume with data, if a non-empty + volume is desired. This may be any object from a non-empty API group (non + core object) or a PersistentVolumeClaim object. + When this field is specified, volume binding will only succeed if the type of + the specified object matches some installed volume populator or dynamic + provisioner. + This field will replace the functionality of the dataSource field and as such + if both fields are non-empty, they must have the same value. For backwards + compatibility, when namespace isn't specified in dataSourceRef, + both fields (dataSource and dataSourceRef) will be set to the same + value automatically if one of them is empty and the other is non-empty. + When namespace is specified in dataSourceRef, + dataSource isn't set to the same value and must be empty. + There are three important differences between dataSource and dataSourceRef: + * While dataSource only allows two specific types of objects, dataSourceRef + allows any non-core object, as well as PersistentVolumeClaim objects. + * While dataSource ignores disallowed values (dropping them), dataSourceRef + preserves all values, and generates an error if a disallowed value is + specified. + * While dataSource only allows local objects, dataSourceRef allows objects + in any namespaces. + (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled. + (Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource + being referenced + type: string + name: + description: Name is the name of resource + being referenced + type: string + namespace: + description: |- + Namespace is the namespace of resource being referenced + Note that when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details. + (Alpha) This field requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + type: string + required: + - kind + - name + type: object + resources: + description: |- + resources represents the minimum resources the volume should have. + If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements + that are lower than previous value but must still be higher than capacity recorded in the + status field of the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + selector: + description: selector is a label query over + volumes to consider for binding. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + description: |- + storageClassName is the name of the StorageClass required by the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1 + type: string + volumeAttributesClassName: + description: |- + volumeAttributesClassName may be used to set the VolumeAttributesClass used by this claim. + If specified, the CSI driver will create or update the volume with the attributes defined + in the corresponding VolumeAttributesClass. This has a different purpose than storageClassName, + it can be changed after the claim is created. An empty string value means that no VolumeAttributesClass + will be applied to the claim but it's not allowed to reset this field to empty string once it is set. + If unspecified and the PersistentVolumeClaim is unbound, the default VolumeAttributesClass + will be set by the persistentvolume controller if it exists. + If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be + set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource + exists. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#volumeattributesclass + (Alpha) Using this field requires the VolumeAttributesClass feature gate to be enabled. + type: string + volumeMode: + description: |- + volumeMode defines what type of volume is required by the claim. + Value of Filesystem is implied when not included in claim spec. + type: string + volumeName: + description: volumeName is the binding reference + to the PersistentVolume backing this claim. + type: string + type: object + required: + - spec + type: object + type: object + fc: + description: fc represents a Fibre Channel resource + that is attached to a kubelet's host machine and then + exposed to the pod. + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + lun: + description: 'lun is Optional: FC target lun number' + format: int32 + type: integer + readOnly: + description: |- + readOnly is Optional: Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + targetWWNs: + description: 'targetWWNs is Optional: FC target + worldwide names (WWNs)' + items: + type: string + type: array + wwids: + description: |- + wwids Optional: FC volume world wide identifiers (wwids) + Either wwids or combination of targetWWNs and lun must be set, but not both simultaneously. + items: + type: string + type: array + type: object + flexVolume: + description: |- + flexVolume represents a generic volume resource that is + provisioned/attached using an exec based plugin. + properties: + driver: + description: driver is the name of the driver to + use for this volume. + type: string + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". The default filesystem depends on FlexVolume script. + type: string + options: + additionalProperties: + type: string + description: 'options is Optional: this field holds + extra command options if any.' + type: object + readOnly: + description: |- + readOnly is Optional: defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: |- + secretRef is Optional: secretRef is reference to the secret object containing + sensitive information to pass to the plugin scripts. This may be + empty if no secret object is specified. If the secret object + contains more than one secret, all secrets are passed to the plugin + scripts. + 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 + required: + - driver + type: object + flocker: + description: flocker represents a Flocker volume attached + to a kubelet's host machine. This depends on the Flocker + control service being running + properties: + datasetName: + description: |- + datasetName is Name of the dataset stored as metadata -> name on the dataset for Flocker + should be considered as deprecated + type: string + datasetUUID: + description: datasetUUID is the UUID of the dataset. + This is unique identifier of a Flocker dataset + type: string + type: object + gcePersistentDisk: + description: |- + gcePersistentDisk represents a GCE Disk resource that is attached to a + kubelet's host machine and then exposed to the pod. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + properties: + fsType: + description: |- + fsType is filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + partition: + description: |- + partition is the partition in the volume that you want to mount. + If omitted, the default is to mount by volume name. + Examples: For volume /dev/sda1, you specify the partition as "1". + Similarly, the volume partition for /dev/sda is "0" (or you can leave the property empty). + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + format: int32 + type: integer + pdName: + description: |- + pdName is unique name of the PD resource in GCE. Used to identify the disk in GCE. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + type: string + readOnly: + description: |- + readOnly here will force the ReadOnly setting in VolumeMounts. + Defaults to false. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + type: boolean + required: + - pdName + type: object + gitRepo: + description: |- + gitRepo represents a git repository at a particular revision. + DEPRECATED: GitRepo is deprecated. To provision a container with a git repo, mount an + EmptyDir into an InitContainer that clones the repo using git, then mount the EmptyDir + into the Pod's container. + properties: + directory: + description: |- + directory is the target directory name. + Must not contain or start with '..'. If '.' is supplied, the volume directory will be the + git repository. Otherwise, if specified, the volume will contain the git repository in + the subdirectory with the given name. + type: string + repository: + description: repository is the URL + type: string + revision: + description: revision is the commit hash for the + specified revision. + type: string + required: + - repository + type: object + glusterfs: + description: |- + glusterfs represents a Glusterfs mount on the host that shares a pod's lifetime. + More info: https://examples.k8s.io/volumes/glusterfs/README.md + properties: + endpoints: + description: |- + endpoints is the endpoint name that details Glusterfs topology. + More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod + type: string + path: + description: |- + path is the Glusterfs volume path. + More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod + type: string + readOnly: + description: |- + readOnly here will force the Glusterfs volume to be mounted with read-only permissions. + Defaults to false. + More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod + type: boolean + required: + - endpoints + - path + type: object + hostPath: + description: |- + hostPath represents a pre-existing file or directory on the host + machine that is directly exposed to the container. This is generally + used for system agents or other privileged things that are allowed + to see the host machine. Most containers will NOT need this. + More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + --- + TODO(jonesdl) We need to restrict who can use host directory mounts and who can/can not + mount host directories as read/write. + properties: + path: + description: |- + path of the directory on the host. + If the path is a symlink, it will follow the link to the real path. + More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + type: string + type: + description: |- + type for HostPath Volume + Defaults to "" + More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + type: string + required: + - path + type: object + iscsi: + description: |- + iscsi represents an ISCSI Disk resource that is attached to a + kubelet's host machine and then exposed to the pod. + More info: https://examples.k8s.io/volumes/iscsi/README.md + properties: + chapAuthDiscovery: + description: chapAuthDiscovery defines whether support + iSCSI Discovery CHAP authentication + type: boolean + chapAuthSession: + description: chapAuthSession defines whether support + iSCSI Session CHAP authentication + type: boolean + fsType: + description: |- + fsType is the filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#iscsi + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + initiatorName: + description: |- + initiatorName is the custom iSCSI Initiator Name. + If initiatorName is specified with iscsiInterface simultaneously, new iSCSI interface + : will be created for the connection. + type: string + iqn: + description: iqn is the target iSCSI Qualified Name. + type: string + iscsiInterface: + description: |- + iscsiInterface is the interface Name that uses an iSCSI transport. + Defaults to 'default' (tcp). + type: string + lun: + description: lun represents iSCSI Target Lun number. + format: int32 + type: integer + portals: + description: |- + portals is the iSCSI Target Portal List. The portal is either an IP or ip_addr:port if the port + is other than default (typically TCP ports 860 and 3260). + items: + type: string + type: array + readOnly: + description: |- + readOnly here will force the ReadOnly setting in VolumeMounts. + Defaults to false. + type: boolean + secretRef: + description: secretRef is the CHAP Secret for iSCSI + target and initiator authentication + 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 + targetPortal: + description: |- + targetPortal is iSCSI Target Portal. The Portal is either an IP or ip_addr:port if the port + is other than default (typically TCP ports 860 and 3260). + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + description: |- + name of the volume. + Must be a DNS_LABEL and unique within the pod. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + nfs: + description: |- + nfs represents an NFS mount on the host that shares a pod's lifetime + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + properties: + path: + description: |- + path that is exported by the NFS server. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + type: string + readOnly: + description: |- + readOnly here will force the NFS export to be mounted with read-only permissions. + Defaults to false. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + type: boolean + server: + description: |- + server is the hostname or IP address of the NFS server. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + description: |- + persistentVolumeClaimVolumeSource represents a reference to a + PersistentVolumeClaim in the same namespace. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims + properties: + claimName: + description: |- + claimName is the name of a PersistentVolumeClaim in the same namespace as the pod using this volume. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims + type: string + readOnly: + description: |- + readOnly Will force the ReadOnly setting in VolumeMounts. + Default false. + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + description: photonPersistentDisk represents a PhotonController + persistent disk attached and mounted on kubelets host + machine + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + pdID: + description: pdID is the ID that identifies Photon + Controller persistent disk + type: string + required: + - pdID + type: object + portworxVolume: + description: portworxVolume represents a portworx volume + attached and mounted on kubelets host machine + properties: + fsType: + description: |- + fSType represents the filesystem type to mount + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs". Implicitly inferred to be "ext4" if unspecified. + type: string + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + volumeID: + description: volumeID uniquely identifies a Portworx + volume + type: string + required: + - volumeID + type: object + projected: + description: projected items for all in one resources + secrets, configmaps, and downward API + properties: + defaultMode: + description: |- + defaultMode are the mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + sources: + description: sources is the list of volume projections + items: + description: Projection that may be projected + along with other supported volume types + properties: + clusterTrustBundle: + description: |- + ClusterTrustBundle allows a pod to access the `.spec.trustBundle` field + of ClusterTrustBundle objects in an auto-updating file. + + + Alpha, gated by the ClusterTrustBundleProjection feature gate. + + + ClusterTrustBundle objects can either be selected by name, or by the + combination of signer name and a label selector. + + + Kubelet performs aggressive normalization of the PEM contents written + into the pod filesystem. Esoteric PEM features such as inter-block + comments and block headers are stripped. Certificates are deduplicated. + The ordering of certificates within the file is arbitrary, and Kubelet + may change the order over time. + properties: + labelSelector: + description: |- + Select all ClusterTrustBundles that match this label selector. Only has + effect if signerName is set. Mutually-exclusive with name. If unset, + interpreted as "match nothing". If set but empty, interpreted as "match + everything". + properties: + matchExpressions: + description: matchExpressions is a + list of label selector requirements. + The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + name: + description: |- + Select a single ClusterTrustBundle by object name. Mutually-exclusive + with signerName and labelSelector. + type: string + optional: + description: |- + If true, don't block pod startup if the referenced ClusterTrustBundle(s) + aren't available. If using name, then the named ClusterTrustBundle is + allowed not to exist. If using signerName, then the combination of + signerName and labelSelector is allowed to match zero + ClusterTrustBundles. + type: boolean + path: + description: Relative path from the volume + root to write the bundle. + type: string + signerName: + description: |- + Select all ClusterTrustBundles that match this signer name. + Mutually-exclusive with name. The contents of all selected + ClusterTrustBundles will be unified and deduplicated. + type: string + required: + - path + type: object + configMap: + description: configMap information about the + configMap data to project + properties: + items: + description: |- + items if unspecified, each key-value pair in the Data field of the referenced + ConfigMap will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the ConfigMap, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a + path within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + 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 + optional: + description: optional specify whether + the ConfigMap or its keys must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + downwardAPI: + description: downwardAPI information about + the downwardAPI data to project + properties: + items: + description: Items is a list of DownwardAPIVolume + file + items: + description: DownwardAPIVolumeFile represents + information to create the file containing + the pod field + properties: + fieldRef: + description: 'Required: Selects + a field of the pod: only annotations, + labels, name and namespace are + supported.' + properties: + apiVersion: + description: Version of the + schema the FieldPath is written + in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field + to select in the specified + API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + description: |- + Optional: mode bits used to set permissions on this file, must be an octal value + between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: 'Required: Path is the + relative path name of the file + to be created. Must not be absolute + or contain the ''..'' path. Must + be utf-8 encoded. The first item + of the relative path must not + start with ''..''' + type: string + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported. + properties: + containerName: + description: 'Container name: + required for volumes, optional + for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output + format of the exposed resources, + defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource + to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + type: object + secret: + description: secret information about the + secret data to project + properties: + items: + description: |- + items if unspecified, each key-value pair in the Data field of the referenced + Secret will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the Secret, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a + path within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + 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 + optional: + description: optional field specify whether + the Secret or its key must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + serviceAccountToken: + description: serviceAccountToken is information + about the serviceAccountToken data to project + properties: + audience: + description: |- + audience is the intended audience of the token. A recipient of a token + must identify itself with an identifier specified in the audience of the + token, and otherwise should reject the token. The audience defaults to the + identifier of the apiserver. + type: string + expirationSeconds: + description: |- + expirationSeconds is the requested duration of validity of the service + account token. As the token approaches expiration, the kubelet volume + plugin will proactively rotate the service account token. The kubelet will + start trying to rotate the token if the token is older than 80 percent of + its time to live or if the token is older than 24 hours.Defaults to 1 hour + and must be at least 10 minutes. + format: int64 + type: integer + path: + description: |- + path is the path relative to the mount point of the file to project the + token into. + type: string + required: + - path + type: object + type: object + type: array + type: object + quobyte: + description: quobyte represents a Quobyte mount on the + host that shares a pod's lifetime + properties: + group: + description: |- + group to map volume access to + Default is no group + type: string + readOnly: + description: |- + readOnly here will force the Quobyte volume to be mounted with read-only permissions. + Defaults to false. + type: boolean + registry: + description: |- + registry represents a single or multiple Quobyte Registry services + specified as a string as host:port pair (multiple entries are separated with commas) + which acts as the central registry for volumes + type: string + tenant: + description: |- + tenant owning the given Quobyte volume in the Backend + Used with dynamically provisioned Quobyte volumes, value is set by the plugin + type: string + user: + description: |- + user to map volume access to + Defaults to serivceaccount user + type: string + volume: + description: volume is a string that references + an already created Quobyte volume by name. + type: string + required: + - registry + - volume + type: object + rbd: + description: |- + rbd represents a Rados Block Device mount on the host that shares a pod's lifetime. + More info: https://examples.k8s.io/volumes/rbd/README.md + properties: + fsType: + description: |- + fsType is the filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#rbd + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + image: + description: |- + image is the rados image name. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + keyring: + description: |- + keyring is the path to key ring for RBDUser. + Default is /etc/ceph/keyring. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + monitors: + description: |- + monitors is a collection of Ceph monitors. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + items: + type: string + type: array + pool: + description: |- + pool is the rados pool name. + Default is rbd. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + readOnly: + description: |- + readOnly here will force the ReadOnly setting in VolumeMounts. + Defaults to false. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: boolean + secretRef: + description: |- + secretRef is name of the authentication secret for RBDUser. If provided + overrides keyring. + Default is nil. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + 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 + user: + description: |- + user is the rados user name. + Default is admin. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + required: + - image + - monitors + type: object + scaleIO: + description: scaleIO represents a ScaleIO persistent + volume attached and mounted on Kubernetes nodes. + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". + Default is "xfs". + type: string + gateway: + description: gateway is the host address of the + ScaleIO API Gateway. + type: string + protectionDomain: + description: protectionDomain is the name of the + ScaleIO Protection Domain for the configured storage. + type: string + readOnly: + description: |- + readOnly Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: |- + secretRef references to the secret for ScaleIO user and other + sensitive information. If this is not provided, Login operation will fail. + 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 + sslEnabled: + description: sslEnabled Flag enable/disable SSL + communication with Gateway, default false + type: boolean + storageMode: + description: |- + storageMode indicates whether the storage for a volume should be ThickProvisioned or ThinProvisioned. + Default is ThinProvisioned. + type: string + storagePool: + description: storagePool is the ScaleIO Storage + Pool associated with the protection domain. + type: string + system: + description: system is the name of the storage system + as configured in ScaleIO. + type: string + volumeName: + description: |- + volumeName is the name of a volume already created in the ScaleIO system + that is associated with this volume source. + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + description: |- + secret represents a secret that should populate this volume. + More info: https://kubernetes.io/docs/concepts/storage/volumes#secret + properties: + defaultMode: + description: |- + defaultMode is Optional: mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values + for mode bits. Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + items: + description: |- + items If unspecified, each key-value pair in the Data field of the referenced + Secret will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the Secret, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within + a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + optional: + description: optional field specify whether the + Secret or its keys must be defined + type: boolean + secretName: + description: |- + secretName is the name of the secret in the pod's namespace to use. + More info: https://kubernetes.io/docs/concepts/storage/volumes#secret + type: string + type: object + storageos: + description: storageOS represents a StorageOS volume + attached and mounted on Kubernetes nodes. + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: |- + secretRef specifies the secret to use for obtaining the StorageOS API + credentials. If not specified, default values will be attempted. + 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 + volumeName: + description: |- + volumeName is the human-readable name of the StorageOS volume. Volume + names are only unique within a namespace. + type: string + volumeNamespace: + description: |- + volumeNamespace specifies the scope of the volume within StorageOS. If no + namespace is specified then the Pod's namespace will be used. This allows the + Kubernetes name scoping to be mirrored within StorageOS for tighter integration. + Set VolumeName to any name to override the default behaviour. + Set to "default" if you are not using namespaces within StorageOS. + Namespaces that do not pre-exist within StorageOS will be created. + type: string + type: object + vsphereVolume: + description: vsphereVolume represents a vSphere volume + attached and mounted on kubelets host machine + properties: + fsType: + description: |- + fsType is filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + storagePolicyID: + description: storagePolicyID is the storage Policy + Based Management (SPBM) profile ID associated + with the StoragePolicyName. + type: string + storagePolicyName: + description: storagePolicyName is the storage Policy + Based Management (SPBM) profile name. + type: string + volumePath: + description: volumePath is the path that identifies + vSphere volume vmdk + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + required: + - containers + type: object + type: object + updateStrategy: + description: |- + Indicates the StatefulSetUpdateStrategy that will be + employed to update Pods in the InstanceSet when a revision is made to + Template. + UpdateStrategy.Type will be set to appsv1.OnDeleteStatefulSetStrategyType if MemberUpdateStrategy is not nil + + + Note: This field will be removed in future version. + properties: + rollingUpdate: + description: RollingUpdate is used to communicate parameters when + Type is RollingUpdateStatefulSetStrategyType. + properties: + maxUnavailable: + anyOf: + - type: integer + - type: string + description: |- + The maximum number of pods that can be unavailable during the update. + Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). + Absolute number is calculated from percentage by rounding up. This can not be 0. + Defaults to 1. This field is alpha-level and is only honored by servers that enable the + MaxUnavailableStatefulSet feature. The field applies to all pods in the range 0 to + Replicas-1. That means if there is any unavailable pod in the range 0 to Replicas-1, it + will be counted towards MaxUnavailable. + x-kubernetes-int-or-string: true + partition: + description: |- + Partition indicates the ordinal at which the StatefulSet should be partitioned + for updates. During a rolling update, all pods from ordinal Replicas-1 to + Partition are updated. All pods from ordinal Partition-1 to 0 remain untouched. + This is helpful in being able to do a canary based deployment. The default value is 0. + format: int32 + type: integer + type: object + type: + description: |- + Type indicates the type of the StatefulSetUpdateStrategy. + Default is RollingUpdate. + type: string + type: object + volumeClaimTemplates: + description: |- + Specifies a list of PersistentVolumeClaim templates that define the storage requirements for each replica. + Each template specifies the desired characteristics of a persistent volume, such as storage class, + size, and access modes. + These templates are used to dynamically provision persistent volumes for replicas upon their creation. + The final name of each PVC is generated by appending the pod's identifier to the name specified in volumeClaimTemplates[*].name. + items: + description: PersistentVolumeClaim is a user's request for and claim + to a persistent volume + 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: + description: |- + Standard object's metadata. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + description: |- + spec defines the desired characteristics of a volume requested by a pod author. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims + properties: + accessModes: + description: |- + accessModes contains the desired access modes the volume should have. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1 + items: + type: string + type: array + dataSource: + description: |- + dataSource field can be used to specify either: + * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) + * An existing PVC (PersistentVolumeClaim) + If the provisioner or an external controller can support the specified data source, + it will create a new volume based on the contents of the specified data source. + When the AnyVolumeDataSource feature gate is enabled, dataSource contents will be copied to dataSourceRef, + and dataSourceRef contents will be copied to dataSource when dataSourceRef.namespace is not specified. + If the namespace is specified, then dataSourceRef will not be copied to dataSource. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + description: |- + dataSourceRef specifies the object from which to populate the volume with data, if a non-empty + volume is desired. This may be any object from a non-empty API group (non + core object) or a PersistentVolumeClaim object. + When this field is specified, volume binding will only succeed if the type of + the specified object matches some installed volume populator or dynamic + provisioner. + This field will replace the functionality of the dataSource field and as such + if both fields are non-empty, they must have the same value. For backwards + compatibility, when namespace isn't specified in dataSourceRef, + both fields (dataSource and dataSourceRef) will be set to the same + value automatically if one of them is empty and the other is non-empty. + When namespace is specified in dataSourceRef, + dataSource isn't set to the same value and must be empty. + There are three important differences between dataSource and dataSourceRef: + * While dataSource only allows two specific types of objects, dataSourceRef + allows any non-core object, as well as PersistentVolumeClaim objects. + * While dataSource ignores disallowed values (dropping them), dataSourceRef + preserves all values, and generates an error if a disallowed value is + specified. + * While dataSource only allows local objects, dataSourceRef allows objects + in any namespaces. + (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled. + (Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + namespace: + description: |- + Namespace is the namespace of resource being referenced + Note that when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details. + (Alpha) This field requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + type: string + required: + - kind + - name + type: object + resources: + description: |- + resources represents the minimum resources the volume should have. + If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements + that are lower than previous value but must still be higher than capacity recorded in the + status field of the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + selector: + description: selector is a label query over volumes to consider + for binding. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + description: |- + storageClassName is the name of the StorageClass required by the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1 + type: string + volumeAttributesClassName: + description: |- + volumeAttributesClassName may be used to set the VolumeAttributesClass used by this claim. + If specified, the CSI driver will create or update the volume with the attributes defined + in the corresponding VolumeAttributesClass. This has a different purpose than storageClassName, + it can be changed after the claim is created. An empty string value means that no VolumeAttributesClass + will be applied to the claim but it's not allowed to reset this field to empty string once it is set. + If unspecified and the PersistentVolumeClaim is unbound, the default VolumeAttributesClass + will be set by the persistentvolume controller if it exists. + If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be + set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource + exists. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#volumeattributesclass + (Alpha) Using this field requires the VolumeAttributesClass feature gate to be enabled. + type: string + volumeMode: + description: |- + volumeMode defines what type of volume is required by the claim. + Value of Filesystem is implied when not included in claim spec. + type: string + volumeName: + description: volumeName is the binding reference to the + PersistentVolume backing this claim. + type: string + type: object + status: + description: |- + status represents the current information/status of a persistent volume claim. + Read-only. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims + properties: + accessModes: + description: |- + accessModes contains the actual access modes the volume backing the PVC has. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1 + items: + type: string + type: array + allocatedResourceStatuses: + additionalProperties: + description: |- + When a controller receives persistentvolume claim update with ClaimResourceStatus for a resource + that it does not recognizes, then it should ignore that update and let other controllers + handle it. + type: string + description: "allocatedResourceStatuses stores status of + resource being resized for the given PVC.\nKey names follow + standard Kubernetes label syntax. Valid values are either:\n\t* + Un-prefixed keys:\n\t\t- storage - the capacity of the + volume.\n\t* Custom resources must use implementation-defined + prefixed names such as \"example.com/my-custom-resource\"\nApart + from above values - keys that are unprefixed or have kubernetes.io + prefix are considered\nreserved and hence may not be used.\n\n\nClaimResourceStatus + can be in any of following states:\n\t- ControllerResizeInProgress:\n\t\tState + set when resize controller starts resizing the volume + in control-plane.\n\t- ControllerResizeFailed:\n\t\tState + set when resize has failed in resize controller with a + terminal error.\n\t- NodeResizePending:\n\t\tState set + when resize controller has finished resizing the volume + but further resizing of\n\t\tvolume is needed on the node.\n\t- + NodeResizeInProgress:\n\t\tState set when kubelet starts + resizing the volume.\n\t- NodeResizeFailed:\n\t\tState + set when resizing has failed in kubelet with a terminal + error. Transient errors don't set\n\t\tNodeResizeFailed.\nFor + example: if expanding a PVC for more capacity - this field + can be one of the following states:\n\t- pvc.status.allocatedResourceStatus['storage'] + = \"ControllerResizeInProgress\"\n - pvc.status.allocatedResourceStatus['storage'] + = \"ControllerResizeFailed\"\n - pvc.status.allocatedResourceStatus['storage'] + = \"NodeResizePending\"\n - pvc.status.allocatedResourceStatus['storage'] + = \"NodeResizeInProgress\"\n - pvc.status.allocatedResourceStatus['storage'] + = \"NodeResizeFailed\"\nWhen this field is not set, it + means that no resize operation is in progress for the + given PVC.\n\n\nA controller that receives PVC update + with previously unknown resourceName or ClaimResourceStatus\nshould + ignore the update for the purpose it was designed. For + example - a controller that\nonly is responsible for resizing + capacity of the volume, should ignore PVC updates that + change other valid\nresources associated with PVC.\n\n\nThis + is an alpha field and requires enabling RecoverVolumeExpansionFailure + feature." + type: object + x-kubernetes-map-type: granular + allocatedResources: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: "allocatedResources tracks the resources allocated + to a PVC including its capacity.\nKey names follow standard + Kubernetes label syntax. Valid values are either:\n\t* + Un-prefixed keys:\n\t\t- storage - the capacity of the + volume.\n\t* Custom resources must use implementation-defined + prefixed names such as \"example.com/my-custom-resource\"\nApart + from above values - keys that are unprefixed or have kubernetes.io + prefix are considered\nreserved and hence may not be used.\n\n\nCapacity + reported here may be larger than the actual capacity when + a volume expansion operation\nis requested.\nFor storage + quota, the larger value from allocatedResources and PVC.spec.resources + is used.\nIf allocatedResources is not set, PVC.spec.resources + alone is used for quota calculation.\nIf a volume expansion + capacity request is lowered, allocatedResources is only\nlowered + if there are no expansion operations in progress and if + the actual volume capacity\nis equal or lower than the + requested capacity.\n\n\nA controller that receives PVC + update with previously unknown resourceName\nshould ignore + the update for the purpose it was designed. For example + - a controller that\nonly is responsible for resizing + capacity of the volume, should ignore PVC updates that + change other valid\nresources associated with PVC.\n\n\nThis + is an alpha field and requires enabling RecoverVolumeExpansionFailure + feature." + type: object + capacity: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: capacity represents the actual resources of + the underlying volume. + type: object + conditions: + description: |- + conditions is the current Condition of persistent volume claim. If underlying persistent volume is being + resized then the Condition will be set to 'ResizeStarted'. + items: + description: PersistentVolumeClaimCondition contains details + about state of pvc + properties: + lastProbeTime: + description: lastProbeTime is the time we probed the + condition. + format: date-time + type: string + lastTransitionTime: + description: lastTransitionTime is the time the condition + transitioned from one status to another. + format: date-time + type: string + message: + description: message is the human-readable message + indicating details about last transition. + type: string + reason: + description: |- + reason is a unique, this should be a short, machine understandable string that gives the reason + for condition's last transition. If it reports "ResizeStarted" that means the underlying + persistent volume is being resized. + type: string + status: + type: string + type: + description: PersistentVolumeClaimConditionType is + a valid value of PersistentVolumeClaimCondition.Type + type: string + required: + - status + - type + type: object + type: array + currentVolumeAttributesClassName: + description: |- + currentVolumeAttributesClassName is the current name of the VolumeAttributesClass the PVC is using. + When unset, there is no VolumeAttributeClass applied to this PersistentVolumeClaim + This is an alpha field and requires enabling VolumeAttributesClass feature. + type: string + modifyVolumeStatus: + description: |- + ModifyVolumeStatus represents the status object of ControllerModifyVolume operation. + When this is unset, there is no ModifyVolume operation being attempted. + This is an alpha field and requires enabling VolumeAttributesClass feature. + properties: + status: + description: "status is the status of the ControllerModifyVolume + operation. It can be in any of following states:\n + - Pending\n Pending indicates that the PersistentVolumeClaim + cannot be modified due to unmet requirements, such + as\n the specified VolumeAttributesClass not existing.\n + - InProgress\n InProgress indicates that the volume + is being modified.\n - Infeasible\n Infeasible indicates + that the request has been rejected as invalid by the + CSI driver. To\n\t resolve the error, a valid VolumeAttributesClass + needs to be specified.\nNote: New statuses can be + added in the future. Consumers should check for unknown + statuses and fail appropriately." + type: string + targetVolumeAttributesClassName: + description: targetVolumeAttributesClassName is the + name of the VolumeAttributesClass the PVC currently + being reconciled + type: string + required: + - status + type: object + phase: + description: phase represents the current phase of PersistentVolumeClaim. + type: string + type: object + type: object + type: array + required: + - selector + - template + type: object + status: + description: Represents the current information about the state machine. + This data may be out of date. + properties: + availableReplicas: + description: Total number of available instances (ready for at least + minReadySeconds) targeted by this InstanceSet. + format: int32 + type: integer + conditions: + description: |- + Represents the latest available observations of an instanceset's current state. + Known .status.conditions.type are: "InstanceFailure", "InstanceReady" + items: + description: "Condition contains details for one aspect of the current + state of this API Resource.\n---\nThis struct is intended for + direct use as an array at the field path .status.conditions. For + example,\n\n\n\ttype FooStatus struct{\n\t // Represents the + observations of a foo's current state.\n\t // Known .status.conditions.type + are: \"Available\", \"Progressing\", and \"Degraded\"\n\t // + +patchMergeKey=type\n\t // +patchStrategy=merge\n\t // +listType=map\n\t + \ // +listMapKey=type\n\t Conditions []metav1.Condition `json:\"conditions,omitempty\" + patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t + \ // other fields\n\t}" + 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 + currentReplicas: + description: |- + currentReplicas is the number of instances created by the InstanceSet controller from the InstanceSet version + indicated by CurrentRevisions. + format: int32 + type: integer + currentRevision: + description: |- + currentRevision, if not empty, indicates the version of the InstanceSet used to generate instances in the + sequence [0,currentReplicas). + type: string + currentRevisions: + additionalProperties: + type: string + description: |- + currentRevisions, if not empty, indicates the old version of the InstanceSet used to generate the underlying workload. + key is the pod name, value is the revision. + type: object + initReplicas: + description: |- + Defines the initial number of instances when the cluster is first initialized. + This value is set to spec.Replicas at the time of object creation and remains constant thereafter. + Used only when spec.roles set. + format: int32 + type: integer + membersStatus: + description: Provides the status of each member in the cluster. + items: + properties: + podName: + default: Unknown + description: Represents the name of the pod. + type: string + role: + description: Defines the role of the replica in the cluster. + properties: + accessMode: + default: ReadWrite + description: Specifies the service capabilities of this + member. + enum: + - None + - Readonly + - ReadWrite + type: string + canVote: + default: true + description: Indicates if this member has voting rights. + type: boolean + isLeader: + default: false + description: Determines if this member is the leader. + type: boolean + name: + default: leader + description: Defines the role name of the replica. + type: string + required: + - accessMode + - name + type: object + required: + - podName + type: object + type: array + observedGeneration: + description: |- + observedGeneration is the most recent generation observed for this InstanceSet. It corresponds to the + InstanceSet's generation, which is updated on mutation by the API Server. + format: int64 + type: integer + readyInitReplicas: + description: |- + Represents the number of instances that have already reached the MembersStatus during the cluster initialization stage. + This value remains constant once it equals InitReplicas. + Used only when spec.roles set. + format: int32 + type: integer + readyReplicas: + description: readyReplicas is the number of instances created for + this InstanceSet with a Ready Condition. + format: int32 + type: integer + readyWithoutPrimary: + description: Indicates whether it is required for the InstanceSet + to have at least one primary instance ready. + type: boolean + replicas: + description: replicas is the number of instances created by the InstanceSet + controller. + format: int32 + type: integer + templatesStatus: + description: TemplatesStatus represents status of each instance generated + by InstanceTemplates + items: + description: InstanceTemplateStatus aggregates the status of replicas + for each InstanceTemplate + properties: + availableReplicas: + description: AvailableReplicas is the number of Pods that ready + for at least minReadySeconds. + format: int32 + type: integer + currentReplicas: + description: |- + currentReplicas is the number of instances created by the InstanceSet controller from the InstanceSet version + indicated by CurrentRevisions. + format: int32 + type: integer + name: + description: Name, the name of the InstanceTemplate. + type: string + readyReplicas: + description: ReadyReplicas is the number of Pods that have a + Ready Condition. + format: int32 + type: integer + replicas: + description: Replicas is the number of replicas of the InstanceTemplate. + format: int32 + type: integer + updatedReplicas: + description: |- + UpdatedReplicas is the number of Pods created by the InstanceSet controller from the InstanceSet version + indicated by UpdateRevisions. + format: int32 + type: integer + required: + - name + type: object + type: array + updateRevision: + description: |- + updateRevision, if not empty, indicates the version of the InstanceSet used to generate instances in the sequence + [replicas-updatedReplicas,replicas) + type: string + updateRevisions: + additionalProperties: + type: string + description: |- + updateRevisions, if not empty, indicates the new version of the InstanceSet used to generate the underlying workload. + key is the pod name, value is the revision. + type: object + updatedReplicas: + description: |- + updatedReplicas is the number of instances created by the InstanceSet controller from the InstanceSet version + indicated by UpdateRevisions. + format: int32 + type: integer + required: + - replicas + type: object + type: object + served: true + storage: true + subresources: + scale: + specReplicasPath: .spec.replicas + statusReplicasPath: .status.replicas + status: {} - additionalPrinterColumns: - description: leader instance name. jsonPath: .status.membersStatus[?(@.role.isLeader==true)].podName @@ -13092,7 +26171,7 @@ spec: type: object type: object served: true - storage: true + storage: false subresources: scale: specReplicasPath: .spec.replicas diff --git a/config/samples/workloads_v1_instanceset.yaml b/config/samples/workloads_v1_instanceset.yaml new file mode 100644 index 00000000000..dded6a2ed9d --- /dev/null +++ b/config/samples/workloads_v1_instanceset.yaml @@ -0,0 +1,12 @@ +apiVersion: workloads.kubeblocks.io/v1 +kind: InstanceSet +metadata: + labels: + app.kubernetes.io/name: instanceset + app.kubernetes.io/instance: instanceset-sample + app.kubernetes.io/part-of: kubeblocks + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/created-by: kubeblocks + name: instanceset-sample +spec: + # TODO(user): Add fields here diff --git a/controllers/apps/cluster_plan_builder.go b/controllers/apps/cluster_plan_builder.go index efe2b130e2e..e0e5799d6e1 100644 --- a/controllers/apps/cluster_plan_builder.go +++ b/controllers/apps/cluster_plan_builder.go @@ -41,7 +41,7 @@ import ( appsv1beta1 "github.com/apecloud/kubeblocks/apis/apps/v1beta1" dpv1alpha1 "github.com/apecloud/kubeblocks/apis/dataprotection/v1alpha1" extensionsv1alpha1 "github.com/apecloud/kubeblocks/apis/extensions/v1alpha1" - workloadsv1alpha1 "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" + workloadsv1 "github.com/apecloud/kubeblocks/apis/workloads/v1" "github.com/apecloud/kubeblocks/pkg/constant" "github.com/apecloud/kubeblocks/pkg/controller/graph" "github.com/apecloud/kubeblocks/pkg/controller/model" @@ -108,12 +108,13 @@ func (c *clusterTransformContext) GetLogger() logr.Logger { func init() { model.AddScheme(appsv1alpha1.AddToScheme) + model.AddScheme(appsv1beta1.AddToScheme) + model.AddScheme(appsv1.AddToScheme) model.AddScheme(dpv1alpha1.AddToScheme) model.AddScheme(snapshotv1.AddToScheme) model.AddScheme(snapshotv1beta1.AddToScheme) model.AddScheme(extensionsv1alpha1.AddToScheme) - model.AddScheme(workloadsv1alpha1.AddToScheme) - model.AddScheme(appsv1beta1.AddToScheme) + model.AddScheme(workloadsv1.AddToScheme) } // PlanBuilder implementation diff --git a/controllers/apps/component_controller.go b/controllers/apps/component_controller.go index 1092244cb6a..90322d7dbe9 100644 --- a/controllers/apps/component_controller.go +++ b/controllers/apps/component_controller.go @@ -39,7 +39,7 @@ import ( appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" dpv1alpha1 "github.com/apecloud/kubeblocks/apis/dataprotection/v1alpha1" - workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" + workloads "github.com/apecloud/kubeblocks/apis/workloads/v1" "github.com/apecloud/kubeblocks/pkg/constant" "github.com/apecloud/kubeblocks/pkg/controller/multicluster" intctrlutil "github.com/apecloud/kubeblocks/pkg/controllerutil" diff --git a/controllers/apps/component_controller_test.go b/controllers/apps/component_controller_test.go index 0ad24cc5f69..e8b3e3c4d10 100644 --- a/controllers/apps/component_controller_test.go +++ b/controllers/apps/component_controller_test.go @@ -50,7 +50,7 @@ import ( kbappsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" dpv1alpha1 "github.com/apecloud/kubeblocks/apis/dataprotection/v1alpha1" - workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" + workloads "github.com/apecloud/kubeblocks/apis/workloads/v1" "github.com/apecloud/kubeblocks/pkg/constant" "github.com/apecloud/kubeblocks/pkg/controller/component" "github.com/apecloud/kubeblocks/pkg/controller/plan" diff --git a/controllers/apps/component_hscale_volume_populator.go b/controllers/apps/component_hscale_volume_populator.go index 39db28e8d85..66afa80adbc 100644 --- a/controllers/apps/component_hscale_volume_populator.go +++ b/controllers/apps/component_hscale_volume_populator.go @@ -31,7 +31,7 @@ import ( appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" dpv1alpha1 "github.com/apecloud/kubeblocks/apis/dataprotection/v1alpha1" - workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" + workloads "github.com/apecloud/kubeblocks/apis/workloads/v1" "github.com/apecloud/kubeblocks/pkg/constant" "github.com/apecloud/kubeblocks/pkg/controller/component" "github.com/apecloud/kubeblocks/pkg/controller/factory" diff --git a/controllers/apps/component_utils.go b/controllers/apps/component_utils.go index 67d791f0d6f..e43f1af7eb9 100644 --- a/controllers/apps/component_utils.go +++ b/controllers/apps/component_utils.go @@ -24,12 +24,12 @@ import ( corev1 "k8s.io/api/core/v1" - "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" + workloads "github.com/apecloud/kubeblocks/apis/workloads/v1" "github.com/apecloud/kubeblocks/pkg/constant" viper "github.com/apecloud/kubeblocks/pkg/viperx" ) -func delayUpdateInstanceSetSystemFields(obj v1alpha1.InstanceSetSpec, pobj *v1alpha1.InstanceSetSpec) { +func delayUpdateInstanceSetSystemFields(obj workloads.InstanceSetSpec, pobj *workloads.InstanceSetSpec) { delayUpdatePodSpecSystemFields(obj.Template.Spec, &pobj.Template.Spec) if pobj.RoleProbe != nil && obj.RoleProbe != nil { @@ -48,7 +48,7 @@ func delayUpdatePodSpecSystemFields(obj corev1.PodSpec, pobj *corev1.PodSpec) { } } -func updateInstanceSetSystemFields(obj v1alpha1.InstanceSetSpec, pobj *v1alpha1.InstanceSetSpec) { +func updateInstanceSetSystemFields(obj workloads.InstanceSetSpec, pobj *workloads.InstanceSetSpec) { updatePodSpecSystemFields(obj.Template.Spec, &pobj.Template.Spec) if pobj.RoleProbe != nil && obj.RoleProbe != nil { pobj.RoleProbe.FailureThreshold = obj.RoleProbe.FailureThreshold diff --git a/controllers/apps/component_utils_test.go b/controllers/apps/component_utils_test.go index df699b0fed1..cc90b46ad54 100644 --- a/controllers/apps/component_utils_test.go +++ b/controllers/apps/component_utils_test.go @@ -30,7 +30,7 @@ import ( "k8s.io/apimachinery/pkg/util/intstr" "sigs.k8s.io/controller-runtime/pkg/client" - workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" + workloads "github.com/apecloud/kubeblocks/apis/workloads/v1" "github.com/apecloud/kubeblocks/pkg/controllerutil" "github.com/apecloud/kubeblocks/pkg/generics" testapps "github.com/apecloud/kubeblocks/pkg/testutil/apps" diff --git a/controllers/apps/configuration/config_reconcile_wrapper.go b/controllers/apps/configuration/config_reconcile_wrapper.go index 3fc52c284ea..fe90d75b62a 100644 --- a/controllers/apps/configuration/config_reconcile_wrapper.go +++ b/controllers/apps/configuration/config_reconcile_wrapper.go @@ -23,7 +23,7 @@ import ( corev1 "k8s.io/api/core/v1" "sigs.k8s.io/controller-runtime/pkg/client" - workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" + workloads "github.com/apecloud/kubeblocks/apis/workloads/v1" "github.com/apecloud/kubeblocks/pkg/controller/component" configctrl "github.com/apecloud/kubeblocks/pkg/controller/configuration" intctrlutil "github.com/apecloud/kubeblocks/pkg/controllerutil" diff --git a/controllers/apps/configuration/config_related_helper.go b/controllers/apps/configuration/config_related_helper.go index 1acdbad1310..3d3aa028568 100644 --- a/controllers/apps/configuration/config_related_helper.go +++ b/controllers/apps/configuration/config_related_helper.go @@ -27,7 +27,7 @@ import ( corev1 "k8s.io/api/core/v1" "sigs.k8s.io/controller-runtime/pkg/client" - workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" + workloads "github.com/apecloud/kubeblocks/apis/workloads/v1" "github.com/apecloud/kubeblocks/pkg/configuration/core" cfgutil "github.com/apecloud/kubeblocks/pkg/configuration/util" "github.com/apecloud/kubeblocks/pkg/constant" diff --git a/controllers/apps/configuration/policy_util.go b/controllers/apps/configuration/policy_util.go index 67bcdd3ddd2..3f92f3ff0df 100644 --- a/controllers/apps/configuration/policy_util.go +++ b/controllers/apps/configuration/policy_util.go @@ -29,7 +29,7 @@ import ( corev1 "k8s.io/api/core/v1" "sigs.k8s.io/controller-runtime/pkg/client" - workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" + workloads "github.com/apecloud/kubeblocks/apis/workloads/v1" "github.com/apecloud/kubeblocks/pkg/configuration/core" cfgproto "github.com/apecloud/kubeblocks/pkg/configuration/proto" "github.com/apecloud/kubeblocks/pkg/constant" diff --git a/controllers/apps/configuration/policy_util_test.go b/controllers/apps/configuration/policy_util_test.go index 30ed8880c33..d243009c070 100644 --- a/controllers/apps/configuration/policy_util_test.go +++ b/controllers/apps/configuration/policy_util_test.go @@ -34,7 +34,7 @@ import ( appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1beta1 "github.com/apecloud/kubeblocks/apis/apps/v1beta1" - workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" + workloads "github.com/apecloud/kubeblocks/apis/workloads/v1" "github.com/apecloud/kubeblocks/pkg/configuration/core" "github.com/apecloud/kubeblocks/pkg/controller/component" intctrlutil "github.com/apecloud/kubeblocks/pkg/controllerutil" diff --git a/controllers/apps/configuration/reconfigure_policy.go b/controllers/apps/configuration/reconfigure_policy.go index abdfc0d6278..854189fb7f7 100644 --- a/controllers/apps/configuration/reconfigure_policy.go +++ b/controllers/apps/configuration/reconfigure_policy.go @@ -31,7 +31,7 @@ import ( appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" appsv1beta1 "github.com/apecloud/kubeblocks/apis/apps/v1beta1" - workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" + workloads "github.com/apecloud/kubeblocks/apis/workloads/v1" configmanager "github.com/apecloud/kubeblocks/pkg/configuration/config_manager" "github.com/apecloud/kubeblocks/pkg/configuration/core" cfgproto "github.com/apecloud/kubeblocks/pkg/configuration/proto" diff --git a/controllers/apps/configuration/suite_test.go b/controllers/apps/configuration/suite_test.go index a64d20c0512..0035a97c3eb 100644 --- a/controllers/apps/configuration/suite_test.go +++ b/controllers/apps/configuration/suite_test.go @@ -39,7 +39,7 @@ import ( appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" appsv1beta1 "github.com/apecloud/kubeblocks/apis/apps/v1beta1" - workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" + workloadsv1 "github.com/apecloud/kubeblocks/apis/workloads/v1" intctrlutil "github.com/apecloud/kubeblocks/pkg/controllerutil" "github.com/apecloud/kubeblocks/pkg/testutil" viper "github.com/apecloud/kubeblocks/pkg/viperx" @@ -81,10 +81,10 @@ var _ = BeforeSuite(func() { err = appsv1alpha1.AddToScheme(scheme.Scheme) Expect(err).NotTo(HaveOccurred()) - err = workloads.AddToScheme(scheme.Scheme) - Expect(err).NotTo(HaveOccurred()) err = appsv1beta1.AddToScheme(scheme.Scheme) Expect(err).NotTo(HaveOccurred()) + err = workloadsv1.AddToScheme(scheme.Scheme) + Expect(err).NotTo(HaveOccurred()) // +kubebuilder:scaffold:scheme diff --git a/controllers/apps/operations/ops_progress_util.go b/controllers/apps/operations/ops_progress_util.go index 1f3020d8765..2fe1c6d8d53 100644 --- a/controllers/apps/operations/ops_progress_util.go +++ b/controllers/apps/operations/ops_progress_util.go @@ -35,7 +35,7 @@ import ( appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" - workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" + workloads "github.com/apecloud/kubeblocks/apis/workloads/v1" "github.com/apecloud/kubeblocks/pkg/constant" intctrlcomp "github.com/apecloud/kubeblocks/pkg/controller/component" "github.com/apecloud/kubeblocks/pkg/controller/instanceset" diff --git a/controllers/apps/operations/restart.go b/controllers/apps/operations/restart.go index fe1213d7142..428bd0932c7 100644 --- a/controllers/apps/operations/restart.go +++ b/controllers/apps/operations/restart.go @@ -31,7 +31,7 @@ import ( appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" - workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" + workloads "github.com/apecloud/kubeblocks/apis/workloads/v1" "github.com/apecloud/kubeblocks/pkg/constant" intctrlutil "github.com/apecloud/kubeblocks/pkg/controllerutil" ) diff --git a/controllers/apps/operations/suite_test.go b/controllers/apps/operations/suite_test.go index 0c9f2ca3abd..820dd1aefe6 100644 --- a/controllers/apps/operations/suite_test.go +++ b/controllers/apps/operations/suite_test.go @@ -44,7 +44,7 @@ import ( appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" appsv1beta1 "github.com/apecloud/kubeblocks/apis/apps/v1beta1" dpv1alpha1 "github.com/apecloud/kubeblocks/apis/dataprotection/v1alpha1" - workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" + workloads "github.com/apecloud/kubeblocks/apis/workloads/v1" "github.com/apecloud/kubeblocks/pkg/constant" intctrlcomp "github.com/apecloud/kubeblocks/pkg/controller/component" intctrlutil "github.com/apecloud/kubeblocks/pkg/controllerutil" @@ -105,10 +105,12 @@ var _ = BeforeSuite(func() { Expect(err).NotTo(HaveOccurred()) err = appsv1beta1.AddToScheme(scheme.Scheme) Expect(err).NotTo(HaveOccurred()) - err = workloads.AddToScheme(scheme.Scheme) + err = appsv1.AddToScheme(scheme.Scheme) Expect(err).NotTo(HaveOccurred()) err = dpv1alpha1.AddToScheme(scheme.Scheme) Expect(err).NotTo(HaveOccurred()) + err = workloads.AddToScheme(scheme.Scheme) + Expect(err).NotTo(HaveOccurred()) // +kubebuilder:scaffold:scheme diff --git a/controllers/apps/opsrequest_controller.go b/controllers/apps/opsrequest_controller.go index b7c35d10b1a..95575743e20 100644 --- a/controllers/apps/opsrequest_controller.go +++ b/controllers/apps/opsrequest_controller.go @@ -45,7 +45,7 @@ import ( appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" dpv1alpha1 "github.com/apecloud/kubeblocks/apis/dataprotection/v1alpha1" - workloadsv1alpha1 "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" + workloads "github.com/apecloud/kubeblocks/apis/workloads/v1" "github.com/apecloud/kubeblocks/controllers/apps/operations" opsutil "github.com/apecloud/kubeblocks/controllers/apps/operations/util" "github.com/apecloud/kubeblocks/pkg/constant" @@ -95,7 +95,7 @@ func (r *OpsRequestReconciler) SetupWithManager(mgr ctrl.Manager) error { MaxConcurrentReconciles: int(math.Ceil(viper.GetFloat64(constant.CfgKBReconcileWorkers) / 2)), }). Watches(&appsv1.Cluster{}, handler.EnqueueRequestsFromMapFunc(r.parseRunningOpsRequests)). - Watches(&workloadsv1alpha1.InstanceSet{}, handler.EnqueueRequestsFromMapFunc(r.parseRunningOpsRequestsForInstanceSet)). + Watches(&workloads.InstanceSet{}, handler.EnqueueRequestsFromMapFunc(r.parseRunningOpsRequestsForInstanceSet)). Watches(&dpv1alpha1.Backup{}, handler.EnqueueRequestsFromMapFunc(r.parseBackupOpsRequest)). Watches(&corev1.PersistentVolumeClaim{}, handler.EnqueueRequestsFromMapFunc(r.parseVolumeExpansionOpsRequest)). Watches(&corev1.Pod{}, handler.EnqueueRequestsFromMapFunc(r.parsePod)). @@ -422,7 +422,7 @@ func (r *OpsRequestReconciler) parseRunningOpsRequests(ctx context.Context, obje } func (r *OpsRequestReconciler) parseRunningOpsRequestsForInstanceSet(ctx context.Context, object client.Object) []reconcile.Request { - its := object.(*workloadsv1alpha1.InstanceSet) + its := object.(*workloads.InstanceSet) clusterName := its.Labels[constant.AppInstanceLabelKey] if clusterName == "" { return nil diff --git a/controllers/apps/opsrequest_controller_test.go b/controllers/apps/opsrequest_controller_test.go index 2c18c3db23e..532cfcb6243 100644 --- a/controllers/apps/opsrequest_controller_test.go +++ b/controllers/apps/opsrequest_controller_test.go @@ -41,7 +41,7 @@ import ( appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" dpv1alpha1 "github.com/apecloud/kubeblocks/apis/dataprotection/v1alpha1" - workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" + workloads "github.com/apecloud/kubeblocks/apis/workloads/v1" opsutil "github.com/apecloud/kubeblocks/controllers/apps/operations/util" "github.com/apecloud/kubeblocks/pkg/constant" "github.com/apecloud/kubeblocks/pkg/controller/component" diff --git a/controllers/apps/suite_test.go b/controllers/apps/suite_test.go index 22194f96919..188ac558181 100644 --- a/controllers/apps/suite_test.go +++ b/controllers/apps/suite_test.go @@ -48,7 +48,7 @@ import ( appsv1beta1 "github.com/apecloud/kubeblocks/apis/apps/v1beta1" dpv1alpha1 "github.com/apecloud/kubeblocks/apis/dataprotection/v1alpha1" "github.com/apecloud/kubeblocks/apis/workloads/legacy" - workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" + workloadsv1 "github.com/apecloud/kubeblocks/apis/workloads/v1" "github.com/apecloud/kubeblocks/controllers/apps/configuration" "github.com/apecloud/kubeblocks/controllers/k8score" "github.com/apecloud/kubeblocks/pkg/constant" @@ -142,9 +142,9 @@ var _ = BeforeSuite(func() { Expect(err).NotTo(HaveOccurred()) model.AddScheme(snapshotv1.AddToScheme) - err = workloads.AddToScheme(scheme.Scheme) + err = workloadsv1.AddToScheme(scheme.Scheme) Expect(err).NotTo(HaveOccurred()) - model.AddScheme(workloads.AddToScheme) + model.AddScheme(workloadsv1.AddToScheme) err = legacy.AddToScheme(scheme.Scheme) Expect(err).NotTo(HaveOccurred()) diff --git a/controllers/apps/transform_types.go b/controllers/apps/transform_types.go index 3ca02f57d68..735ce8428c9 100644 --- a/controllers/apps/transform_types.go +++ b/controllers/apps/transform_types.go @@ -32,7 +32,7 @@ import ( appsv1beta1 "github.com/apecloud/kubeblocks/apis/apps/v1beta1" dpv1alpha1 "github.com/apecloud/kubeblocks/apis/dataprotection/v1alpha1" extensionsv1alpha1 "github.com/apecloud/kubeblocks/apis/extensions/v1alpha1" - workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" + workloads "github.com/apecloud/kubeblocks/apis/workloads/v1" ) var ( diff --git a/controllers/apps/transform_utils.go b/controllers/apps/transform_utils.go index 75e170ed429..25d9282e685 100644 --- a/controllers/apps/transform_utils.go +++ b/controllers/apps/transform_utils.go @@ -37,7 +37,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" - workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" + workloads "github.com/apecloud/kubeblocks/apis/workloads/v1" "github.com/apecloud/kubeblocks/pkg/constant" "github.com/apecloud/kubeblocks/pkg/controller/graph" "github.com/apecloud/kubeblocks/pkg/controller/model" diff --git a/controllers/apps/transform_utils_test.go b/controllers/apps/transform_utils_test.go index c646b9ee0dd..ff52bcd15c6 100644 --- a/controllers/apps/transform_utils_test.go +++ b/controllers/apps/transform_utils_test.go @@ -36,7 +36,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" kbappsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" - workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" + workloads "github.com/apecloud/kubeblocks/apis/workloads/v1" ) func TestReflect(t *testing.T) { diff --git a/controllers/apps/transformer_cluster_backup_policy.go b/controllers/apps/transformer_cluster_backup_policy.go index 96b6c89b1e9..72978b2af77 100644 --- a/controllers/apps/transformer_cluster_backup_policy.go +++ b/controllers/apps/transformer_cluster_backup_policy.go @@ -33,7 +33,7 @@ import ( appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" dpv1alpha1 "github.com/apecloud/kubeblocks/apis/dataprotection/v1alpha1" - workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" + workloads "github.com/apecloud/kubeblocks/apis/workloads/v1" "github.com/apecloud/kubeblocks/pkg/common" "github.com/apecloud/kubeblocks/pkg/constant" "github.com/apecloud/kubeblocks/pkg/controller/graph" diff --git a/controllers/apps/transformer_component_deletion.go b/controllers/apps/transformer_component_deletion.go index 24a7d4392c7..c72c599188d 100644 --- a/controllers/apps/transformer_component_deletion.go +++ b/controllers/apps/transformer_component_deletion.go @@ -35,7 +35,7 @@ import ( appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" dpv1alpha1 "github.com/apecloud/kubeblocks/apis/dataprotection/v1alpha1" - wlv1alpha1 "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" + workloads "github.com/apecloud/kubeblocks/apis/workloads/v1" "github.com/apecloud/kubeblocks/pkg/constant" "github.com/apecloud/kubeblocks/pkg/controller/component" "github.com/apecloud/kubeblocks/pkg/controller/graph" @@ -174,13 +174,13 @@ func (t *componentDeletionTransformer) getCluster(transCtx *componentTransformCo func compOwnedWorkloadKinds() []client.ObjectList { return []client.ObjectList{ - &wlv1alpha1.InstanceSetList{}, + &workloads.InstanceSetList{}, } } func compOwnedKinds() []client.ObjectList { return []client.ObjectList{ - &wlv1alpha1.InstanceSetList{}, + &workloads.InstanceSetList{}, &policyv1.PodDisruptionBudgetList{}, &corev1.ServiceList{}, &corev1.ServiceAccountList{}, diff --git a/controllers/apps/transformer_component_rbac.go b/controllers/apps/transformer_component_rbac.go index af528478a8b..5261e4ed930 100644 --- a/controllers/apps/transformer_component_rbac.go +++ b/controllers/apps/transformer_component_rbac.go @@ -32,7 +32,7 @@ import ( appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" - workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" + workloads "github.com/apecloud/kubeblocks/apis/workloads/v1" "github.com/apecloud/kubeblocks/pkg/common" "github.com/apecloud/kubeblocks/pkg/constant" "github.com/apecloud/kubeblocks/pkg/controller/factory" diff --git a/controllers/apps/transformer_component_rbac_test.go b/controllers/apps/transformer_component_rbac_test.go index 6f75cdf46c9..2aa0e3e08ac 100644 --- a/controllers/apps/transformer_component_rbac_test.go +++ b/controllers/apps/transformer_component_rbac_test.go @@ -27,7 +27,7 @@ import ( "k8s.io/apimachinery/pkg/types" appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" - workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" + workloads "github.com/apecloud/kubeblocks/apis/workloads/v1" "github.com/apecloud/kubeblocks/pkg/constant" "github.com/apecloud/kubeblocks/pkg/controller/component" "github.com/apecloud/kubeblocks/pkg/controller/factory" diff --git a/controllers/apps/transformer_component_service.go b/controllers/apps/transformer_component_service.go index e98a70ebc5b..aed1d3dc002 100644 --- a/controllers/apps/transformer_component_service.go +++ b/controllers/apps/transformer_component_service.go @@ -31,7 +31,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" - workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" + workloads "github.com/apecloud/kubeblocks/apis/workloads/v1" "github.com/apecloud/kubeblocks/pkg/common" "github.com/apecloud/kubeblocks/pkg/constant" "github.com/apecloud/kubeblocks/pkg/controller/builder" diff --git a/controllers/apps/transformer_component_status.go b/controllers/apps/transformer_component_status.go index 7295e58c851..7ce8d6d7ed5 100644 --- a/controllers/apps/transformer_component_status.go +++ b/controllers/apps/transformer_component_status.go @@ -33,7 +33,7 @@ import ( appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" dpv1alpha1 "github.com/apecloud/kubeblocks/apis/dataprotection/v1alpha1" - workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" + workloads "github.com/apecloud/kubeblocks/apis/workloads/v1" cfgcore "github.com/apecloud/kubeblocks/pkg/configuration/core" "github.com/apecloud/kubeblocks/pkg/constant" "github.com/apecloud/kubeblocks/pkg/controller/component" diff --git a/controllers/apps/transformer_component_vars.go b/controllers/apps/transformer_component_vars.go index d3f50d3a764..2d9d759c592 100644 --- a/controllers/apps/transformer_component_vars.go +++ b/controllers/apps/transformer_component_vars.go @@ -31,7 +31,7 @@ import ( "k8s.io/apimachinery/pkg/util/sets" "sigs.k8s.io/controller-runtime/pkg/client" - workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" + workloads "github.com/apecloud/kubeblocks/apis/workloads/v1" "github.com/apecloud/kubeblocks/pkg/common" "github.com/apecloud/kubeblocks/pkg/constant" "github.com/apecloud/kubeblocks/pkg/controller/builder" diff --git a/controllers/apps/transformer_component_workload.go b/controllers/apps/transformer_component_workload.go index 7823654b90e..a492000aa64 100644 --- a/controllers/apps/transformer_component_workload.go +++ b/controllers/apps/transformer_component_workload.go @@ -37,7 +37,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" - workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" + workloads "github.com/apecloud/kubeblocks/apis/workloads/v1" "github.com/apecloud/kubeblocks/pkg/constant" "github.com/apecloud/kubeblocks/pkg/controller/component" "github.com/apecloud/kubeblocks/pkg/controller/component/lifecycle" diff --git a/controllers/apps/transformer_component_workload_upgrade.go b/controllers/apps/transformer_component_workload_upgrade.go index 976a08f2162..77574e6346f 100644 --- a/controllers/apps/transformer_component_workload_upgrade.go +++ b/controllers/apps/transformer_component_workload_upgrade.go @@ -32,7 +32,7 @@ import ( kbappsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" "github.com/apecloud/kubeblocks/apis/workloads/legacy" - workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" + workloads "github.com/apecloud/kubeblocks/apis/workloads/v1" "github.com/apecloud/kubeblocks/pkg/constant" "github.com/apecloud/kubeblocks/pkg/controller/component" "github.com/apecloud/kubeblocks/pkg/controller/factory" diff --git a/controllers/experimental/reconciler_update_status.go b/controllers/experimental/reconciler_update_status.go index d164b7dc87b..22ba0bcc19d 100644 --- a/controllers/experimental/reconciler_update_status.go +++ b/controllers/experimental/reconciler_update_status.go @@ -30,7 +30,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" experimental "github.com/apecloud/kubeblocks/apis/experimental/v1alpha1" - workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" + workloads "github.com/apecloud/kubeblocks/apis/workloads/v1" "github.com/apecloud/kubeblocks/pkg/constant" "github.com/apecloud/kubeblocks/pkg/controller/kubebuilderx" "github.com/apecloud/kubeblocks/pkg/controller/model" diff --git a/controllers/experimental/reconciler_update_status_test.go b/controllers/experimental/reconciler_update_status_test.go index a8838c6bd24..b9661235f78 100644 --- a/controllers/experimental/reconciler_update_status_test.go +++ b/controllers/experimental/reconciler_update_status_test.go @@ -27,7 +27,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" experimentalv1alpha1 "github.com/apecloud/kubeblocks/apis/experimental/v1alpha1" - workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" + workloads "github.com/apecloud/kubeblocks/apis/workloads/v1" "github.com/apecloud/kubeblocks/pkg/controller/kubebuilderx" ) diff --git a/controllers/experimental/suite_test.go b/controllers/experimental/suite_test.go index 8675c7196c1..53c2d89425f 100644 --- a/controllers/experimental/suite_test.go +++ b/controllers/experimental/suite_test.go @@ -33,7 +33,7 @@ import ( //+kubebuilder:scaffold:imports appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" experimentalv1alpha1 "github.com/apecloud/kubeblocks/apis/experimental/v1alpha1" - workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" + workloads "github.com/apecloud/kubeblocks/apis/workloads/v1" "github.com/apecloud/kubeblocks/pkg/constant" "github.com/apecloud/kubeblocks/pkg/controller/builder" "github.com/apecloud/kubeblocks/pkg/controller/kubebuilderx" diff --git a/controllers/experimental/tree_loader.go b/controllers/experimental/tree_loader.go index d27af5065c0..ddcdb90fb3f 100644 --- a/controllers/experimental/tree_loader.go +++ b/controllers/experimental/tree_loader.go @@ -31,7 +31,7 @@ import ( appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" experimental "github.com/apecloud/kubeblocks/apis/experimental/v1alpha1" - workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" + workloads "github.com/apecloud/kubeblocks/apis/workloads/v1" "github.com/apecloud/kubeblocks/pkg/constant" "github.com/apecloud/kubeblocks/pkg/controller/kubebuilderx" ) diff --git a/controllers/experimental/tree_loader_test.go b/controllers/experimental/tree_loader_test.go index 845ebb64a60..230fa4a6f69 100644 --- a/controllers/experimental/tree_loader_test.go +++ b/controllers/experimental/tree_loader_test.go @@ -34,7 +34,7 @@ import ( appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" experimental "github.com/apecloud/kubeblocks/apis/experimental/v1alpha1" - workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" + workloads "github.com/apecloud/kubeblocks/apis/workloads/v1" "github.com/apecloud/kubeblocks/pkg/constant" "github.com/apecloud/kubeblocks/pkg/controller/builder" testutil "github.com/apecloud/kubeblocks/pkg/testutil/k8s" diff --git a/controllers/k8score/event_controller_test.go b/controllers/k8score/event_controller_test.go index 3c34232bcb1..70ceb23bf17 100644 --- a/controllers/k8score/event_controller_test.go +++ b/controllers/k8score/event_controller_test.go @@ -35,7 +35,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" - workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" + workloads "github.com/apecloud/kubeblocks/apis/workloads/v1" "github.com/apecloud/kubeblocks/pkg/constant" "github.com/apecloud/kubeblocks/pkg/controller/builder" "github.com/apecloud/kubeblocks/pkg/controller/instanceset" diff --git a/controllers/k8score/suite_test.go b/controllers/k8score/suite_test.go index 5482531761a..d6bc14aa37c 100644 --- a/controllers/k8score/suite_test.go +++ b/controllers/k8score/suite_test.go @@ -42,7 +42,7 @@ import ( appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" appsv1beta1 "github.com/apecloud/kubeblocks/apis/apps/v1beta1" - workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" + workloads "github.com/apecloud/kubeblocks/apis/workloads/v1" "github.com/apecloud/kubeblocks/pkg/testutil" viper "github.com/apecloud/kubeblocks/pkg/viperx" ) diff --git a/controllers/workloads/instanceset_controller.go b/controllers/workloads/instanceset_controller.go index e01e2e5176f..c723e61245a 100644 --- a/controllers/workloads/instanceset_controller.go +++ b/controllers/workloads/instanceset_controller.go @@ -31,7 +31,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/controller" "sigs.k8s.io/controller-runtime/pkg/log" - workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" + workloads "github.com/apecloud/kubeblocks/apis/workloads/v1" "github.com/apecloud/kubeblocks/pkg/constant" "github.com/apecloud/kubeblocks/pkg/controller/handler" "github.com/apecloud/kubeblocks/pkg/controller/instanceset" diff --git a/controllers/workloads/instanceset_controller_test.go b/controllers/workloads/instanceset_controller_test.go index 2324621ff53..ab240ec0f5b 100644 --- a/controllers/workloads/instanceset_controller_test.go +++ b/controllers/workloads/instanceset_controller_test.go @@ -26,7 +26,7 @@ import ( corev1 "k8s.io/api/core/v1" "sigs.k8s.io/controller-runtime/pkg/client" - workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" + workloads "github.com/apecloud/kubeblocks/apis/workloads/v1" "github.com/apecloud/kubeblocks/pkg/constant" "github.com/apecloud/kubeblocks/pkg/controller/builder" testapps "github.com/apecloud/kubeblocks/pkg/testutil/apps" diff --git a/controllers/workloads/suite_test.go b/controllers/workloads/suite_test.go index f4659e96ebb..540b798b7a9 100644 --- a/controllers/workloads/suite_test.go +++ b/controllers/workloads/suite_test.go @@ -38,7 +38,7 @@ import ( // +kubebuilder:scaffold:imports - workloadsv1alpha1 "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" + workloadsv1 "github.com/apecloud/kubeblocks/apis/workloads/v1" "github.com/apecloud/kubeblocks/pkg/testutil" ) @@ -75,7 +75,7 @@ var _ = BeforeSuite(func() { Expect(err).NotTo(HaveOccurred()) Expect(cfg).NotTo(BeNil()) - err = workloadsv1alpha1.AddToScheme(scheme.Scheme) + err = workloadsv1.AddToScheme(scheme.Scheme) Expect(err).NotTo(HaveOccurred()) // +kubebuilder:scaffold:scheme diff --git a/deploy/helm/crds/workloads.kubeblocks.io_instancesets.yaml b/deploy/helm/crds/workloads.kubeblocks.io_instancesets.yaml index 85bfcf29ab5..ae79ae18c17 100644 --- a/deploy/helm/crds/workloads.kubeblocks.io_instancesets.yaml +++ b/deploy/helm/crds/workloads.kubeblocks.io_instancesets.yaml @@ -19,6 +19,13085 @@ spec: singular: instanceset scope: Namespaced versions: + - additionalPrinterColumns: + - description: leader instance name. + jsonPath: .status.membersStatus[?(@.role.isLeader==true)].podName + name: LEADER + type: string + - description: ready replicas. + jsonPath: .status.readyReplicas + name: READY + type: string + - description: total replicas. + jsonPath: .status.replicas + name: REPLICAS + type: string + - jsonPath: .metadata.creationTimestamp + name: AGE + type: date + name: v1 + schema: + openAPIV3Schema: + description: InstanceSet is the Schema for the instancesets 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: Defines the desired state of the state machine. It includes + the configuration details for the state machine. + properties: + credential: + description: Credential used to connect to DB engine + properties: + password: + description: |- + Represents the user's password for the credential. + The corresponding environment variable will be KB_ITS_PASSWORD. + properties: + value: + description: |- + Specifies the value of the environment variable. This field is optional and defaults to an empty string. + The value can include variable references in the format $(VAR_NAME) which will be expanded using previously defined environment variables in the container and any service environment variables. + + + If a variable cannot be resolved, the reference in the input string will remain unchanged. + Double $$ can be used to escape the $(VAR_NAME) syntax, resulting in a single $ and producing the string literal "$(VAR_NAME)". + Escaped references will not be expanded, regardless of whether the variable exists or not. + type: string + valueFrom: + description: Defines the source for the environment variable's + value. This field is optional and cannot be used if the + 'Value' field is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the FieldPath is + written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the specified + API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the exposed + resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in the pod's namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + username: + description: |- + Defines the user's name for the credential. + The corresponding environment variable will be KB_ITS_USERNAME. + properties: + value: + description: |- + Specifies the value of the environment variable. This field is optional and defaults to an empty string. + The value can include variable references in the format $(VAR_NAME) which will be expanded using previously defined environment variables in the container and any service environment variables. + + + If a variable cannot be resolved, the reference in the input string will remain unchanged. + Double $$ can be used to escape the $(VAR_NAME) syntax, resulting in a single $ and producing the string literal "$(VAR_NAME)". + Escaped references will not be expanded, regardless of whether the variable exists or not. + type: string + valueFrom: + description: Defines the source for the environment variable's + value. This field is optional and cannot be used if the + 'Value' field is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the FieldPath is + written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the specified + API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the exposed + resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in the pod's namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + required: + - password + - username + type: object + defaultTemplateOrdinals: + description: |- + Specifies the desired Ordinals of the default template. + The Ordinals used to specify the ordinal of the instance (pod) names to be generated under the default template. + + + For example, if Ordinals is {ranges: [{start: 0, end: 1}], discrete: [7]}, + then the instance names generated under the default template would be + $(cluster.name)-$(component.name)-0、$(cluster.name)-$(component.name)-1 and $(cluster.name)-$(component.name)-7 + properties: + discrete: + items: + format: int32 + type: integer + type: array + ranges: + items: + description: |- + Range represents a range with a start and an end value. + It is used to define a continuous segment. + properties: + end: + format: int32 + type: integer + start: + format: int32 + type: integer + required: + - end + - start + type: object + type: array + type: object + instances: + description: |- + Overrides values in default Template. + + + Instance is the fundamental unit managed by KubeBlocks. + It represents a Pod with additional objects such as PVCs, Services, ConfigMaps, etc. + An InstanceSet manages instances with a total count of Replicas, + and by default, all these instances are generated from the same template. + The InstanceTemplate provides a way to override values in the default template, + allowing the InstanceSet to manage instances from different templates. + + + The naming convention for instances (pods) based on the InstanceSet Name, InstanceTemplate Name, and ordinal. + The constructed instance name follows the pattern: $(instance_set.name)-$(template.name)-$(ordinal). + By default, the ordinal starts from 0 for each InstanceTemplate. + It is important to ensure that the Name of each InstanceTemplate is unique. + + + The sum of replicas across all InstanceTemplates should not exceed the total number of Replicas specified for the InstanceSet. + Any remaining replicas will be generated using the default template and will follow the default naming rules. + items: + description: |- + InstanceTemplate allows customization of individual replica configurations within a Component, + without altering the base component template defined in ClusterComponentSpec. + It enables the application of distinct settings to specific instances (replicas), + providing flexibility while maintaining a common configuration baseline. + properties: + annotations: + additionalProperties: + type: string + description: |- + Specifies a map of key-value pairs to be merged into the Pod's existing annotations. + Existing keys will have their values overwritten, while new keys will be added to the annotations. + type: object + env: + description: |- + Defines Env to override. + Add new or override existing envs. + items: + description: EnvVar represents an environment variable present + in a Container. + properties: + name: + description: Name of the environment variable. Must be + a C_IDENTIFIER. + type: string + value: + description: |- + Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in the container and + any service environment variables. If a variable cannot be resolved, + the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless of whether the variable + exists or not. + Defaults to "". + type: string + valueFrom: + description: Source for the environment variable's value. + Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap or + its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the + specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the + exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in the pod's + namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its + key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + image: + description: Specifies an override for the first container's + image in the pod. + type: string + labels: + additionalProperties: + type: string + description: |- + Specifies a map of key-value pairs that will be merged into the Pod's existing labels. + Values for existing keys will be overwritten, and new keys will be added. + type: object + name: + description: |- + Name specifies the unique name of the instance Pod created using this InstanceTemplate. + This name is constructed by concatenating the component's name, the template's name, and the instance's ordinal + using the pattern: $(cluster.name)-$(component.name)-$(template.name)-$(ordinal). Ordinals start from 0. + The specified name overrides any default naming conventions or patterns. + maxLength: 54 + pattern: ^[a-z0-9]([a-z0-9\.\-]*[a-z0-9])?$ + type: string + ordinals: + description: |- + Specifies the desired Ordinals of this InstanceTemplate. + The Ordinals used to specify the ordinal of the instance (pod) names to be generated under this InstanceTemplate. + + + For example, if Ordinals is {ranges: [{start: 0, end: 1}], discrete: [7]}, + then the instance names generated under this InstanceTemplate would be + $(cluster.name)-$(component.name)-$(template.name)-0、$(cluster.name)-$(component.name)-$(template.name)-1 and + $(cluster.name)-$(component.name)-$(template.name)-7 + properties: + discrete: + items: + format: int32 + type: integer + type: array + ranges: + items: + description: |- + Range represents a range with a start and an end value. + It is used to define a continuous segment. + properties: + end: + format: int32 + type: integer + start: + format: int32 + type: integer + required: + - end + - start + type: object + type: array + type: object + replicas: + default: 1 + description: |- + Specifies the number of instances (Pods) to create from this InstanceTemplate. + This field allows setting how many replicated instances of the component, + with the specific overrides in the InstanceTemplate, are created. + The default value is 1. A value of 0 disables instance creation. + format: int32 + minimum: 0 + type: integer + resources: + description: |- + Specifies an override for the resource requirements of the first container in the Pod. + This field allows for customizing resource allocation (CPU, memory, etc.) for the container. + properties: + claims: + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + + + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + + + This field is immutable. It can only be set for containers. + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + schedulingPolicy: + description: Specifies the scheduling policy for the Component. + properties: + affinity: + description: Specifies a group of affinity scheduling rules + of the Cluster, including NodeAffinity, PodAffinity, and + PodAntiAffinity. + properties: + nodeAffinity: + description: Describes node affinity scheduling rules + for the pod. + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node matches the corresponding matchExpressions; the + node(s) with the highest sum are the most preferred. + items: + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). + properties: + preference: + description: A node selector term, associated + with the corresponding weight. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that + the selector applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that + the selector applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + weight: + description: Weight associated with matching + the corresponding nodeSelectorTerm, in the + range 1-100. + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. + properties: + nodeSelectorTerms: + description: Required. A list of node selector + terms. The terms are ORed. + items: + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that + the selector applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that + the selector applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + type: array + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + description: Describes pod affinity scheduling rules + (e.g. co-locate this pod in the same node, zone, etc. + as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched + WeightedPodAffinityTerm fields are added per-node + to find the most preferred node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, + associated with the corresponding weight. + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a + list of label selector requirements. + The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. + Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a + list of label selector requirements. + The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: |- + weight associated with matching the corresponding podAffinityTerm, + in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. + items: + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. + Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + description: Describes pod anti-affinity scheduling + rules (e.g. avoid putting this pod in the same node, + zone, etc. as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the anti-affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched + WeightedPodAffinityTerm fields are added per-node + to find the most preferred node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, + associated with the corresponding weight. + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a + list of label selector requirements. + The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. + Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a + list of label selector requirements. + The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: |- + weight associated with matching the corresponding podAffinityTerm, + in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the anti-affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the anti-affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. + items: + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. + Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + nodeName: + description: |- + NodeName is a request to schedule this Pod onto a specific node. If it is non-empty, + the scheduler simply schedules this Pod onto that node, assuming that it fits resource + requirements. + type: string + nodeSelector: + additionalProperties: + type: string + description: |- + NodeSelector is a selector which must be true for the Pod to fit on a node. + Selector which must match a node's labels for the Pod to be scheduled on that node. + More info: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ + type: object + x-kubernetes-map-type: atomic + schedulerName: + description: |- + If specified, the Pod will be dispatched by specified scheduler. + If not specified, the Pod will be dispatched by default scheduler. + type: string + tolerations: + description: |- + Allows Pods to be scheduled onto nodes with matching taints. + Each toleration in the array allows the Pod to tolerate node taints based on + specified `key`, `value`, `effect`, and `operator`. + + + - The `key`, `value`, and `effect` identify the taint that the toleration matches. + - The `operator` determines how the toleration matches the taint. + + + Pods with matching tolerations are allowed to be scheduled on tainted nodes, typically reserved for specific purposes. + items: + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . + properties: + effect: + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. + type: string + operator: + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. + type: string + tolerationSeconds: + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. + format: int64 + type: integer + value: + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. + type: string + type: object + type: array + topologySpreadConstraints: + description: |- + TopologySpreadConstraints describes how a group of Pods ought to spread across topology + domains. Scheduler will schedule Pods in a way which abides by the constraints. + All topologySpreadConstraints are ANDed. + items: + description: TopologySpreadConstraint specifies how to + spread matching pods among the given topology. + properties: + labelSelector: + description: |- + LabelSelector is used to find matching pods. + Pods that match this label selector are counted to determine the number of pods + in their corresponding topology domain. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select the pods over which + spreading will be calculated. The keys are used to lookup values from the + incoming pod labels, those key-value labels are ANDed with labelSelector + to select the group of existing pods over which spreading will be calculated + for the incoming pod. The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + MatchLabelKeys cannot be set when LabelSelector isn't set. + Keys that don't exist in the incoming pod labels will + be ignored. A null or empty list means only match against labelSelector. + + + This is a beta field and requires the MatchLabelKeysInPodTopologySpread feature gate to be enabled (enabled by default). + items: + type: string + type: array + x-kubernetes-list-type: atomic + maxSkew: + description: |- + MaxSkew describes the degree to which pods may be unevenly distributed. + When `whenUnsatisfiable=DoNotSchedule`, it is the maximum permitted difference + between the number of matching pods in the target topology and the global minimum. + The global minimum is the minimum number of matching pods in an eligible domain + or zero if the number of eligible domains is less than MinDomains. + For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same + labelSelector spread as 2/2/1: + In this case, the global minimum is 1. + | zone1 | zone2 | zone3 | + | P P | P P | P | + - if MaxSkew is 1, incoming pod can only be scheduled to zone3 to become 2/2/2; + scheduling it onto zone1(zone2) would make the ActualSkew(3-1) on zone1(zone2) + violate MaxSkew(1). + - if MaxSkew is 2, incoming pod can be scheduled onto any zone. + When `whenUnsatisfiable=ScheduleAnyway`, it is used to give higher precedence + to topologies that satisfy it. + It's a required field. Default value is 1 and 0 is not allowed. + format: int32 + type: integer + minDomains: + description: |- + MinDomains indicates a minimum number of eligible domains. + When the number of eligible domains with matching topology keys is less than minDomains, + Pod Topology Spread treats "global minimum" as 0, and then the calculation of Skew is performed. + And when the number of eligible domains with matching topology keys equals or greater than minDomains, + this value has no effect on scheduling. + As a result, when the number of eligible domains is less than minDomains, + scheduler won't schedule more than maxSkew Pods to those domains. + If value is nil, the constraint behaves as if MinDomains is equal to 1. + Valid values are integers greater than 0. + When value is not nil, WhenUnsatisfiable must be DoNotSchedule. + + + For example, in a 3-zone cluster, MaxSkew is set to 2, MinDomains is set to 5 and pods with the same + labelSelector spread as 2/2/2: + | zone1 | zone2 | zone3 | + | P P | P P | P P | + The number of domains is less than 5(MinDomains), so "global minimum" is treated as 0. + In this situation, new pod with the same labelSelector cannot be scheduled, + because computed skew will be 3(3 - 0) if new Pod is scheduled to any of the three zones, + it will violate MaxSkew. + + + This is a beta field and requires the MinDomainsInPodTopologySpread feature gate to be enabled (enabled by default). + format: int32 + type: integer + nodeAffinityPolicy: + description: |- + NodeAffinityPolicy indicates how we will treat Pod's nodeAffinity/nodeSelector + when calculating pod topology spread skew. Options are: + - Honor: only nodes matching nodeAffinity/nodeSelector are included in the calculations. + - Ignore: nodeAffinity/nodeSelector are ignored. All nodes are included in the calculations. + + + If this value is nil, the behavior is equivalent to the Honor policy. + This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag. + type: string + nodeTaintsPolicy: + description: |- + NodeTaintsPolicy indicates how we will treat node taints when calculating + pod topology spread skew. Options are: + - Honor: nodes without taints, along with tainted nodes for which the incoming pod + has a toleration, are included. + - Ignore: node taints are ignored. All nodes are included. + + + If this value is nil, the behavior is equivalent to the Ignore policy. + This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag. + type: string + topologyKey: + description: |- + TopologyKey is the key of node labels. Nodes that have a label with this key + and identical values are considered to be in the same topology. + We consider each as a "bucket", and try to put balanced number + of pods into each bucket. + We define a domain as a particular instance of a topology. + Also, we define an eligible domain as a domain whose nodes meet the requirements of + nodeAffinityPolicy and nodeTaintsPolicy. + e.g. If TopologyKey is "kubernetes.io/hostname", each Node is a domain of that topology. + And, if TopologyKey is "topology.kubernetes.io/zone", each zone is a domain of that topology. + It's a required field. + type: string + whenUnsatisfiable: + description: |- + WhenUnsatisfiable indicates how to deal with a pod if it doesn't satisfy + the spread constraint. + - DoNotSchedule (default) tells the scheduler not to schedule it. + - ScheduleAnyway tells the scheduler to schedule the pod in any location, + but giving higher precedence to topologies that would help reduce the + skew. + A constraint is considered "Unsatisfiable" for an incoming pod + if and only if every possible node assignment for that pod would violate + "MaxSkew" on some topology. + For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same + labelSelector spread as 3/1/1: + | zone1 | zone2 | zone3 | + | P P P | P | P | + If WhenUnsatisfiable is set to DoNotSchedule, incoming pod can only be scheduled + to zone2(zone3) to become 3/2/1(3/1/2) as ActualSkew(2-1) on zone2(zone3) satisfies + MaxSkew(1). In other words, the cluster can still be imbalanced, but scheduler + won't make it *more* imbalanced. + It's a required field. + type: string + required: + - maxSkew + - topologyKey + - whenUnsatisfiable + type: object + type: array + type: object + volumeClaimTemplates: + description: |- + Defines VolumeClaimTemplates to override. + Add new or override existing volume claim templates. + items: + description: PersistentVolumeClaim is a user's request for + and claim to a persistent volume + 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: + description: |- + Standard object's metadata. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + description: |- + spec defines the desired characteristics of a volume requested by a pod author. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims + properties: + accessModes: + description: |- + accessModes contains the desired access modes the volume should have. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1 + items: + type: string + type: array + dataSource: + description: |- + dataSource field can be used to specify either: + * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) + * An existing PVC (PersistentVolumeClaim) + If the provisioner or an external controller can support the specified data source, + it will create a new volume based on the contents of the specified data source. + When the AnyVolumeDataSource feature gate is enabled, dataSource contents will be copied to dataSourceRef, + and dataSourceRef contents will be copied to dataSource when dataSourceRef.namespace is not specified. + If the namespace is specified, then dataSourceRef will not be copied to dataSource. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being + referenced + type: string + name: + description: Name is the name of resource being + referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + description: |- + dataSourceRef specifies the object from which to populate the volume with data, if a non-empty + volume is desired. This may be any object from a non-empty API group (non + core object) or a PersistentVolumeClaim object. + When this field is specified, volume binding will only succeed if the type of + the specified object matches some installed volume populator or dynamic + provisioner. + This field will replace the functionality of the dataSource field and as such + if both fields are non-empty, they must have the same value. For backwards + compatibility, when namespace isn't specified in dataSourceRef, + both fields (dataSource and dataSourceRef) will be set to the same + value automatically if one of them is empty and the other is non-empty. + When namespace is specified in dataSourceRef, + dataSource isn't set to the same value and must be empty. + There are three important differences between dataSource and dataSourceRef: + * While dataSource only allows two specific types of objects, dataSourceRef + allows any non-core object, as well as PersistentVolumeClaim objects. + * While dataSource ignores disallowed values (dropping them), dataSourceRef + preserves all values, and generates an error if a disallowed value is + specified. + * While dataSource only allows local objects, dataSourceRef allows objects + in any namespaces. + (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled. + (Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being + referenced + type: string + name: + description: Name is the name of resource being + referenced + type: string + namespace: + description: |- + Namespace is the namespace of resource being referenced + Note that when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details. + (Alpha) This field requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + type: string + required: + - kind + - name + type: object + resources: + description: |- + resources represents the minimum resources the volume should have. + If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements + that are lower than previous value but must still be higher than capacity recorded in the + status field of the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + selector: + description: selector is a label query over volumes + to consider for binding. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + description: |- + storageClassName is the name of the StorageClass required by the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1 + type: string + volumeAttributesClassName: + description: |- + volumeAttributesClassName may be used to set the VolumeAttributesClass used by this claim. + If specified, the CSI driver will create or update the volume with the attributes defined + in the corresponding VolumeAttributesClass. This has a different purpose than storageClassName, + it can be changed after the claim is created. An empty string value means that no VolumeAttributesClass + will be applied to the claim but it's not allowed to reset this field to empty string once it is set. + If unspecified and the PersistentVolumeClaim is unbound, the default VolumeAttributesClass + will be set by the persistentvolume controller if it exists. + If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be + set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource + exists. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#volumeattributesclass + (Alpha) Using this field requires the VolumeAttributesClass feature gate to be enabled. + type: string + volumeMode: + description: |- + volumeMode defines what type of volume is required by the claim. + Value of Filesystem is implied when not included in claim spec. + type: string + volumeName: + description: volumeName is the binding reference to + the PersistentVolume backing this claim. + type: string + type: object + status: + description: |- + status represents the current information/status of a persistent volume claim. + Read-only. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims + properties: + accessModes: + description: |- + accessModes contains the actual access modes the volume backing the PVC has. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1 + items: + type: string + type: array + allocatedResourceStatuses: + additionalProperties: + description: |- + When a controller receives persistentvolume claim update with ClaimResourceStatus for a resource + that it does not recognizes, then it should ignore that update and let other controllers + handle it. + type: string + description: "allocatedResourceStatuses stores status + of resource being resized for the given PVC.\nKey + names follow standard Kubernetes label syntax. Valid + values are either:\n\t* Un-prefixed keys:\n\t\t- + storage - the capacity of the volume.\n\t* Custom + resources must use implementation-defined prefixed + names such as \"example.com/my-custom-resource\"\nApart + from above values - keys that are unprefixed or + have kubernetes.io prefix are considered\nreserved + and hence may not be used.\n\n\nClaimResourceStatus + can be in any of following states:\n\t- ControllerResizeInProgress:\n\t\tState + set when resize controller starts resizing the volume + in control-plane.\n\t- ControllerResizeFailed:\n\t\tState + set when resize has failed in resize controller + with a terminal error.\n\t- NodeResizePending:\n\t\tState + set when resize controller has finished resizing + the volume but further resizing of\n\t\tvolume is + needed on the node.\n\t- NodeResizeInProgress:\n\t\tState + set when kubelet starts resizing the volume.\n\t- + NodeResizeFailed:\n\t\tState set when resizing has + failed in kubelet with a terminal error. Transient + errors don't set\n\t\tNodeResizeFailed.\nFor example: + if expanding a PVC for more capacity - this field + can be one of the following states:\n\t- pvc.status.allocatedResourceStatus['storage'] + = \"ControllerResizeInProgress\"\n - pvc.status.allocatedResourceStatus['storage'] + = \"ControllerResizeFailed\"\n - pvc.status.allocatedResourceStatus['storage'] + = \"NodeResizePending\"\n - pvc.status.allocatedResourceStatus['storage'] + = \"NodeResizeInProgress\"\n - pvc.status.allocatedResourceStatus['storage'] + = \"NodeResizeFailed\"\nWhen this field is not set, + it means that no resize operation is in progress + for the given PVC.\n\n\nA controller that receives + PVC update with previously unknown resourceName + or ClaimResourceStatus\nshould ignore the update + for the purpose it was designed. For example - a + controller that\nonly is responsible for resizing + capacity of the volume, should ignore PVC updates + that change other valid\nresources associated with + PVC.\n\n\nThis is an alpha field and requires enabling + RecoverVolumeExpansionFailure feature." + type: object + x-kubernetes-map-type: granular + allocatedResources: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: "allocatedResources tracks the resources + allocated to a PVC including its capacity.\nKey + names follow standard Kubernetes label syntax. Valid + values are either:\n\t* Un-prefixed keys:\n\t\t- + storage - the capacity of the volume.\n\t* Custom + resources must use implementation-defined prefixed + names such as \"example.com/my-custom-resource\"\nApart + from above values - keys that are unprefixed or + have kubernetes.io prefix are considered\nreserved + and hence may not be used.\n\n\nCapacity reported + here may be larger than the actual capacity when + a volume expansion operation\nis requested.\nFor + storage quota, the larger value from allocatedResources + and PVC.spec.resources is used.\nIf allocatedResources + is not set, PVC.spec.resources alone is used for + quota calculation.\nIf a volume expansion capacity + request is lowered, allocatedResources is only\nlowered + if there are no expansion operations in progress + and if the actual volume capacity\nis equal or lower + than the requested capacity.\n\n\nA controller that + receives PVC update with previously unknown resourceName\nshould + ignore the update for the purpose it was designed. + For example - a controller that\nonly is responsible + for resizing capacity of the volume, should ignore + PVC updates that change other valid\nresources associated + with PVC.\n\n\nThis is an alpha field and requires + enabling RecoverVolumeExpansionFailure feature." + type: object + capacity: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: capacity represents the actual resources + of the underlying volume. + type: object + conditions: + description: |- + conditions is the current Condition of persistent volume claim. If underlying persistent volume is being + resized then the Condition will be set to 'ResizeStarted'. + items: + description: PersistentVolumeClaimCondition contains + details about state of pvc + properties: + lastProbeTime: + description: lastProbeTime is the time we probed + the condition. + format: date-time + type: string + lastTransitionTime: + description: lastTransitionTime is the time + the condition transitioned from one status + to another. + format: date-time + type: string + message: + description: message is the human-readable message + indicating details about last transition. + type: string + reason: + description: |- + reason is a unique, this should be a short, machine understandable string that gives the reason + for condition's last transition. If it reports "ResizeStarted" that means the underlying + persistent volume is being resized. + type: string + status: + type: string + type: + description: PersistentVolumeClaimConditionType + is a valid value of PersistentVolumeClaimCondition.Type + type: string + required: + - status + - type + type: object + type: array + currentVolumeAttributesClassName: + description: |- + currentVolumeAttributesClassName is the current name of the VolumeAttributesClass the PVC is using. + When unset, there is no VolumeAttributeClass applied to this PersistentVolumeClaim + This is an alpha field and requires enabling VolumeAttributesClass feature. + type: string + modifyVolumeStatus: + description: |- + ModifyVolumeStatus represents the status object of ControllerModifyVolume operation. + When this is unset, there is no ModifyVolume operation being attempted. + This is an alpha field and requires enabling VolumeAttributesClass feature. + properties: + status: + description: "status is the status of the ControllerModifyVolume + operation. It can be in any of following states:\n + - Pending\n Pending indicates that the PersistentVolumeClaim + cannot be modified due to unmet requirements, + such as\n the specified VolumeAttributesClass + not existing.\n - InProgress\n InProgress + indicates that the volume is being modified.\n + - Infeasible\n Infeasible indicates that the + request has been rejected as invalid by the + CSI driver. To\n\t resolve the error, a valid + VolumeAttributesClass needs to be specified.\nNote: + New statuses can be added in the future. Consumers + should check for unknown statuses and fail appropriately." + type: string + targetVolumeAttributesClassName: + description: targetVolumeAttributesClassName is + the name of the VolumeAttributesClass the PVC + currently being reconciled + type: string + required: + - status + type: object + phase: + description: phase represents the current phase of + PersistentVolumeClaim. + type: string + type: object + type: object + type: array + volumeMounts: + description: |- + Defines VolumeMounts to override. + Add new or override existing volume mounts of the first container in the pod. + items: + description: VolumeMount describes a mounting of a Volume + within a container. + properties: + mountPath: + description: |- + Path within the container at which the volume should be mounted. Must + not contain ':'. + type: string + mountPropagation: + description: |- + mountPropagation determines how mounts are propagated from the host + to container and the other way around. + When not set, MountPropagationNone is used. + This field is beta in 1.10. + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: |- + Mounted read-only if true, read-write otherwise (false or unspecified). + Defaults to false. + type: boolean + subPath: + description: |- + Path within the volume from which the container's volume should be mounted. + Defaults to "" (volume's root). + type: string + subPathExpr: + description: |- + Expanded path within the volume from which the container's volume should be mounted. + Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment. + Defaults to "" (volume's root). + SubPathExpr and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + volumes: + description: |- + Defines Volumes to override. + Add new or override existing volumes. + items: + description: Volume represents a named volume in a pod that + may be accessed by any container in the pod. + properties: + awsElasticBlockStore: + description: |- + awsElasticBlockStore represents an AWS Disk resource that is attached to a + kubelet's host machine and then exposed to the pod. + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + properties: + fsType: + description: |- + fsType is the filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + partition: + description: |- + partition is the partition in the volume that you want to mount. + If omitted, the default is to mount by volume name. + Examples: For volume /dev/sda1, you specify the partition as "1". + Similarly, the volume partition for /dev/sda is "0" (or you can leave the property empty). + format: int32 + type: integer + readOnly: + description: |- + readOnly value true will force the readOnly setting in VolumeMounts. + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + type: boolean + volumeID: + description: |- + volumeID is unique ID of the persistent disk resource in AWS (Amazon EBS volume). + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + type: string + required: + - volumeID + type: object + azureDisk: + description: azureDisk represents an Azure Data Disk mount + on the host and bind mount to the pod. + properties: + cachingMode: + description: 'cachingMode is the Host Caching mode: + None, Read Only, Read Write.' + type: string + diskName: + description: diskName is the Name of the data disk + in the blob storage + type: string + diskURI: + description: diskURI is the URI of data disk in the + blob storage + type: string + fsType: + description: |- + fsType is Filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + kind: + description: 'kind expected values are Shared: multiple + blob disks per storage account Dedicated: single + blob disk per storage account Managed: azure managed + data disk (only in managed availability set). defaults + to shared' + type: string + readOnly: + description: |- + readOnly Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + description: azureFile represents an Azure File Service + mount on the host and bind mount to the pod. + properties: + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretName: + description: secretName is the name of secret that + contains Azure Storage Account Name and Key + type: string + shareName: + description: shareName is the azure share Name + type: string + required: + - secretName + - shareName + type: object + cephfs: + description: cephFS represents a Ceph FS mount on the + host that shares a pod's lifetime + properties: + monitors: + description: |- + monitors is Required: Monitors is a collection of Ceph monitors + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + items: + type: string + type: array + path: + description: 'path is Optional: Used as the mounted + root, rather than the full Ceph tree, default is + /' + type: string + readOnly: + description: |- + readOnly is Optional: Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + type: boolean + secretFile: + description: |- + secretFile is Optional: SecretFile is the path to key ring for User, default is /etc/ceph/user.secret + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + type: string + secretRef: + description: |- + secretRef is Optional: SecretRef is reference to the authentication secret for User, default is empty. + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + 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 + user: + description: |- + user is optional: User is the rados user name, default is admin + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + type: string + required: + - monitors + type: object + cinder: + description: |- + cinder represents a cinder volume attached and mounted on kubelets host machine. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + type: string + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + type: boolean + secretRef: + description: |- + secretRef is optional: points to a secret object containing parameters used to connect + to OpenStack. + 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 + volumeID: + description: |- + volumeID used to identify the volume in cinder. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + type: string + required: + - volumeID + type: object + configMap: + description: configMap represents a configMap that should + populate this volume + properties: + defaultMode: + description: |- + defaultMode is optional: mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + items: + description: |- + items if unspecified, each key-value pair in the Data field of the referenced + ConfigMap will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the ConfigMap, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within + a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + 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 + optional: + description: optional specify whether the ConfigMap + or its keys must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + csi: + description: csi (Container Storage Interface) represents + ephemeral storage that is handled by certain external + CSI drivers (Beta feature). + properties: + driver: + description: |- + driver is the name of the CSI driver that handles this volume. + Consult with your admin for the correct name as registered in the cluster. + type: string + fsType: + description: |- + fsType to mount. Ex. "ext4", "xfs", "ntfs". + If not provided, the empty value is passed to the associated CSI driver + which will determine the default filesystem to apply. + type: string + nodePublishSecretRef: + description: |- + nodePublishSecretRef is a reference to the secret object containing + sensitive information to pass to the CSI driver to complete the CSI + NodePublishVolume and NodeUnpublishVolume calls. + This field is optional, and may be empty if no secret is required. If the + secret object contains more than one secret, all secret references are passed. + 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 + readOnly: + description: |- + readOnly specifies a read-only configuration for the volume. + Defaults to false (read/write). + type: boolean + volumeAttributes: + additionalProperties: + type: string + description: |- + volumeAttributes stores driver-specific properties that are passed to the CSI + driver. Consult your driver's documentation for supported values. + type: object + required: + - driver + type: object + downwardAPI: + description: downwardAPI represents downward API about + the pod that should populate this volume + properties: + defaultMode: + description: |- + Optional: mode bits to use on created files by default. Must be a + Optional: mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + items: + description: Items is a list of downward API volume + file + items: + description: DownwardAPIVolumeFile represents information + to create the file containing the pod field + properties: + fieldRef: + description: 'Required: Selects a field of the + pod: only annotations, labels, name and namespace + are supported.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select + in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + description: |- + Optional: mode bits used to set permissions on this file, must be an octal value + between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: 'Required: Path is the relative + path name of the file to be created. Must + not be absolute or contain the ''..'' path. + Must be utf-8 encoded. The first item of the + relative path must not start with ''..''' + type: string + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported. + properties: + containerName: + description: 'Container name: required for + volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format + of the exposed resources, defaults to + "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + type: object + emptyDir: + description: |- + emptyDir represents a temporary directory that shares a pod's lifetime. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir + properties: + medium: + description: |- + medium represents what type of storage medium should back this directory. + The default is "" which means to use the node's default medium. + Must be an empty string (default) or Memory. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + description: |- + sizeLimit is the total amount of local storage required for this EmptyDir volume. + The size limit is also applicable for memory medium. + The maximum usage on memory medium EmptyDir would be the minimum value between + the SizeLimit specified here and the sum of memory limits of all containers in a pod. + The default is nil which means that the limit is undefined. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + description: |- + ephemeral represents a volume that is handled by a cluster storage driver. + The volume's lifecycle is tied to the pod that defines it - it will be created before the pod starts, + and deleted when the pod is removed. + + + Use this if: + a) the volume is only needed while the pod runs, + b) features of normal volumes like restoring from snapshot or capacity + tracking are needed, + c) the storage driver is specified through a storage class, and + d) the storage driver supports dynamic volume provisioning through + a PersistentVolumeClaim (see EphemeralVolumeSource for more + information on the connection between this volume type + and PersistentVolumeClaim). + + + Use PersistentVolumeClaim or one of the vendor-specific + APIs for volumes that persist for longer than the lifecycle + of an individual pod. + + + Use CSI for light-weight local ephemeral volumes if the CSI driver is meant to + be used that way - see the documentation of the driver for + more information. + + + A pod can use both types of ephemeral volumes and + persistent volumes at the same time. + properties: + volumeClaimTemplate: + description: |- + Will be used to create a stand-alone PVC to provision the volume. + The pod in which this EphemeralVolumeSource is embedded will be the + owner of the PVC, i.e. the PVC will be deleted together with the + pod. The name of the PVC will be `-` where + `` is the name from the `PodSpec.Volumes` array + entry. Pod validation will reject the pod if the concatenated name + is not valid for a PVC (for example, too long). + + + An existing PVC with that name that is not owned by the pod + will *not* be used for the pod to avoid using an unrelated + volume by mistake. Starting the pod is then blocked until + the unrelated PVC is removed. If such a pre-created PVC is + meant to be used by the pod, the PVC has to updated with an + owner reference to the pod once the pod exists. Normally + this should not be necessary, but it may be useful when + manually reconstructing a broken cluster. + + + This field is read-only and no changes will be made by Kubernetes + to the PVC after it has been created. + + + Required, must not be nil. + properties: + metadata: + description: |- + May contain labels and annotations that will be copied into the PVC + when creating it. No other fields are allowed and will be rejected during + validation. + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + description: |- + The specification for the PersistentVolumeClaim. The entire content is + copied unchanged into the PVC that gets created from this + template. The same fields as in a PersistentVolumeClaim + are also valid here. + properties: + accessModes: + description: |- + accessModes contains the desired access modes the volume should have. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1 + items: + type: string + type: array + dataSource: + description: |- + dataSource field can be used to specify either: + * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) + * An existing PVC (PersistentVolumeClaim) + If the provisioner or an external controller can support the specified data source, + it will create a new volume based on the contents of the specified data source. + When the AnyVolumeDataSource feature gate is enabled, dataSource contents will be copied to dataSourceRef, + and dataSourceRef contents will be copied to dataSource when dataSourceRef.namespace is not specified. + If the namespace is specified, then dataSourceRef will not be copied to dataSource. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource + being referenced + type: string + name: + description: Name is the name of resource + being referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + description: |- + dataSourceRef specifies the object from which to populate the volume with data, if a non-empty + volume is desired. This may be any object from a non-empty API group (non + core object) or a PersistentVolumeClaim object. + When this field is specified, volume binding will only succeed if the type of + the specified object matches some installed volume populator or dynamic + provisioner. + This field will replace the functionality of the dataSource field and as such + if both fields are non-empty, they must have the same value. For backwards + compatibility, when namespace isn't specified in dataSourceRef, + both fields (dataSource and dataSourceRef) will be set to the same + value automatically if one of them is empty and the other is non-empty. + When namespace is specified in dataSourceRef, + dataSource isn't set to the same value and must be empty. + There are three important differences between dataSource and dataSourceRef: + * While dataSource only allows two specific types of objects, dataSourceRef + allows any non-core object, as well as PersistentVolumeClaim objects. + * While dataSource ignores disallowed values (dropping them), dataSourceRef + preserves all values, and generates an error if a disallowed value is + specified. + * While dataSource only allows local objects, dataSourceRef allows objects + in any namespaces. + (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled. + (Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource + being referenced + type: string + name: + description: Name is the name of resource + being referenced + type: string + namespace: + description: |- + Namespace is the namespace of resource being referenced + Note that when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details. + (Alpha) This field requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + type: string + required: + - kind + - name + type: object + resources: + description: |- + resources represents the minimum resources the volume should have. + If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements + that are lower than previous value but must still be higher than capacity recorded in the + status field of the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + selector: + description: selector is a label query over + volumes to consider for binding. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + description: |- + storageClassName is the name of the StorageClass required by the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1 + type: string + volumeAttributesClassName: + description: |- + volumeAttributesClassName may be used to set the VolumeAttributesClass used by this claim. + If specified, the CSI driver will create or update the volume with the attributes defined + in the corresponding VolumeAttributesClass. This has a different purpose than storageClassName, + it can be changed after the claim is created. An empty string value means that no VolumeAttributesClass + will be applied to the claim but it's not allowed to reset this field to empty string once it is set. + If unspecified and the PersistentVolumeClaim is unbound, the default VolumeAttributesClass + will be set by the persistentvolume controller if it exists. + If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be + set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource + exists. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#volumeattributesclass + (Alpha) Using this field requires the VolumeAttributesClass feature gate to be enabled. + type: string + volumeMode: + description: |- + volumeMode defines what type of volume is required by the claim. + Value of Filesystem is implied when not included in claim spec. + type: string + volumeName: + description: volumeName is the binding reference + to the PersistentVolume backing this claim. + type: string + type: object + required: + - spec + type: object + type: object + fc: + description: fc represents a Fibre Channel resource that + is attached to a kubelet's host machine and then exposed + to the pod. + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + lun: + description: 'lun is Optional: FC target lun number' + format: int32 + type: integer + readOnly: + description: |- + readOnly is Optional: Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + targetWWNs: + description: 'targetWWNs is Optional: FC target worldwide + names (WWNs)' + items: + type: string + type: array + wwids: + description: |- + wwids Optional: FC volume world wide identifiers (wwids) + Either wwids or combination of targetWWNs and lun must be set, but not both simultaneously. + items: + type: string + type: array + type: object + flexVolume: + description: |- + flexVolume represents a generic volume resource that is + provisioned/attached using an exec based plugin. + properties: + driver: + description: driver is the name of the driver to use + for this volume. + type: string + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". The default filesystem depends on FlexVolume script. + type: string + options: + additionalProperties: + type: string + description: 'options is Optional: this field holds + extra command options if any.' + type: object + readOnly: + description: |- + readOnly is Optional: defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: |- + secretRef is Optional: secretRef is reference to the secret object containing + sensitive information to pass to the plugin scripts. This may be + empty if no secret object is specified. If the secret object + contains more than one secret, all secrets are passed to the plugin + scripts. + 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 + required: + - driver + type: object + flocker: + description: flocker represents a Flocker volume attached + to a kubelet's host machine. This depends on the Flocker + control service being running + properties: + datasetName: + description: |- + datasetName is Name of the dataset stored as metadata -> name on the dataset for Flocker + should be considered as deprecated + type: string + datasetUUID: + description: datasetUUID is the UUID of the dataset. + This is unique identifier of a Flocker dataset + type: string + type: object + gcePersistentDisk: + description: |- + gcePersistentDisk represents a GCE Disk resource that is attached to a + kubelet's host machine and then exposed to the pod. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + properties: + fsType: + description: |- + fsType is filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + partition: + description: |- + partition is the partition in the volume that you want to mount. + If omitted, the default is to mount by volume name. + Examples: For volume /dev/sda1, you specify the partition as "1". + Similarly, the volume partition for /dev/sda is "0" (or you can leave the property empty). + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + format: int32 + type: integer + pdName: + description: |- + pdName is unique name of the PD resource in GCE. Used to identify the disk in GCE. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + type: string + readOnly: + description: |- + readOnly here will force the ReadOnly setting in VolumeMounts. + Defaults to false. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + type: boolean + required: + - pdName + type: object + gitRepo: + description: |- + gitRepo represents a git repository at a particular revision. + DEPRECATED: GitRepo is deprecated. To provision a container with a git repo, mount an + EmptyDir into an InitContainer that clones the repo using git, then mount the EmptyDir + into the Pod's container. + properties: + directory: + description: |- + directory is the target directory name. + Must not contain or start with '..'. If '.' is supplied, the volume directory will be the + git repository. Otherwise, if specified, the volume will contain the git repository in + the subdirectory with the given name. + type: string + repository: + description: repository is the URL + type: string + revision: + description: revision is the commit hash for the specified + revision. + type: string + required: + - repository + type: object + glusterfs: + description: |- + glusterfs represents a Glusterfs mount on the host that shares a pod's lifetime. + More info: https://examples.k8s.io/volumes/glusterfs/README.md + properties: + endpoints: + description: |- + endpoints is the endpoint name that details Glusterfs topology. + More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod + type: string + path: + description: |- + path is the Glusterfs volume path. + More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod + type: string + readOnly: + description: |- + readOnly here will force the Glusterfs volume to be mounted with read-only permissions. + Defaults to false. + More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod + type: boolean + required: + - endpoints + - path + type: object + hostPath: + description: |- + hostPath represents a pre-existing file or directory on the host + machine that is directly exposed to the container. This is generally + used for system agents or other privileged things that are allowed + to see the host machine. Most containers will NOT need this. + More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + --- + TODO(jonesdl) We need to restrict who can use host directory mounts and who can/can not + mount host directories as read/write. + properties: + path: + description: |- + path of the directory on the host. + If the path is a symlink, it will follow the link to the real path. + More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + type: string + type: + description: |- + type for HostPath Volume + Defaults to "" + More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + type: string + required: + - path + type: object + iscsi: + description: |- + iscsi represents an ISCSI Disk resource that is attached to a + kubelet's host machine and then exposed to the pod. + More info: https://examples.k8s.io/volumes/iscsi/README.md + properties: + chapAuthDiscovery: + description: chapAuthDiscovery defines whether support + iSCSI Discovery CHAP authentication + type: boolean + chapAuthSession: + description: chapAuthSession defines whether support + iSCSI Session CHAP authentication + type: boolean + fsType: + description: |- + fsType is the filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#iscsi + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + initiatorName: + description: |- + initiatorName is the custom iSCSI Initiator Name. + If initiatorName is specified with iscsiInterface simultaneously, new iSCSI interface + : will be created for the connection. + type: string + iqn: + description: iqn is the target iSCSI Qualified Name. + type: string + iscsiInterface: + description: |- + iscsiInterface is the interface Name that uses an iSCSI transport. + Defaults to 'default' (tcp). + type: string + lun: + description: lun represents iSCSI Target Lun number. + format: int32 + type: integer + portals: + description: |- + portals is the iSCSI Target Portal List. The portal is either an IP or ip_addr:port if the port + is other than default (typically TCP ports 860 and 3260). + items: + type: string + type: array + readOnly: + description: |- + readOnly here will force the ReadOnly setting in VolumeMounts. + Defaults to false. + type: boolean + secretRef: + description: secretRef is the CHAP Secret for iSCSI + target and initiator authentication + 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 + targetPortal: + description: |- + targetPortal is iSCSI Target Portal. The Portal is either an IP or ip_addr:port if the port + is other than default (typically TCP ports 860 and 3260). + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + description: |- + name of the volume. + Must be a DNS_LABEL and unique within the pod. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + nfs: + description: |- + nfs represents an NFS mount on the host that shares a pod's lifetime + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + properties: + path: + description: |- + path that is exported by the NFS server. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + type: string + readOnly: + description: |- + readOnly here will force the NFS export to be mounted with read-only permissions. + Defaults to false. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + type: boolean + server: + description: |- + server is the hostname or IP address of the NFS server. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + description: |- + persistentVolumeClaimVolumeSource represents a reference to a + PersistentVolumeClaim in the same namespace. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims + properties: + claimName: + description: |- + claimName is the name of a PersistentVolumeClaim in the same namespace as the pod using this volume. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims + type: string + readOnly: + description: |- + readOnly Will force the ReadOnly setting in VolumeMounts. + Default false. + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + description: photonPersistentDisk represents a PhotonController + persistent disk attached and mounted on kubelets host + machine + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + pdID: + description: pdID is the ID that identifies Photon + Controller persistent disk + type: string + required: + - pdID + type: object + portworxVolume: + description: portworxVolume represents a portworx volume + attached and mounted on kubelets host machine + properties: + fsType: + description: |- + fSType represents the filesystem type to mount + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs". Implicitly inferred to be "ext4" if unspecified. + type: string + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + volumeID: + description: volumeID uniquely identifies a Portworx + volume + type: string + required: + - volumeID + type: object + projected: + description: projected items for all in one resources + secrets, configmaps, and downward API + properties: + defaultMode: + description: |- + defaultMode are the mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + sources: + description: sources is the list of volume projections + items: + description: Projection that may be projected along + with other supported volume types + properties: + clusterTrustBundle: + description: |- + ClusterTrustBundle allows a pod to access the `.spec.trustBundle` field + of ClusterTrustBundle objects in an auto-updating file. + + + Alpha, gated by the ClusterTrustBundleProjection feature gate. + + + ClusterTrustBundle objects can either be selected by name, or by the + combination of signer name and a label selector. + + + Kubelet performs aggressive normalization of the PEM contents written + into the pod filesystem. Esoteric PEM features such as inter-block + comments and block headers are stripped. Certificates are deduplicated. + The ordering of certificates within the file is arbitrary, and Kubelet + may change the order over time. + properties: + labelSelector: + description: |- + Select all ClusterTrustBundles that match this label selector. Only has + effect if signerName is set. Mutually-exclusive with name. If unset, + interpreted as "match nothing". If set but empty, interpreted as "match + everything". + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + name: + description: |- + Select a single ClusterTrustBundle by object name. Mutually-exclusive + with signerName and labelSelector. + type: string + optional: + description: |- + If true, don't block pod startup if the referenced ClusterTrustBundle(s) + aren't available. If using name, then the named ClusterTrustBundle is + allowed not to exist. If using signerName, then the combination of + signerName and labelSelector is allowed to match zero + ClusterTrustBundles. + type: boolean + path: + description: Relative path from the volume + root to write the bundle. + type: string + signerName: + description: |- + Select all ClusterTrustBundles that match this signer name. + Mutually-exclusive with name. The contents of all selected + ClusterTrustBundles will be unified and deduplicated. + type: string + required: + - path + type: object + configMap: + description: configMap information about the + configMap data to project + properties: + items: + description: |- + items if unspecified, each key-value pair in the Data field of the referenced + ConfigMap will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the ConfigMap, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path + within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + 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 + optional: + description: optional specify whether the + ConfigMap or its keys must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + downwardAPI: + description: downwardAPI information about the + downwardAPI data to project + properties: + items: + description: Items is a list of DownwardAPIVolume + file + items: + description: DownwardAPIVolumeFile represents + information to create the file containing + the pod field + properties: + fieldRef: + description: 'Required: Selects a + field of the pod: only annotations, + labels, name and namespace are supported.' + properties: + apiVersion: + description: Version of the schema + the FieldPath is written in + terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field + to select in the specified API + version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + description: |- + Optional: mode bits used to set permissions on this file, must be an octal value + between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: 'Required: Path is the + relative path name of the file to + be created. Must not be absolute + or contain the ''..'' path. Must + be utf-8 encoded. The first item + of the relative path must not start + with ''..''' + type: string + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported. + properties: + containerName: + description: 'Container name: + required for volumes, optional + for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output + format of the exposed resources, + defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource + to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + type: object + secret: + description: secret information about the secret + data to project + properties: + items: + description: |- + items if unspecified, each key-value pair in the Data field of the referenced + Secret will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the Secret, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path + within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + 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 + optional: + description: optional field specify whether + the Secret or its key must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + serviceAccountToken: + description: serviceAccountToken is information + about the serviceAccountToken data to project + properties: + audience: + description: |- + audience is the intended audience of the token. A recipient of a token + must identify itself with an identifier specified in the audience of the + token, and otherwise should reject the token. The audience defaults to the + identifier of the apiserver. + type: string + expirationSeconds: + description: |- + expirationSeconds is the requested duration of validity of the service + account token. As the token approaches expiration, the kubelet volume + plugin will proactively rotate the service account token. The kubelet will + start trying to rotate the token if the token is older than 80 percent of + its time to live or if the token is older than 24 hours.Defaults to 1 hour + and must be at least 10 minutes. + format: int64 + type: integer + path: + description: |- + path is the path relative to the mount point of the file to project the + token into. + type: string + required: + - path + type: object + type: object + type: array + type: object + quobyte: + description: quobyte represents a Quobyte mount on the + host that shares a pod's lifetime + properties: + group: + description: |- + group to map volume access to + Default is no group + type: string + readOnly: + description: |- + readOnly here will force the Quobyte volume to be mounted with read-only permissions. + Defaults to false. + type: boolean + registry: + description: |- + registry represents a single or multiple Quobyte Registry services + specified as a string as host:port pair (multiple entries are separated with commas) + which acts as the central registry for volumes + type: string + tenant: + description: |- + tenant owning the given Quobyte volume in the Backend + Used with dynamically provisioned Quobyte volumes, value is set by the plugin + type: string + user: + description: |- + user to map volume access to + Defaults to serivceaccount user + type: string + volume: + description: volume is a string that references an + already created Quobyte volume by name. + type: string + required: + - registry + - volume + type: object + rbd: + description: |- + rbd represents a Rados Block Device mount on the host that shares a pod's lifetime. + More info: https://examples.k8s.io/volumes/rbd/README.md + properties: + fsType: + description: |- + fsType is the filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#rbd + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + image: + description: |- + image is the rados image name. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + keyring: + description: |- + keyring is the path to key ring for RBDUser. + Default is /etc/ceph/keyring. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + monitors: + description: |- + monitors is a collection of Ceph monitors. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + items: + type: string + type: array + pool: + description: |- + pool is the rados pool name. + Default is rbd. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + readOnly: + description: |- + readOnly here will force the ReadOnly setting in VolumeMounts. + Defaults to false. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: boolean + secretRef: + description: |- + secretRef is name of the authentication secret for RBDUser. If provided + overrides keyring. + Default is nil. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + 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 + user: + description: |- + user is the rados user name. + Default is admin. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + required: + - image + - monitors + type: object + scaleIO: + description: scaleIO represents a ScaleIO persistent volume + attached and mounted on Kubernetes nodes. + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". + Default is "xfs". + type: string + gateway: + description: gateway is the host address of the ScaleIO + API Gateway. + type: string + protectionDomain: + description: protectionDomain is the name of the ScaleIO + Protection Domain for the configured storage. + type: string + readOnly: + description: |- + readOnly Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: |- + secretRef references to the secret for ScaleIO user and other + sensitive information. If this is not provided, Login operation will fail. + 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 + sslEnabled: + description: sslEnabled Flag enable/disable SSL communication + with Gateway, default false + type: boolean + storageMode: + description: |- + storageMode indicates whether the storage for a volume should be ThickProvisioned or ThinProvisioned. + Default is ThinProvisioned. + type: string + storagePool: + description: storagePool is the ScaleIO Storage Pool + associated with the protection domain. + type: string + system: + description: system is the name of the storage system + as configured in ScaleIO. + type: string + volumeName: + description: |- + volumeName is the name of a volume already created in the ScaleIO system + that is associated with this volume source. + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + description: |- + secret represents a secret that should populate this volume. + More info: https://kubernetes.io/docs/concepts/storage/volumes#secret + properties: + defaultMode: + description: |- + defaultMode is Optional: mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values + for mode bits. Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + items: + description: |- + items If unspecified, each key-value pair in the Data field of the referenced + Secret will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the Secret, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within + a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + optional: + description: optional field specify whether the Secret + or its keys must be defined + type: boolean + secretName: + description: |- + secretName is the name of the secret in the pod's namespace to use. + More info: https://kubernetes.io/docs/concepts/storage/volumes#secret + type: string + type: object + storageos: + description: storageOS represents a StorageOS volume attached + and mounted on Kubernetes nodes. + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: |- + secretRef specifies the secret to use for obtaining the StorageOS API + credentials. If not specified, default values will be attempted. + 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 + volumeName: + description: |- + volumeName is the human-readable name of the StorageOS volume. Volume + names are only unique within a namespace. + type: string + volumeNamespace: + description: |- + volumeNamespace specifies the scope of the volume within StorageOS. If no + namespace is specified then the Pod's namespace will be used. This allows the + Kubernetes name scoping to be mirrored within StorageOS for tighter integration. + Set VolumeName to any name to override the default behaviour. + Set to "default" if you are not using namespaces within StorageOS. + Namespaces that do not pre-exist within StorageOS will be created. + type: string + type: object + vsphereVolume: + description: vsphereVolume represents a vSphere volume + attached and mounted on kubelets host machine + properties: + fsType: + description: |- + fsType is filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + storagePolicyID: + description: storagePolicyID is the storage Policy + Based Management (SPBM) profile ID associated with + the StoragePolicyName. + type: string + storagePolicyName: + description: storagePolicyName is the storage Policy + Based Management (SPBM) profile name. + type: string + volumePath: + description: volumePath is the path that identifies + vSphere volume vmdk + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + memberUpdateStrategy: + description: |- + Members(Pods) update strategy. + + + - serial: update Members one by one that guarantee minimum component unavailable time. + - bestEffortParallel: update Members in parallel that guarantee minimum component un-writable time. + - parallel: force parallel + enum: + - Serial + - BestEffortParallel + - Parallel + type: string + membershipReconfiguration: + description: Provides actions to do membership dynamic reconfiguration. + properties: + logSyncAction: + description: |- + Defines the action to trigger the new member to start log syncing. + If the Image is not configured, the Image from the previous non-nil action will be used. + properties: + args: + description: Additional parameters used to perform specific + statements. This field is optional. + items: + type: string + type: array + command: + description: A set of instructions that will be executed within + the Container to retrieve or process role information. This + field is required. + items: + type: string + type: array + image: + description: Refers to the utility image that contains the + command which can be utilized to retrieve or process role + information. + type: string + required: + - command + type: object + memberJoinAction: + description: |- + Defines the action to add a member. + If the Image is not configured, the Image from the previous non-nil action will be used. + properties: + args: + description: Additional parameters used to perform specific + statements. This field is optional. + items: + type: string + type: array + command: + description: A set of instructions that will be executed within + the Container to retrieve or process role information. This + field is required. + items: + type: string + type: array + image: + description: Refers to the utility image that contains the + command which can be utilized to retrieve or process role + information. + type: string + required: + - command + type: object + memberLeaveAction: + description: |- + Defines the action to remove a member. + If the Image is not configured, the Image from the previous non-nil action will be used. + properties: + args: + description: Additional parameters used to perform specific + statements. This field is optional. + items: + type: string + type: array + command: + description: A set of instructions that will be executed within + the Container to retrieve or process role information. This + field is required. + items: + type: string + type: array + image: + description: Refers to the utility image that contains the + command which can be utilized to retrieve or process role + information. + type: string + required: + - command + type: object + promoteAction: + description: |- + Defines the action to inform the cluster that the new member can join voting now. + If the Image is not configured, the Image from the previous non-nil action will be used. + properties: + args: + description: Additional parameters used to perform specific + statements. This field is optional. + items: + type: string + type: array + command: + description: A set of instructions that will be executed within + the Container to retrieve or process role information. This + field is required. + items: + type: string + type: array + image: + description: Refers to the utility image that contains the + command which can be utilized to retrieve or process role + information. + type: string + required: + - command + type: object + switchoverAction: + description: |- + Specifies the environment variables that can be used in all following Actions: + - KB_ITS_USERNAME: Represents the username part of the credential + - KB_ITS_PASSWORD: Represents the password part of the credential + - KB_ITS_LEADER_HOST: Represents the leader host + - KB_ITS_TARGET_HOST: Represents the target host + - KB_ITS_SERVICE_PORT: Represents the service port + + + Defines the action to perform a switchover. + If the Image is not configured, the latest [BusyBox](https://busybox.net/) image will be used. + properties: + args: + description: Additional parameters used to perform specific + statements. This field is optional. + items: + type: string + type: array + command: + description: A set of instructions that will be executed within + the Container to retrieve or process role information. This + field is required. + items: + type: string + type: array + image: + description: Refers to the utility image that contains the + command which can be utilized to retrieve or process role + information. + type: string + required: + - command + type: object + type: object + minReadySeconds: + default: 0 + description: |- + Defines the minimum number of seconds a newly created pod should be ready + without any of its container crashing to be considered available. + Defaults to 0, meaning the pod will be considered available as soon as it is ready. + format: int32 + minimum: 0 + type: integer + offlineInstances: + description: |- + Specifies the names of instances to be transitioned to offline status. + + + Marking an instance as offline results in the following: + + + 1. The associated pod is stopped, and its PersistentVolumeClaim (PVC) is retained for potential + future reuse or data recovery, but it is no longer actively used. + 2. The ordinal number assigned to this instance is preserved, ensuring it remains unique + and avoiding conflicts with new instances. + + + Setting instances to offline allows for a controlled scale-in process, preserving their data and maintaining + ordinal consistency within the cluster. + Note that offline instances and their associated resources, such as PVCs, are not automatically deleted. + The cluster administrator must manually manage the cleanup and removal of these resources when they are no longer needed. + items: + type: string + type: array + parallelPodManagementConcurrency: + anyOf: + - type: integer + - type: string + description: |- + Controls the concurrency of pods during initial scale up, when replacing pods on nodes, + or when scaling down. It only used when `PodManagementPolicy` is set to `Parallel`. + The default Concurrency is 100%. + x-kubernetes-int-or-string: true + paused: + description: Indicates that the InstanceSet is paused, meaning the + reconciliation of this InstanceSet object will be paused. + type: boolean + podManagementPolicy: + description: |- + Controls how pods are created during initial scale up, + when replacing pods on nodes, or when scaling down. + + + The default policy is `OrderedReady`, where pods are created in increasing order and the controller waits until each pod is ready before + continuing. When scaling down, the pods are removed in the opposite order. + The alternative policy is `Parallel` which will create pods in parallel + to match the desired scale without waiting, and on scale down will delete + all pods at once. + + + Note: This field will be removed in future version. + type: string + podUpdatePolicy: + description: |- + PodUpdatePolicy indicates how pods should be updated + + + - `StrictInPlace` indicates that only allows in-place upgrades. + Any attempt to modify other fields will be rejected. + - `PreferInPlace` indicates that we will first attempt an in-place upgrade of the Pod. + If that fails, it will fall back to the ReCreate, where pod will be recreated. + Default value is "PreferInPlace" + type: string + replicas: + default: 1 + description: |- + Specifies the desired number of replicas of the given Template. + These replicas are instantiations of the same Template, with each having a consistent identity. + Defaults to 1 if unspecified. + format: int32 + minimum: 0 + type: integer + roleProbe: + description: Provides method to probe role. + properties: + customHandler: + description: |- + Defines a custom method for role probing. + Actions defined here are executed in series. + Upon completion of all actions, the final output should be a single string representing the role name defined in spec.Roles. + The latest [BusyBox](https://busybox.net/) image will be used if Image is not configured. + Environment variables can be used in Command: + - v_KB_ITS_LAST_STDOUT: stdout from the last action, watch for 'v_' prefix + - KB_ITS_USERNAME: username part of the credential + - KB_ITS_PASSWORD: password part of the credential + items: + properties: + args: + description: Additional parameters used to perform specific + statements. This field is optional. + items: + type: string + type: array + command: + description: A set of instructions that will be executed + within the Container to retrieve or process role information. + This field is required. + items: + type: string + type: array + image: + description: Refers to the utility image that contains the + command which can be utilized to retrieve or process role + information. + type: string + required: + - command + type: object + type: array + failureThreshold: + default: 3 + description: Specifies the minimum number of consecutive failures + for the probe to be considered failed after having succeeded. + format: int32 + minimum: 1 + type: integer + initialDelaySeconds: + default: 0 + description: Specifies the number of seconds to wait after the + container has started before initiating role probing. + format: int32 + minimum: 0 + type: integer + periodSeconds: + default: 2 + description: Specifies the frequency (in seconds) of probe execution. + format: int32 + minimum: 1 + type: integer + roleUpdateMechanism: + default: ReadinessProbeEventUpdate + description: Specifies the method for updating the pod role label. + enum: + - ReadinessProbeEventUpdate + - DirectAPIServerEventUpdate + type: string + successThreshold: + default: 1 + description: Specifies the minimum number of consecutive successes + for the probe to be considered successful after having failed. + format: int32 + minimum: 1 + type: integer + timeoutSeconds: + default: 1 + description: Specifies the number of seconds after which the probe + times out. + format: int32 + minimum: 1 + type: integer + type: object + roles: + description: A list of roles defined in the system. + items: + properties: + accessMode: + default: ReadWrite + description: Specifies the service capabilities of this member. + enum: + - None + - Readonly + - ReadWrite + type: string + canVote: + default: true + description: Indicates if this member has voting rights. + type: boolean + isLeader: + default: false + description: Determines if this member is the leader. + type: boolean + name: + default: leader + description: Defines the role name of the replica. + type: string + required: + - accessMode + - name + type: object + type: array + selector: + description: |- + Represents a label query over pods that should match the desired replica count indicated by the `replica` field. + It must match the labels defined in the pod template. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. + The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + service: + description: |- + Defines the behavior of a service spec. + Provides read-write service. + https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status + + + Note: This field will be removed in future version. + 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: + description: |- + Standard object's metadata. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + description: |- + Spec defines the behavior of a service. + https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status + properties: + allocateLoadBalancerNodePorts: + description: |- + allocateLoadBalancerNodePorts defines if NodePorts will be automatically + allocated for services with type LoadBalancer. Default is "true". It + may be set to "false" if the cluster load-balancer does not rely on + NodePorts. If the caller requests specific NodePorts (by specifying a + value), those requests will be respected, regardless of this field. + This field may only be set for services with type LoadBalancer and will + be cleared if the type is changed to any other type. + type: boolean + clusterIP: + description: |- + clusterIP is the IP address of the service and is usually assigned + randomly. If an address is specified manually, is in-range (as per + system configuration), and is not in use, it will be allocated to the + service; otherwise creation of the service will fail. This field may not + be changed through updates unless the type field is also being changed + to ExternalName (which requires this field to be blank) or the type + field is being changed from ExternalName (in which case this field may + optionally be specified, as describe above). Valid values are "None", + empty string (""), or a valid IP address. Setting this to "None" makes a + "headless service" (no virtual IP), which is useful when direct endpoint + connections are preferred and proxying is not required. Only applies to + types ClusterIP, NodePort, and LoadBalancer. If this field is specified + when creating a Service of type ExternalName, creation will fail. This + field will be wiped when updating a Service to type ExternalName. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + type: string + clusterIPs: + description: |- + ClusterIPs is a list of IP addresses assigned to this service, and are + usually assigned randomly. If an address is specified manually, is + in-range (as per system configuration), and is not in use, it will be + allocated to the service; otherwise creation of the service will fail. + This field may not be changed through updates unless the type field is + also being changed to ExternalName (which requires this field to be + empty) or the type field is being changed from ExternalName (in which + case this field may optionally be specified, as describe above). Valid + values are "None", empty string (""), or a valid IP address. Setting + this to "None" makes a "headless service" (no virtual IP), which is + useful when direct endpoint connections are preferred and proxying is + not required. Only applies to types ClusterIP, NodePort, and + LoadBalancer. If this field is specified when creating a Service of type + ExternalName, creation will fail. This field will be wiped when updating + a Service to type ExternalName. If this field is not specified, it will + be initialized from the clusterIP field. If this field is specified, + clients must ensure that clusterIPs[0] and clusterIP have the same + value. + + + This field may hold a maximum of two entries (dual-stack IPs, in either order). + These IPs must correspond to the values of the ipFamilies field. Both + clusterIPs and ipFamilies are governed by the ipFamilyPolicy field. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalIPs: + description: |- + externalIPs is a list of IP addresses for which nodes in the cluster + will also accept traffic for this service. These IPs are not managed by + Kubernetes. The user is responsible for ensuring that traffic arrives + at a node with this IP. A common example is external load-balancers + that are not part of the Kubernetes system. + items: + type: string + type: array + externalName: + description: |- + externalName is the external reference that discovery mechanisms will + return as an alias for this service (e.g. a DNS CNAME record). No + proxying will be involved. Must be a lowercase RFC-1123 hostname + (https://tools.ietf.org/html/rfc1123) and requires `type` to be "ExternalName". + type: string + externalTrafficPolicy: + description: |- + externalTrafficPolicy describes how nodes distribute service traffic they + receive on one of the Service's "externally-facing" addresses (NodePorts, + ExternalIPs, and LoadBalancer IPs). If set to "Local", the proxy will configure + the service in a way that assumes that external load balancers will take care + of balancing the service traffic between nodes, and so each node will deliver + traffic only to the node-local endpoints of the service, without masquerading + the client source IP. (Traffic mistakenly sent to a node with no endpoints will + be dropped.) The default value, "Cluster", uses the standard behavior of + routing to all endpoints evenly (possibly modified by topology and other + features). Note that traffic sent to an External IP or LoadBalancer IP from + within the cluster will always get "Cluster" semantics, but clients sending to + a NodePort from within the cluster may need to take traffic policy into account + when picking a node. + type: string + healthCheckNodePort: + description: |- + healthCheckNodePort specifies the healthcheck nodePort for the service. + This only applies when type is set to LoadBalancer and + externalTrafficPolicy is set to Local. If a value is specified, is + in-range, and is not in use, it will be used. If not specified, a value + will be automatically allocated. External systems (e.g. load-balancers) + can use this port to determine if a given node holds endpoints for this + service or not. If this field is specified when creating a Service + which does not need it, creation will fail. This field will be wiped + when updating a Service to no longer need it (e.g. changing type). + This field cannot be updated once set. + format: int32 + type: integer + internalTrafficPolicy: + description: |- + InternalTrafficPolicy describes how nodes distribute service traffic they + receive on the ClusterIP. If set to "Local", the proxy will assume that pods + only want to talk to endpoints of the service on the same node as the pod, + dropping the traffic if there are no local endpoints. The default value, + "Cluster", uses the standard behavior of routing to all endpoints evenly + (possibly modified by topology and other features). + type: string + ipFamilies: + description: |- + IPFamilies is a list of IP families (e.g. IPv4, IPv6) assigned to this + service. This field is usually assigned automatically based on cluster + configuration and the ipFamilyPolicy field. If this field is specified + manually, the requested family is available in the cluster, + and ipFamilyPolicy allows it, it will be used; otherwise creation of + the service will fail. This field is conditionally mutable: it allows + for adding or removing a secondary IP family, but it does not allow + changing the primary IP family of the Service. Valid values are "IPv4" + and "IPv6". This field only applies to Services of types ClusterIP, + NodePort, and LoadBalancer, and does apply to "headless" services. + This field will be wiped when updating a Service to type ExternalName. + + + This field may hold a maximum of two entries (dual-stack families, in + either order). These families must correspond to the values of the + clusterIPs field, if specified. Both clusterIPs and ipFamilies are + governed by the ipFamilyPolicy field. + items: + description: |- + IPFamily represents the IP Family (IPv4 or IPv6). This type is used + to express the family of an IP expressed by a type (e.g. service.spec.ipFamilies). + type: string + type: array + x-kubernetes-list-type: atomic + ipFamilyPolicy: + description: |- + IPFamilyPolicy represents the dual-stack-ness requested or required by + this Service. If there is no value provided, then this field will be set + to SingleStack. Services can be "SingleStack" (a single IP family), + "PreferDualStack" (two IP families on dual-stack configured clusters or + a single IP family on single-stack clusters), or "RequireDualStack" + (two IP families on dual-stack configured clusters, otherwise fail). The + ipFamilies and clusterIPs fields depend on the value of this field. This + field will be wiped when updating a service to type ExternalName. + type: string + loadBalancerClass: + description: |- + loadBalancerClass is the class of the load balancer implementation this Service belongs to. + If specified, the value of this field must be a label-style identifier, with an optional prefix, + e.g. "internal-vip" or "example.com/internal-vip". Unprefixed names are reserved for end-users. + This field can only be set when the Service type is 'LoadBalancer'. If not set, the default load + balancer implementation is used, today this is typically done through the cloud provider integration, + but should apply for any default implementation. If set, it is assumed that a load balancer + implementation is watching for Services with a matching class. Any default load balancer + implementation (e.g. cloud providers) should ignore Services that set this field. + This field can only be set when creating or updating a Service to type 'LoadBalancer'. + Once set, it can not be changed. This field will be wiped when a service is updated to a non 'LoadBalancer' type. + type: string + loadBalancerIP: + description: |- + Only applies to Service Type: LoadBalancer. + This feature depends on whether the underlying cloud-provider supports specifying + the loadBalancerIP when a load balancer is created. + This field will be ignored if the cloud-provider does not support the feature. + Deprecated: This field was under-specified and its meaning varies across implementations. + Using it is non-portable and it may not support dual-stack. + Users are encouraged to use implementation-specific annotations when available. + type: string + loadBalancerSourceRanges: + description: |- + If specified and supported by the platform, this will restrict traffic through the cloud-provider + load-balancer will be restricted to the specified client IPs. This field will be ignored if the + cloud-provider does not support the feature." + More info: https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/ + items: + type: string + type: array + ports: + description: |- + The list of ports that are exposed by this service. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + items: + description: ServicePort contains information on service's + port. + properties: + appProtocol: + description: |- + The application protocol for this port. + This is used as a hint for implementations to offer richer behavior for protocols that they understand. + This field follows standard Kubernetes label syntax. + Valid values are either: + + + * Un-prefixed protocol names - reserved for IANA standard service names (as per + RFC-6335 and https://www.iana.org/assignments/service-names). + + + * Kubernetes-defined prefixed names: + * 'kubernetes.io/h2c' - HTTP/2 prior knowledge over cleartext as described in https://www.rfc-editor.org/rfc/rfc9113.html#name-starting-http-2-with-prior- + * 'kubernetes.io/ws' - WebSocket over cleartext as described in https://www.rfc-editor.org/rfc/rfc6455 + * 'kubernetes.io/wss' - WebSocket over TLS as described in https://www.rfc-editor.org/rfc/rfc6455 + + + * Other protocols should use implementation-defined prefixed names such as + mycompany.com/my-custom-protocol. + type: string + name: + description: |- + The name of this port within the service. This must be a DNS_LABEL. + All ports within a ServiceSpec must have unique names. When considering + the endpoints for a Service, this must match the 'name' field in the + EndpointPort. + Optional if only one ServicePort is defined on this service. + type: string + nodePort: + description: |- + The port on each node on which this service is exposed when type is + NodePort or LoadBalancer. Usually assigned by the system. If a value is + specified, in-range, and not in use it will be used, otherwise the + operation will fail. If not specified, a port will be allocated if this + Service requires one. If this field is specified when creating a + Service which does not need it, creation will fail. This field will be + wiped when updating a Service to no longer need it (e.g. changing type + from NodePort to ClusterIP). + More info: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport + format: int32 + type: integer + port: + description: The port that will be exposed by this service. + format: int32 + type: integer + protocol: + default: TCP + description: |- + The IP protocol for this port. Supports "TCP", "UDP", and "SCTP". + Default is TCP. + type: string + targetPort: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the pods targeted by the service. + Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + If this is a string, it will be looked up as a named port in the + target Pod's container ports. If this is not specified, the value + of the 'port' field is used (an identity map). + This field is ignored for services with clusterIP=None, and should be + omitted or set equal to the 'port' field. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#defining-a-service + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-map-keys: + - port + - protocol + x-kubernetes-list-type: map + publishNotReadyAddresses: + description: |- + publishNotReadyAddresses indicates that any agent which deals with endpoints for this + Service should disregard any indications of ready/not-ready. + The primary use case for setting this field is for a StatefulSet's Headless Service to + propagate SRV DNS records for its Pods for the purpose of peer discovery. + The Kubernetes controllers that generate Endpoints and EndpointSlice resources for + Services interpret this to mean that all endpoints are considered "ready" even if the + Pods themselves are not. Agents which consume only Kubernetes generated endpoints + through the Endpoints or EndpointSlice resources can safely assume this behavior. + type: boolean + selector: + additionalProperties: + type: string + description: |- + Route service traffic to pods with label keys and values matching this + selector. If empty or not present, the service is assumed to have an + external process managing its endpoints, which Kubernetes will not + modify. Only applies to types ClusterIP, NodePort, and LoadBalancer. + Ignored if type is ExternalName. + More info: https://kubernetes.io/docs/concepts/services-networking/service/ + type: object + x-kubernetes-map-type: atomic + sessionAffinity: + description: |- + Supports "ClientIP" and "None". Used to maintain session affinity. + Enable client IP based session affinity. + Must be ClientIP or None. + Defaults to None. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + type: string + sessionAffinityConfig: + description: sessionAffinityConfig contains the configurations + of session affinity. + properties: + clientIP: + description: clientIP contains the configurations of Client + IP based session affinity. + properties: + timeoutSeconds: + description: |- + timeoutSeconds specifies the seconds of ClientIP type session sticky time. + The value must be >0 && <=86400(for 1 day) if ServiceAffinity == "ClientIP". + Default value is 10800(for 3 hours). + format: int32 + type: integer + type: object + type: object + type: + description: |- + type determines how the Service is exposed. Defaults to ClusterIP. Valid + options are ExternalName, ClusterIP, NodePort, and LoadBalancer. + "ClusterIP" allocates a cluster-internal IP address for load-balancing + to endpoints. Endpoints are determined by the selector or if that is not + specified, by manual construction of an Endpoints object or + EndpointSlice objects. If clusterIP is "None", no virtual IP is + allocated and the endpoints are published as a set of endpoints rather + than a virtual IP. + "NodePort" builds on ClusterIP and allocates a port on every node which + routes to the same endpoints as the clusterIP. + "LoadBalancer" builds on NodePort and creates an external load-balancer + (if supported in the current cloud) which routes to the same endpoints + as the clusterIP. + "ExternalName" aliases this service to the specified externalName. + Several other fields do not apply to ExternalName services. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types + type: string + type: object + status: + description: |- + Most recently observed status of the service. + Populated by the system. + Read-only. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status + properties: + conditions: + description: Current service state + items: + description: "Condition contains details for one aspect + of the current state of this API Resource.\n---\nThis + struct is intended for direct use as an array at the field + path .status.conditions. For example,\n\n\n\ttype FooStatus + struct{\n\t // Represents the observations of a foo's + current state.\n\t // Known .status.conditions.type + are: \"Available\", \"Progressing\", and \"Degraded\"\n\t + \ // +patchMergeKey=type\n\t // +patchStrategy=merge\n\t + \ // +listType=map\n\t // +listMapKey=type\n\t Conditions + []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" + patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t + \ // other fields\n\t}" + 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 + loadBalancer: + description: |- + LoadBalancer contains the current status of the load-balancer, + if one is present. + properties: + ingress: + description: |- + Ingress is a list containing ingress points for the load-balancer. + Traffic intended for the service should be sent to these ingress points. + items: + description: |- + LoadBalancerIngress represents the status of a load-balancer ingress point: + traffic intended for the service should be sent to an ingress point. + properties: + hostname: + description: |- + Hostname is set for load-balancer ingress points that are DNS based + (typically AWS load-balancers) + type: string + ip: + description: |- + IP is set for load-balancer ingress points that are IP based + (typically GCE or OpenStack load-balancers) + type: string + ipMode: + description: |- + IPMode specifies how the load-balancer IP behaves, and may only be specified when the ip field is specified. + Setting this to "VIP" indicates that traffic is delivered to the node with + the destination set to the load-balancer's IP and port. + Setting this to "Proxy" indicates that traffic is delivered to the node or pod with + the destination set to the node's IP and node port or the pod's IP and port. + Service implementations may use this information to adjust traffic routing. + type: string + ports: + description: |- + Ports is a list of records of service ports + If used, every port defined in the service should have an entry in it + items: + properties: + error: + description: |- + Error is to record the problem with the service port + The format of the error shall comply with the following rules: + - built-in error values shall be specified in this file and those shall use + CamelCase names + - cloud provider specific error values must have names that comply with the + format foo.example.com/CamelCase. + --- + 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 + port: + description: Port is the port number of the + service port of which status is recorded + here + format: int32 + type: integer + protocol: + default: TCP + description: |- + Protocol is the protocol of the service port of which status is recorded here + The supported values are: "TCP", "UDP", "SCTP" + type: string + required: + - port + - protocol + type: object + type: array + x-kubernetes-list-type: atomic + type: object + type: array + type: object + type: object + type: object + x-kubernetes-preserve-unknown-fields: true + template: + description: PodTemplateSpec describes the data a pod should have + when created from a template + properties: + metadata: + description: |- + Standard object's metadata. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + description: |- + Specification of the desired behavior of the pod. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status + properties: + activeDeadlineSeconds: + description: |- + Optional duration in seconds the pod may be active on the node relative to + StartTime before the system will actively try to mark it failed and kill associated containers. + Value must be a positive integer. + format: int64 + type: integer + affinity: + description: If specified, the pod's scheduling constraints + properties: + nodeAffinity: + description: Describes node affinity scheduling rules + for the pod. + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node matches the corresponding matchExpressions; the + node(s) with the highest sum are the most preferred. + items: + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). + properties: + preference: + description: A node selector term, associated + with the corresponding weight. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that the + selector applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that the + selector applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + weight: + description: Weight associated with matching + the corresponding nodeSelectorTerm, in the + range 1-100. + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. + properties: + nodeSelectorTerms: + description: Required. A list of node selector + terms. The terms are ORed. + items: + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that the + selector applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that the + selector applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + type: array + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + description: Describes pod affinity scheduling rules (e.g. + co-locate this pod in the same node, zone, etc. as some + other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred + node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, + associated with the corresponding weight. + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. + Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: |- + weight associated with matching the corresponding podAffinityTerm, + in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. + items: + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. + Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + description: Describes pod anti-affinity scheduling rules + (e.g. avoid putting this pod in the same node, zone, + etc. as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the anti-affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred + node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, + associated with the corresponding weight. + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. + Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: |- + weight associated with matching the corresponding podAffinityTerm, + in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the anti-affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the anti-affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. + items: + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. + Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + automountServiceAccountToken: + description: AutomountServiceAccountToken indicates whether + a service account token should be automatically mounted. + type: boolean + containers: + description: |- + List of containers belonging to the pod. + Containers cannot currently be added or removed. + There must be at least one container in a Pod. + Cannot be updated. + items: + description: A single application container that you want + to run within a pod. + properties: + args: + description: |- + Arguments to the entrypoint. + The container image's CMD is used if this is not provided. + Variable references $(VAR_NAME) are expanded using the container's environment. If a variable + cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will + produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless + of whether the variable exists or not. Cannot be updated. + More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell + items: + type: string + type: array + command: + description: |- + Entrypoint array. Not executed within a shell. + The container image's ENTRYPOINT is used if this is not provided. + Variable references $(VAR_NAME) are expanded using the container's environment. If a variable + cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will + produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless + of whether the variable exists or not. Cannot be updated. + More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell + items: + type: string + type: array + env: + description: |- + List of environment variables to set in the container. + Cannot be updated. + items: + description: EnvVar represents an environment variable + present in a Container. + properties: + name: + description: Name of the environment variable. + Must be a C_IDENTIFIER. + type: string + value: + description: |- + Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in the container and + any service environment variables. If a variable cannot be resolved, + the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless of whether the variable + exists or not. + Defaults to "". + type: string + valueFrom: + description: Source for the environment variable's + value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the + FieldPath is written in terms of, defaults + to "v1". + type: string + fieldPath: + description: Path of the field to select + in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required + for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format + of the exposed resources, defaults to + "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in + the pod's namespace + properties: + key: + description: The key of the secret to + select from. Must be a valid secret + key. + type: string + 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 + optional: + description: Specify whether the Secret + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + envFrom: + description: |- + List of sources to populate environment variables in the container. + The keys defined within a source must be a C_IDENTIFIER. All invalid keys + will be reported as an event when the container is starting. When a key exists in multiple + sources, the value associated with the last source will take precedence. + Values defined by an Env with a duplicate key will take precedence. + Cannot be updated. + items: + description: EnvFromSource represents the source of + a set of ConfigMaps + properties: + configMapRef: + description: The ConfigMap to select from + 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 + optional: + description: Specify whether the ConfigMap + must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + description: An optional identifier to prepend + to each key in the ConfigMap. Must be a C_IDENTIFIER. + type: string + secretRef: + description: The Secret to select from + 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 + optional: + description: Specify whether the Secret must + be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + image: + description: |- + Container image name. + More info: https://kubernetes.io/docs/concepts/containers/images + This field is optional to allow higher level config management to default or override + container images in workload controllers like Deployments and StatefulSets. + type: string + imagePullPolicy: + description: |- + Image pull policy. + One of Always, Never, IfNotPresent. + Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/containers/images#updating-images + type: string + lifecycle: + description: |- + Actions that the management system should take in response to container lifecycle events. + Cannot be updated. + properties: + postStart: + description: |- + PostStart is called immediately after a container is created. If the handler fails, + the container is terminated and restarted according to its restart policy. + Other management of the container blocks until the hook completes. + More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the + request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP + server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + sleep: + description: Sleep represents the duration that + the container should sleep before being terminated. + properties: + seconds: + description: Seconds is the number of seconds + to sleep. + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + description: |- + Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept + for the backward compatibility. There are no validation of this field and + lifecycle hooks will fail in runtime when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + description: |- + PreStop is called immediately before a container is terminated due to an + API request or management event such as liveness/startup probe failure, + preemption, resource contention, etc. The handler is not called if the + container crashes or exits. The Pod's termination grace period countdown begins before the + PreStop hook is executed. Regardless of the outcome of the handler, the + container will eventually terminate within the Pod's termination grace + period (unless delayed by finalizers). Other management of the container blocks until the hook completes + or until the termination grace period is reached. + More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the + request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP + server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + sleep: + description: Sleep represents the duration that + the container should sleep before being terminated. + properties: + seconds: + description: Seconds is the number of seconds + to sleep. + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + description: |- + Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept + for the backward compatibility. There are no validation of this field and + lifecycle hooks will fail in runtime when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + description: |- + Periodic probe of container liveness. + Container will be restarted if the probe fails. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving + a GRPC port. + properties: + port: + description: Port number of the gRPC service. + Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + name: + description: |- + Name of the container specified as a DNS_LABEL. + Each container in a pod must have a unique name (DNS_LABEL). + Cannot be updated. + type: string + ports: + description: |- + List of ports to expose from the container. Not specifying a port here + DOES NOT prevent that port from being exposed. Any port which is + listening on the default "0.0.0.0" address inside a container will be + accessible from the network. + Modifying this array with strategic merge patch may corrupt the data. + For more information See https://github.com/kubernetes/kubernetes/issues/108255. + Cannot be updated. + items: + description: ContainerPort represents a network port + in a single container. + properties: + containerPort: + description: |- + Number of port to expose on the pod's IP address. + This must be a valid port number, 0 < x < 65536. + format: int32 + type: integer + hostIP: + description: What host IP to bind the external + port to. + type: string + hostPort: + description: |- + Number of port to expose on the host. + If specified, this must be a valid port number, 0 < x < 65536. + If HostNetwork is specified, this must match ContainerPort. + Most containers do not need this. + format: int32 + type: integer + name: + description: |- + If specified, this must be an IANA_SVC_NAME and unique within the pod. Each + named port in a pod must have a unique name. Name for the port that can be + referred to by services. + type: string + protocol: + default: TCP + description: |- + Protocol for port. Must be UDP, TCP, or SCTP. + Defaults to "TCP". + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + description: |- + Periodic probe of container service readiness. + Container will be removed from service endpoints if the probe fails. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving + a GRPC port. + properties: + port: + description: Port number of the gRPC service. + Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + resizePolicy: + description: Resources resize policy for the container. + items: + description: ContainerResizePolicy represents resource + resize policy for the container. + properties: + resourceName: + description: |- + Name of the resource to which this resource resize policy applies. + Supported values: cpu, memory. + type: string + restartPolicy: + description: |- + Restart policy to apply when specified resource is resized. + If not specified, it defaults to NotRequired. + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + description: |- + Compute Resources required by this container. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + properties: + claims: + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + + + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + + + This field is immutable. It can only be set for containers. + items: + description: ResourceClaim references one entry + in PodSpec.ResourceClaims. + properties: + name: + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + restartPolicy: + description: |- + RestartPolicy defines the restart behavior of individual containers in a pod. + This field may only be set for init containers, and the only allowed value is "Always". + For non-init containers or when this field is not specified, + the restart behavior is defined by the Pod's restart policy and the container type. + Setting the RestartPolicy as "Always" for the init container will have the following effect: + this init container will be continually restarted on + exit until all regular containers have terminated. Once all regular + containers have completed, all init containers with restartPolicy "Always" + will be shut down. This lifecycle differs from normal init containers and + is often referred to as a "sidecar" container. Although this init + container still starts in the init container sequence, it does not wait + for the container to complete before proceeding to the next init + container. Instead, the next init container starts immediately after this + init container is started, or after any startupProbe has successfully + completed. + type: string + securityContext: + description: |- + SecurityContext defines the security options the container should be run with. + If set, the fields of SecurityContext override the equivalent fields of PodSecurityContext. + More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ + properties: + allowPrivilegeEscalation: + description: |- + AllowPrivilegeEscalation controls whether a process can gain more + privileges than its parent process. This bool directly controls if + the no_new_privs flag will be set on the container process. + AllowPrivilegeEscalation is true always when the container is: + 1) run as Privileged + 2) has CAP_SYS_ADMIN + Note that this field cannot be set when spec.os.name is windows. + type: boolean + capabilities: + description: |- + The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the container runtime. + Note that this field cannot be set when spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + type: object + privileged: + description: |- + Run container in privileged mode. + Processes in privileged containers are essentially equivalent to root on the host. + Defaults to false. + Note that this field cannot be set when spec.os.name is windows. + type: boolean + procMount: + description: |- + procMount denotes the type of proc mount to use for the containers. + The default is DefaultProcMount which uses the container runtime defaults for + readonly paths and masked paths. + This requires the ProcMountType feature flag to be enabled. + Note that this field cannot be set when spec.os.name is windows. + type: string + readOnlyRootFilesystem: + description: |- + Whether this container has a read-only root filesystem. + Default is false. + Note that this field cannot be set when spec.os.name is windows. + type: boolean + runAsGroup: + description: |- + The GID to run the entrypoint of the container process. + Uses runtime default if unset. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: |- + Indicates that the container must run as a non-root user. + If true, the Kubelet will validate the image at runtime to ensure that it + does not run as UID 0 (root) and fail to start the container if it does. + If unset or false, no such validation will be performed. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: |- + The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: |- + The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random SELinux context for each + container. May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that + applies to the container. + type: string + role: + description: Role is a SELinux role label that + applies to the container. + type: string + type: + description: Type is a SELinux type label that + applies to the container. + type: string + user: + description: User is a SELinux user label that + applies to the container. + type: string + type: object + seccompProfile: + description: |- + The seccomp options to use by this container. If seccomp options are + provided at both the pod & container level, the container options + override the pod options. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile defined in a file on the node should be used. + The profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be set for any other type. + type: string + type: + description: |- + type indicates which kind of seccomp profile will be applied. + Valid options are: + + + Localhost - a profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile should be used. + Unconfined - no profile should be applied. + type: string + required: + - type + type: object + windowsOptions: + description: |- + The Windows specific settings applied to all containers. + If unspecified, the options from the PodSecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: |- + GMSACredentialSpec is where the GMSA admission webhook + (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the + GMSA credential spec named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name + of the GMSA credential spec to use. + type: string + hostProcess: + description: |- + HostProcess determines if a container should be run as a 'Host Process' container. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: |- + The UserName in Windows to run the entrypoint of the container process. + Defaults to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: string + type: object + type: object + startupProbe: + description: |- + StartupProbe indicates that the Pod has successfully initialized. + If specified, no other probes are executed until this completes successfully. + If this probe fails, the Pod will be restarted, just as if the livenessProbe failed. + This can be used to provide different probe parameters at the beginning of a Pod's lifecycle, + when it might take a long time to load data or warm a cache, than during steady-state operation. + This cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving + a GRPC port. + properties: + port: + description: Port number of the gRPC service. + Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + stdin: + description: |- + Whether this container should allocate a buffer for stdin in the container runtime. If this + is not set, reads from stdin in the container will always result in EOF. + Default is false. + type: boolean + stdinOnce: + description: |- + Whether the container runtime should close the stdin channel after it has been opened by + a single attach. When stdin is true the stdin stream will remain open across multiple attach + sessions. If stdinOnce is set to true, stdin is opened on container start, is empty until the + first client attaches to stdin, and then remains open and accepts data until the client disconnects, + at which time stdin is closed and remains closed until the container is restarted. If this + flag is false, a container processes that reads from stdin will never receive an EOF. + Default is false + type: boolean + terminationMessagePath: + description: |- + Optional: Path at which the file to which the container's termination message + will be written is mounted into the container's filesystem. + Message written is intended to be brief final status, such as an assertion failure message. + Will be truncated by the node if greater than 4096 bytes. The total message length across + all containers will be limited to 12kb. + Defaults to /dev/termination-log. + Cannot be updated. + type: string + terminationMessagePolicy: + description: |- + Indicate how the termination message should be populated. File will use the contents of + terminationMessagePath to populate the container status message on both success and failure. + FallbackToLogsOnError will use the last chunk of container log output if the termination + message file is empty and the container exited with an error. + The log output is limited to 2048 bytes or 80 lines, whichever is smaller. + Defaults to File. + Cannot be updated. + type: string + tty: + description: |- + Whether this container should allocate a TTY for itself, also requires 'stdin' to be true. + Default is false. + type: boolean + volumeDevices: + description: volumeDevices is the list of block devices + to be used by the container. + items: + description: volumeDevice describes a mapping of a + raw block device within a container. + properties: + devicePath: + description: devicePath is the path inside of + the container that the device will be mapped + to. + type: string + name: + description: name must match the name of a persistentVolumeClaim + in the pod + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + description: |- + Pod volumes to mount into the container's filesystem. + Cannot be updated. + items: + description: VolumeMount describes a mounting of a + Volume within a container. + properties: + mountPath: + description: |- + Path within the container at which the volume should be mounted. Must + not contain ':'. + type: string + mountPropagation: + description: |- + mountPropagation determines how mounts are propagated from the host + to container and the other way around. + When not set, MountPropagationNone is used. + This field is beta in 1.10. + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: |- + Mounted read-only if true, read-write otherwise (false or unspecified). + Defaults to false. + type: boolean + subPath: + description: |- + Path within the volume from which the container's volume should be mounted. + Defaults to "" (volume's root). + type: string + subPathExpr: + description: |- + Expanded path within the volume from which the container's volume should be mounted. + Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment. + Defaults to "" (volume's root). + SubPathExpr and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + description: |- + Container's working directory. + If not specified, the container runtime's default will be used, which + might be configured in the container image. + Cannot be updated. + type: string + required: + - name + type: object + type: array + dnsConfig: + description: |- + Specifies the DNS parameters of a pod. + Parameters specified here will be merged to the generated DNS + configuration based on DNSPolicy. + properties: + nameservers: + description: |- + A list of DNS name server IP addresses. + This will be appended to the base nameservers generated from DNSPolicy. + Duplicated nameservers will be removed. + items: + type: string + type: array + options: + description: |- + A list of DNS resolver options. + This will be merged with the base options generated from DNSPolicy. + Duplicated entries will be removed. Resolution options given in Options + will override those that appear in the base DNSPolicy. + items: + description: PodDNSConfigOption defines DNS resolver + options of a pod. + properties: + name: + description: Required. + type: string + value: + type: string + type: object + type: array + searches: + description: |- + A list of DNS search domains for host-name lookup. + This will be appended to the base search paths generated from DNSPolicy. + Duplicated search paths will be removed. + items: + type: string + type: array + type: object + dnsPolicy: + description: |- + Set DNS policy for the pod. + Defaults to "ClusterFirst". + Valid values are 'ClusterFirstWithHostNet', 'ClusterFirst', 'Default' or 'None'. + DNS parameters given in DNSConfig will be merged with the policy selected with DNSPolicy. + To have DNS options set along with hostNetwork, you have to specify DNS policy + explicitly to 'ClusterFirstWithHostNet'. + type: string + enableServiceLinks: + description: |- + EnableServiceLinks indicates whether information about services should be injected into pod's + environment variables, matching the syntax of Docker links. + Optional: Defaults to true. + type: boolean + ephemeralContainers: + description: |- + List of ephemeral containers run in this pod. Ephemeral containers may be run in an existing + pod to perform user-initiated actions such as debugging. This list cannot be specified when + creating a pod, and it cannot be modified by updating the pod spec. In order to add an + ephemeral container to an existing pod, use the pod's ephemeralcontainers subresource. + items: + description: |- + An EphemeralContainer is a temporary container that you may add to an existing Pod for + user-initiated activities such as debugging. Ephemeral containers have no resource or + scheduling guarantees, and they will not be restarted when they exit or when a Pod is + removed or restarted. The kubelet may evict a Pod if an ephemeral container causes the + Pod to exceed its resource allocation. + + + To add an ephemeral container, use the ephemeralcontainers subresource of an existing + Pod. Ephemeral containers may not be removed or restarted. + properties: + args: + description: |- + Arguments to the entrypoint. + The image's CMD is used if this is not provided. + Variable references $(VAR_NAME) are expanded using the container's environment. If a variable + cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will + produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless + of whether the variable exists or not. Cannot be updated. + More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell + items: + type: string + type: array + command: + description: |- + Entrypoint array. Not executed within a shell. + The image's ENTRYPOINT is used if this is not provided. + Variable references $(VAR_NAME) are expanded using the container's environment. If a variable + cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will + produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless + of whether the variable exists or not. Cannot be updated. + More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell + items: + type: string + type: array + env: + description: |- + List of environment variables to set in the container. + Cannot be updated. + items: + description: EnvVar represents an environment variable + present in a Container. + properties: + name: + description: Name of the environment variable. + Must be a C_IDENTIFIER. + type: string + value: + description: |- + Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in the container and + any service environment variables. If a variable cannot be resolved, + the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless of whether the variable + exists or not. + Defaults to "". + type: string + valueFrom: + description: Source for the environment variable's + value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the + FieldPath is written in terms of, defaults + to "v1". + type: string + fieldPath: + description: Path of the field to select + in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required + for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format + of the exposed resources, defaults to + "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in + the pod's namespace + properties: + key: + description: The key of the secret to + select from. Must be a valid secret + key. + type: string + 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 + optional: + description: Specify whether the Secret + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + envFrom: + description: |- + List of sources to populate environment variables in the container. + The keys defined within a source must be a C_IDENTIFIER. All invalid keys + will be reported as an event when the container is starting. When a key exists in multiple + sources, the value associated with the last source will take precedence. + Values defined by an Env with a duplicate key will take precedence. + Cannot be updated. + items: + description: EnvFromSource represents the source of + a set of ConfigMaps + properties: + configMapRef: + description: The ConfigMap to select from + 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 + optional: + description: Specify whether the ConfigMap + must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + description: An optional identifier to prepend + to each key in the ConfigMap. Must be a C_IDENTIFIER. + type: string + secretRef: + description: The Secret to select from + 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 + optional: + description: Specify whether the Secret must + be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + image: + description: |- + Container image name. + More info: https://kubernetes.io/docs/concepts/containers/images + type: string + imagePullPolicy: + description: |- + Image pull policy. + One of Always, Never, IfNotPresent. + Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/containers/images#updating-images + type: string + lifecycle: + description: Lifecycle is not allowed for ephemeral + containers. + properties: + postStart: + description: |- + PostStart is called immediately after a container is created. If the handler fails, + the container is terminated and restarted according to its restart policy. + Other management of the container blocks until the hook completes. + More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the + request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP + server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + sleep: + description: Sleep represents the duration that + the container should sleep before being terminated. + properties: + seconds: + description: Seconds is the number of seconds + to sleep. + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + description: |- + Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept + for the backward compatibility. There are no validation of this field and + lifecycle hooks will fail in runtime when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + description: |- + PreStop is called immediately before a container is terminated due to an + API request or management event such as liveness/startup probe failure, + preemption, resource contention, etc. The handler is not called if the + container crashes or exits. The Pod's termination grace period countdown begins before the + PreStop hook is executed. Regardless of the outcome of the handler, the + container will eventually terminate within the Pod's termination grace + period (unless delayed by finalizers). Other management of the container blocks until the hook completes + or until the termination grace period is reached. + More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the + request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP + server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + sleep: + description: Sleep represents the duration that + the container should sleep before being terminated. + properties: + seconds: + description: Seconds is the number of seconds + to sleep. + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + description: |- + Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept + for the backward compatibility. There are no validation of this field and + lifecycle hooks will fail in runtime when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + description: Probes are not allowed for ephemeral containers. + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving + a GRPC port. + properties: + port: + description: Port number of the gRPC service. + Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + name: + description: |- + Name of the ephemeral container specified as a DNS_LABEL. + This name must be unique among all containers, init containers and ephemeral containers. + type: string + ports: + description: Ports are not allowed for ephemeral containers. + items: + description: ContainerPort represents a network port + in a single container. + properties: + containerPort: + description: |- + Number of port to expose on the pod's IP address. + This must be a valid port number, 0 < x < 65536. + format: int32 + type: integer + hostIP: + description: What host IP to bind the external + port to. + type: string + hostPort: + description: |- + Number of port to expose on the host. + If specified, this must be a valid port number, 0 < x < 65536. + If HostNetwork is specified, this must match ContainerPort. + Most containers do not need this. + format: int32 + type: integer + name: + description: |- + If specified, this must be an IANA_SVC_NAME and unique within the pod. Each + named port in a pod must have a unique name. Name for the port that can be + referred to by services. + type: string + protocol: + default: TCP + description: |- + Protocol for port. Must be UDP, TCP, or SCTP. + Defaults to "TCP". + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + description: Probes are not allowed for ephemeral containers. + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving + a GRPC port. + properties: + port: + description: Port number of the gRPC service. + Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + resizePolicy: + description: Resources resize policy for the container. + items: + description: ContainerResizePolicy represents resource + resize policy for the container. + properties: + resourceName: + description: |- + Name of the resource to which this resource resize policy applies. + Supported values: cpu, memory. + type: string + restartPolicy: + description: |- + Restart policy to apply when specified resource is resized. + If not specified, it defaults to NotRequired. + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + description: |- + Resources are not allowed for ephemeral containers. Ephemeral containers use spare resources + already allocated to the pod. + properties: + claims: + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + + + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + + + This field is immutable. It can only be set for containers. + items: + description: ResourceClaim references one entry + in PodSpec.ResourceClaims. + properties: + name: + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + restartPolicy: + description: |- + Restart policy for the container to manage the restart behavior of each + container within a pod. + This may only be set for init containers. You cannot set this field on + ephemeral containers. + type: string + securityContext: + description: |- + Optional: SecurityContext defines the security options the ephemeral container should be run with. + If set, the fields of SecurityContext override the equivalent fields of PodSecurityContext. + properties: + allowPrivilegeEscalation: + description: |- + AllowPrivilegeEscalation controls whether a process can gain more + privileges than its parent process. This bool directly controls if + the no_new_privs flag will be set on the container process. + AllowPrivilegeEscalation is true always when the container is: + 1) run as Privileged + 2) has CAP_SYS_ADMIN + Note that this field cannot be set when spec.os.name is windows. + type: boolean + capabilities: + description: |- + The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the container runtime. + Note that this field cannot be set when spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + type: object + privileged: + description: |- + Run container in privileged mode. + Processes in privileged containers are essentially equivalent to root on the host. + Defaults to false. + Note that this field cannot be set when spec.os.name is windows. + type: boolean + procMount: + description: |- + procMount denotes the type of proc mount to use for the containers. + The default is DefaultProcMount which uses the container runtime defaults for + readonly paths and masked paths. + This requires the ProcMountType feature flag to be enabled. + Note that this field cannot be set when spec.os.name is windows. + type: string + readOnlyRootFilesystem: + description: |- + Whether this container has a read-only root filesystem. + Default is false. + Note that this field cannot be set when spec.os.name is windows. + type: boolean + runAsGroup: + description: |- + The GID to run the entrypoint of the container process. + Uses runtime default if unset. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: |- + Indicates that the container must run as a non-root user. + If true, the Kubelet will validate the image at runtime to ensure that it + does not run as UID 0 (root) and fail to start the container if it does. + If unset or false, no such validation will be performed. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: |- + The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: |- + The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random SELinux context for each + container. May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that + applies to the container. + type: string + role: + description: Role is a SELinux role label that + applies to the container. + type: string + type: + description: Type is a SELinux type label that + applies to the container. + type: string + user: + description: User is a SELinux user label that + applies to the container. + type: string + type: object + seccompProfile: + description: |- + The seccomp options to use by this container. If seccomp options are + provided at both the pod & container level, the container options + override the pod options. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile defined in a file on the node should be used. + The profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be set for any other type. + type: string + type: + description: |- + type indicates which kind of seccomp profile will be applied. + Valid options are: + + + Localhost - a profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile should be used. + Unconfined - no profile should be applied. + type: string + required: + - type + type: object + windowsOptions: + description: |- + The Windows specific settings applied to all containers. + If unspecified, the options from the PodSecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: |- + GMSACredentialSpec is where the GMSA admission webhook + (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the + GMSA credential spec named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name + of the GMSA credential spec to use. + type: string + hostProcess: + description: |- + HostProcess determines if a container should be run as a 'Host Process' container. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: |- + The UserName in Windows to run the entrypoint of the container process. + Defaults to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: string + type: object + type: object + startupProbe: + description: Probes are not allowed for ephemeral containers. + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving + a GRPC port. + properties: + port: + description: Port number of the gRPC service. + Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + stdin: + description: |- + Whether this container should allocate a buffer for stdin in the container runtime. If this + is not set, reads from stdin in the container will always result in EOF. + Default is false. + type: boolean + stdinOnce: + description: |- + Whether the container runtime should close the stdin channel after it has been opened by + a single attach. When stdin is true the stdin stream will remain open across multiple attach + sessions. If stdinOnce is set to true, stdin is opened on container start, is empty until the + first client attaches to stdin, and then remains open and accepts data until the client disconnects, + at which time stdin is closed and remains closed until the container is restarted. If this + flag is false, a container processes that reads from stdin will never receive an EOF. + Default is false + type: boolean + targetContainerName: + description: |- + If set, the name of the container from PodSpec that this ephemeral container targets. + The ephemeral container will be run in the namespaces (IPC, PID, etc) of this container. + If not set then the ephemeral container uses the namespaces configured in the Pod spec. + + + The container runtime must implement support for this feature. If the runtime does not + support namespace targeting then the result of setting this field is undefined. + type: string + terminationMessagePath: + description: |- + Optional: Path at which the file to which the container's termination message + will be written is mounted into the container's filesystem. + Message written is intended to be brief final status, such as an assertion failure message. + Will be truncated by the node if greater than 4096 bytes. The total message length across + all containers will be limited to 12kb. + Defaults to /dev/termination-log. + Cannot be updated. + type: string + terminationMessagePolicy: + description: |- + Indicate how the termination message should be populated. File will use the contents of + terminationMessagePath to populate the container status message on both success and failure. + FallbackToLogsOnError will use the last chunk of container log output if the termination + message file is empty and the container exited with an error. + The log output is limited to 2048 bytes or 80 lines, whichever is smaller. + Defaults to File. + Cannot be updated. + type: string + tty: + description: |- + Whether this container should allocate a TTY for itself, also requires 'stdin' to be true. + Default is false. + type: boolean + volumeDevices: + description: volumeDevices is the list of block devices + to be used by the container. + items: + description: volumeDevice describes a mapping of a + raw block device within a container. + properties: + devicePath: + description: devicePath is the path inside of + the container that the device will be mapped + to. + type: string + name: + description: name must match the name of a persistentVolumeClaim + in the pod + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + description: |- + Pod volumes to mount into the container's filesystem. Subpath mounts are not allowed for ephemeral containers. + Cannot be updated. + items: + description: VolumeMount describes a mounting of a + Volume within a container. + properties: + mountPath: + description: |- + Path within the container at which the volume should be mounted. Must + not contain ':'. + type: string + mountPropagation: + description: |- + mountPropagation determines how mounts are propagated from the host + to container and the other way around. + When not set, MountPropagationNone is used. + This field is beta in 1.10. + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: |- + Mounted read-only if true, read-write otherwise (false or unspecified). + Defaults to false. + type: boolean + subPath: + description: |- + Path within the volume from which the container's volume should be mounted. + Defaults to "" (volume's root). + type: string + subPathExpr: + description: |- + Expanded path within the volume from which the container's volume should be mounted. + Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment. + Defaults to "" (volume's root). + SubPathExpr and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + description: |- + Container's working directory. + If not specified, the container runtime's default will be used, which + might be configured in the container image. + Cannot be updated. + type: string + required: + - name + type: object + type: array + hostAliases: + description: |- + HostAliases is an optional list of hosts and IPs that will be injected into the pod's hosts + file if specified. This is only valid for non-hostNetwork pods. + items: + description: |- + HostAlias holds the mapping between IP and hostnames that will be injected as an entry in the + pod's hosts file. + properties: + hostnames: + description: Hostnames for the above IP address. + items: + type: string + type: array + ip: + description: IP address of the host file entry. + type: string + type: object + type: array + hostIPC: + description: |- + Use the host's ipc namespace. + Optional: Default to false. + type: boolean + hostNetwork: + description: |- + Host networking requested for this pod. Use the host's network namespace. + If this option is set, the ports that will be used must be specified. + Default to false. + type: boolean + hostPID: + description: |- + Use the host's pid namespace. + Optional: Default to false. + type: boolean + hostUsers: + description: |- + Use the host's user namespace. + Optional: Default to true. + If set to true or not present, the pod will be run in the host user namespace, useful + for when the pod needs a feature only available to the host user namespace, such as + loading a kernel module with CAP_SYS_MODULE. + When set to false, a new userns is created for the pod. Setting false is useful for + mitigating container breakout vulnerabilities even allowing users to run their + containers as root without actually having root privileges on the host. + This field is alpha-level and is only honored by servers that enable the UserNamespacesSupport feature. + type: boolean + hostname: + description: |- + Specifies the hostname of the Pod + If not specified, the pod's hostname will be set to a system-defined value. + type: string + imagePullSecrets: + description: |- + ImagePullSecrets is an optional list of references to secrets in the same namespace to use for pulling any of the images used by this PodSpec. + If specified, these secrets will be passed to individual puller implementations for them to use. + More info: https://kubernetes.io/docs/concepts/containers/images#specifying-imagepullsecrets-on-a-pod + items: + 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? + type: string + type: object + x-kubernetes-map-type: atomic + type: array + initContainers: + description: |- + List of initialization containers belonging to the pod. + Init containers are executed in order prior to containers being started. If any + init container fails, the pod is considered to have failed and is handled according + to its restartPolicy. The name for an init container or normal container must be + unique among all containers. + Init containers may not have Lifecycle actions, Readiness probes, Liveness probes, or Startup probes. + The resourceRequirements of an init container are taken into account during scheduling + by finding the highest request/limit for each resource type, and then using the max of + of that value or the sum of the normal containers. Limits are applied to init containers + in a similar fashion. + Init containers cannot currently be added or removed. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/init-containers/ + items: + description: A single application container that you want + to run within a pod. + properties: + args: + description: |- + Arguments to the entrypoint. + The container image's CMD is used if this is not provided. + Variable references $(VAR_NAME) are expanded using the container's environment. If a variable + cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will + produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless + of whether the variable exists or not. Cannot be updated. + More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell + items: + type: string + type: array + command: + description: |- + Entrypoint array. Not executed within a shell. + The container image's ENTRYPOINT is used if this is not provided. + Variable references $(VAR_NAME) are expanded using the container's environment. If a variable + cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will + produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless + of whether the variable exists or not. Cannot be updated. + More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell + items: + type: string + type: array + env: + description: |- + List of environment variables to set in the container. + Cannot be updated. + items: + description: EnvVar represents an environment variable + present in a Container. + properties: + name: + description: Name of the environment variable. + Must be a C_IDENTIFIER. + type: string + value: + description: |- + Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in the container and + any service environment variables. If a variable cannot be resolved, + the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless of whether the variable + exists or not. + Defaults to "". + type: string + valueFrom: + description: Source for the environment variable's + value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the + FieldPath is written in terms of, defaults + to "v1". + type: string + fieldPath: + description: Path of the field to select + in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required + for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format + of the exposed resources, defaults to + "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in + the pod's namespace + properties: + key: + description: The key of the secret to + select from. Must be a valid secret + key. + type: string + 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 + optional: + description: Specify whether the Secret + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + envFrom: + description: |- + List of sources to populate environment variables in the container. + The keys defined within a source must be a C_IDENTIFIER. All invalid keys + will be reported as an event when the container is starting. When a key exists in multiple + sources, the value associated with the last source will take precedence. + Values defined by an Env with a duplicate key will take precedence. + Cannot be updated. + items: + description: EnvFromSource represents the source of + a set of ConfigMaps + properties: + configMapRef: + description: The ConfigMap to select from + 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 + optional: + description: Specify whether the ConfigMap + must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + description: An optional identifier to prepend + to each key in the ConfigMap. Must be a C_IDENTIFIER. + type: string + secretRef: + description: The Secret to select from + 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 + optional: + description: Specify whether the Secret must + be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + image: + description: |- + Container image name. + More info: https://kubernetes.io/docs/concepts/containers/images + This field is optional to allow higher level config management to default or override + container images in workload controllers like Deployments and StatefulSets. + type: string + imagePullPolicy: + description: |- + Image pull policy. + One of Always, Never, IfNotPresent. + Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/containers/images#updating-images + type: string + lifecycle: + description: |- + Actions that the management system should take in response to container lifecycle events. + Cannot be updated. + properties: + postStart: + description: |- + PostStart is called immediately after a container is created. If the handler fails, + the container is terminated and restarted according to its restart policy. + Other management of the container blocks until the hook completes. + More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the + request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP + server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + sleep: + description: Sleep represents the duration that + the container should sleep before being terminated. + properties: + seconds: + description: Seconds is the number of seconds + to sleep. + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + description: |- + Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept + for the backward compatibility. There are no validation of this field and + lifecycle hooks will fail in runtime when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + description: |- + PreStop is called immediately before a container is terminated due to an + API request or management event such as liveness/startup probe failure, + preemption, resource contention, etc. The handler is not called if the + container crashes or exits. The Pod's termination grace period countdown begins before the + PreStop hook is executed. Regardless of the outcome of the handler, the + container will eventually terminate within the Pod's termination grace + period (unless delayed by finalizers). Other management of the container blocks until the hook completes + or until the termination grace period is reached. + More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the + request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP + server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + sleep: + description: Sleep represents the duration that + the container should sleep before being terminated. + properties: + seconds: + description: Seconds is the number of seconds + to sleep. + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + description: |- + Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept + for the backward compatibility. There are no validation of this field and + lifecycle hooks will fail in runtime when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + description: |- + Periodic probe of container liveness. + Container will be restarted if the probe fails. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving + a GRPC port. + properties: + port: + description: Port number of the gRPC service. + Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + name: + description: |- + Name of the container specified as a DNS_LABEL. + Each container in a pod must have a unique name (DNS_LABEL). + Cannot be updated. + type: string + ports: + description: |- + List of ports to expose from the container. Not specifying a port here + DOES NOT prevent that port from being exposed. Any port which is + listening on the default "0.0.0.0" address inside a container will be + accessible from the network. + Modifying this array with strategic merge patch may corrupt the data. + For more information See https://github.com/kubernetes/kubernetes/issues/108255. + Cannot be updated. + items: + description: ContainerPort represents a network port + in a single container. + properties: + containerPort: + description: |- + Number of port to expose on the pod's IP address. + This must be a valid port number, 0 < x < 65536. + format: int32 + type: integer + hostIP: + description: What host IP to bind the external + port to. + type: string + hostPort: + description: |- + Number of port to expose on the host. + If specified, this must be a valid port number, 0 < x < 65536. + If HostNetwork is specified, this must match ContainerPort. + Most containers do not need this. + format: int32 + type: integer + name: + description: |- + If specified, this must be an IANA_SVC_NAME and unique within the pod. Each + named port in a pod must have a unique name. Name for the port that can be + referred to by services. + type: string + protocol: + default: TCP + description: |- + Protocol for port. Must be UDP, TCP, or SCTP. + Defaults to "TCP". + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + description: |- + Periodic probe of container service readiness. + Container will be removed from service endpoints if the probe fails. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving + a GRPC port. + properties: + port: + description: Port number of the gRPC service. + Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + resizePolicy: + description: Resources resize policy for the container. + items: + description: ContainerResizePolicy represents resource + resize policy for the container. + properties: + resourceName: + description: |- + Name of the resource to which this resource resize policy applies. + Supported values: cpu, memory. + type: string + restartPolicy: + description: |- + Restart policy to apply when specified resource is resized. + If not specified, it defaults to NotRequired. + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + description: |- + Compute Resources required by this container. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + properties: + claims: + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + + + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + + + This field is immutable. It can only be set for containers. + items: + description: ResourceClaim references one entry + in PodSpec.ResourceClaims. + properties: + name: + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + restartPolicy: + description: |- + RestartPolicy defines the restart behavior of individual containers in a pod. + This field may only be set for init containers, and the only allowed value is "Always". + For non-init containers or when this field is not specified, + the restart behavior is defined by the Pod's restart policy and the container type. + Setting the RestartPolicy as "Always" for the init container will have the following effect: + this init container will be continually restarted on + exit until all regular containers have terminated. Once all regular + containers have completed, all init containers with restartPolicy "Always" + will be shut down. This lifecycle differs from normal init containers and + is often referred to as a "sidecar" container. Although this init + container still starts in the init container sequence, it does not wait + for the container to complete before proceeding to the next init + container. Instead, the next init container starts immediately after this + init container is started, or after any startupProbe has successfully + completed. + type: string + securityContext: + description: |- + SecurityContext defines the security options the container should be run with. + If set, the fields of SecurityContext override the equivalent fields of PodSecurityContext. + More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ + properties: + allowPrivilegeEscalation: + description: |- + AllowPrivilegeEscalation controls whether a process can gain more + privileges than its parent process. This bool directly controls if + the no_new_privs flag will be set on the container process. + AllowPrivilegeEscalation is true always when the container is: + 1) run as Privileged + 2) has CAP_SYS_ADMIN + Note that this field cannot be set when spec.os.name is windows. + type: boolean + capabilities: + description: |- + The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the container runtime. + Note that this field cannot be set when spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + type: object + privileged: + description: |- + Run container in privileged mode. + Processes in privileged containers are essentially equivalent to root on the host. + Defaults to false. + Note that this field cannot be set when spec.os.name is windows. + type: boolean + procMount: + description: |- + procMount denotes the type of proc mount to use for the containers. + The default is DefaultProcMount which uses the container runtime defaults for + readonly paths and masked paths. + This requires the ProcMountType feature flag to be enabled. + Note that this field cannot be set when spec.os.name is windows. + type: string + readOnlyRootFilesystem: + description: |- + Whether this container has a read-only root filesystem. + Default is false. + Note that this field cannot be set when spec.os.name is windows. + type: boolean + runAsGroup: + description: |- + The GID to run the entrypoint of the container process. + Uses runtime default if unset. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: |- + Indicates that the container must run as a non-root user. + If true, the Kubelet will validate the image at runtime to ensure that it + does not run as UID 0 (root) and fail to start the container if it does. + If unset or false, no such validation will be performed. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: |- + The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: |- + The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random SELinux context for each + container. May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that + applies to the container. + type: string + role: + description: Role is a SELinux role label that + applies to the container. + type: string + type: + description: Type is a SELinux type label that + applies to the container. + type: string + user: + description: User is a SELinux user label that + applies to the container. + type: string + type: object + seccompProfile: + description: |- + The seccomp options to use by this container. If seccomp options are + provided at both the pod & container level, the container options + override the pod options. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile defined in a file on the node should be used. + The profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be set for any other type. + type: string + type: + description: |- + type indicates which kind of seccomp profile will be applied. + Valid options are: + + + Localhost - a profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile should be used. + Unconfined - no profile should be applied. + type: string + required: + - type + type: object + windowsOptions: + description: |- + The Windows specific settings applied to all containers. + If unspecified, the options from the PodSecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: |- + GMSACredentialSpec is where the GMSA admission webhook + (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the + GMSA credential spec named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name + of the GMSA credential spec to use. + type: string + hostProcess: + description: |- + HostProcess determines if a container should be run as a 'Host Process' container. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: |- + The UserName in Windows to run the entrypoint of the container process. + Defaults to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: string + type: object + type: object + startupProbe: + description: |- + StartupProbe indicates that the Pod has successfully initialized. + If specified, no other probes are executed until this completes successfully. + If this probe fails, the Pod will be restarted, just as if the livenessProbe failed. + This can be used to provide different probe parameters at the beginning of a Pod's lifecycle, + when it might take a long time to load data or warm a cache, than during steady-state operation. + This cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving + a GRPC port. + properties: + port: + description: Port number of the gRPC service. + Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + stdin: + description: |- + Whether this container should allocate a buffer for stdin in the container runtime. If this + is not set, reads from stdin in the container will always result in EOF. + Default is false. + type: boolean + stdinOnce: + description: |- + Whether the container runtime should close the stdin channel after it has been opened by + a single attach. When stdin is true the stdin stream will remain open across multiple attach + sessions. If stdinOnce is set to true, stdin is opened on container start, is empty until the + first client attaches to stdin, and then remains open and accepts data until the client disconnects, + at which time stdin is closed and remains closed until the container is restarted. If this + flag is false, a container processes that reads from stdin will never receive an EOF. + Default is false + type: boolean + terminationMessagePath: + description: |- + Optional: Path at which the file to which the container's termination message + will be written is mounted into the container's filesystem. + Message written is intended to be brief final status, such as an assertion failure message. + Will be truncated by the node if greater than 4096 bytes. The total message length across + all containers will be limited to 12kb. + Defaults to /dev/termination-log. + Cannot be updated. + type: string + terminationMessagePolicy: + description: |- + Indicate how the termination message should be populated. File will use the contents of + terminationMessagePath to populate the container status message on both success and failure. + FallbackToLogsOnError will use the last chunk of container log output if the termination + message file is empty and the container exited with an error. + The log output is limited to 2048 bytes or 80 lines, whichever is smaller. + Defaults to File. + Cannot be updated. + type: string + tty: + description: |- + Whether this container should allocate a TTY for itself, also requires 'stdin' to be true. + Default is false. + type: boolean + volumeDevices: + description: volumeDevices is the list of block devices + to be used by the container. + items: + description: volumeDevice describes a mapping of a + raw block device within a container. + properties: + devicePath: + description: devicePath is the path inside of + the container that the device will be mapped + to. + type: string + name: + description: name must match the name of a persistentVolumeClaim + in the pod + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + description: |- + Pod volumes to mount into the container's filesystem. + Cannot be updated. + items: + description: VolumeMount describes a mounting of a + Volume within a container. + properties: + mountPath: + description: |- + Path within the container at which the volume should be mounted. Must + not contain ':'. + type: string + mountPropagation: + description: |- + mountPropagation determines how mounts are propagated from the host + to container and the other way around. + When not set, MountPropagationNone is used. + This field is beta in 1.10. + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: |- + Mounted read-only if true, read-write otherwise (false or unspecified). + Defaults to false. + type: boolean + subPath: + description: |- + Path within the volume from which the container's volume should be mounted. + Defaults to "" (volume's root). + type: string + subPathExpr: + description: |- + Expanded path within the volume from which the container's volume should be mounted. + Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment. + Defaults to "" (volume's root). + SubPathExpr and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + description: |- + Container's working directory. + If not specified, the container runtime's default will be used, which + might be configured in the container image. + Cannot be updated. + type: string + required: + - name + type: object + type: array + nodeName: + description: |- + NodeName is a request to schedule this pod onto a specific node. If it is non-empty, + the scheduler simply schedules this pod onto that node, assuming that it fits resource + requirements. + type: string + nodeSelector: + additionalProperties: + type: string + description: |- + NodeSelector is a selector which must be true for the pod to fit on a node. + Selector which must match a node's labels for the pod to be scheduled on that node. + More info: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ + type: object + x-kubernetes-map-type: atomic + os: + description: |- + Specifies the OS of the containers in the pod. + Some pod and container fields are restricted if this is set. + + + If the OS field is set to linux, the following fields must be unset: + -securityContext.windowsOptions + + + If the OS field is set to windows, following fields must be unset: + - spec.hostPID + - spec.hostIPC + - spec.hostUsers + - spec.securityContext.seLinuxOptions + - spec.securityContext.seccompProfile + - spec.securityContext.fsGroup + - spec.securityContext.fsGroupChangePolicy + - spec.securityContext.sysctls + - spec.shareProcessNamespace + - spec.securityContext.runAsUser + - spec.securityContext.runAsGroup + - spec.securityContext.supplementalGroups + - spec.containers[*].securityContext.seLinuxOptions + - spec.containers[*].securityContext.seccompProfile + - spec.containers[*].securityContext.capabilities + - spec.containers[*].securityContext.readOnlyRootFilesystem + - spec.containers[*].securityContext.privileged + - spec.containers[*].securityContext.allowPrivilegeEscalation + - spec.containers[*].securityContext.procMount + - spec.containers[*].securityContext.runAsUser + - spec.containers[*].securityContext.runAsGroup + properties: + name: + description: |- + Name is the name of the operating system. The currently supported values are linux and windows. + Additional value may be defined in future and can be one of: + https://github.com/opencontainers/runtime-spec/blob/master/config.md#platform-specific-configuration + Clients should expect to handle additional values and treat unrecognized values in this field as os: null + type: string + required: + - name + type: object + overhead: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Overhead represents the resource overhead associated with running a pod for a given RuntimeClass. + This field will be autopopulated at admission time by the RuntimeClass admission controller. If + the RuntimeClass admission controller is enabled, overhead must not be set in Pod create requests. + The RuntimeClass admission controller will reject Pod create requests which have the overhead already + set. If RuntimeClass is configured and selected in the PodSpec, Overhead will be set to the value + defined in the corresponding RuntimeClass, otherwise it will remain unset and treated as zero. + More info: https://git.k8s.io/enhancements/keps/sig-node/688-pod-overhead/README.md + type: object + preemptionPolicy: + description: |- + PreemptionPolicy is the Policy for preempting pods with lower priority. + One of Never, PreemptLowerPriority. + Defaults to PreemptLowerPriority if unset. + type: string + priority: + description: |- + The priority value. Various system components use this field to find the + priority of the pod. When Priority Admission Controller is enabled, it + prevents users from setting this field. The admission controller populates + this field from PriorityClassName. + The higher the value, the higher the priority. + format: int32 + type: integer + priorityClassName: + description: |- + If specified, indicates the pod's priority. "system-node-critical" and + "system-cluster-critical" are two special keywords which indicate the + highest priorities with the former being the highest priority. Any other + name must be defined by creating a PriorityClass object with that name. + If not specified, the pod priority will be default or zero if there is no + default. + type: string + readinessGates: + description: |- + If specified, all readiness gates will be evaluated for pod readiness. + A pod is ready when all its containers are ready AND + all conditions specified in the readiness gates have status equal to "True" + More info: https://git.k8s.io/enhancements/keps/sig-network/580-pod-readiness-gates + items: + description: PodReadinessGate contains the reference to + a pod condition + properties: + conditionType: + description: ConditionType refers to a condition in + the pod's condition list with matching type. + type: string + required: + - conditionType + type: object + type: array + resourceClaims: + description: |- + ResourceClaims defines which ResourceClaims must be allocated + and reserved before the Pod is allowed to start. The resources + will be made available to those containers which consume them + by name. + + + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + + + This field is immutable. + items: + description: |- + PodResourceClaim references exactly one ResourceClaim through a ClaimSource. + It adds a name to it that uniquely identifies the ResourceClaim inside the Pod. + Containers that need access to the ResourceClaim reference it with this name. + properties: + name: + description: |- + Name uniquely identifies this resource claim inside the pod. + This must be a DNS_LABEL. + type: string + source: + description: Source describes where to find the ResourceClaim. + properties: + resourceClaimName: + description: |- + ResourceClaimName is the name of a ResourceClaim object in the same + namespace as this pod. + type: string + resourceClaimTemplateName: + description: |- + ResourceClaimTemplateName is the name of a ResourceClaimTemplate + object in the same namespace as this pod. + + + The template will be used to create a new ResourceClaim, which will + be bound to this pod. When this pod is deleted, the ResourceClaim + will also be deleted. The pod name and resource name, along with a + generated component, will be used to form a unique name for the + ResourceClaim, which will be recorded in pod.status.resourceClaimStatuses. + + + This field is immutable and no changes will be made to the + corresponding ResourceClaim by the control plane after creating the + ResourceClaim. + type: string + type: object + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + restartPolicy: + description: |- + Restart policy for all containers within the pod. + One of Always, OnFailure, Never. In some contexts, only a subset of those values may be permitted. + Default to Always. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#restart-policy + type: string + runtimeClassName: + description: |- + RuntimeClassName refers to a RuntimeClass object in the node.k8s.io group, which should be used + to run this pod. If no RuntimeClass resource matches the named class, the pod will not be run. + If unset or empty, the "legacy" RuntimeClass will be used, which is an implicit class with an + empty definition that uses the default runtime handler. + More info: https://git.k8s.io/enhancements/keps/sig-node/585-runtime-class + type: string + schedulerName: + description: |- + If specified, the pod will be dispatched by specified scheduler. + If not specified, the pod will be dispatched by default scheduler. + type: string + schedulingGates: + description: |- + SchedulingGates is an opaque list of values that if specified will block scheduling the pod. + If schedulingGates is not empty, the pod will stay in the SchedulingGated state and the + scheduler will not attempt to schedule the pod. + + + SchedulingGates can only be set at pod creation time, and be removed only afterwards. + + + This is a beta feature enabled by the PodSchedulingReadiness feature gate. + items: + description: PodSchedulingGate is associated to a Pod to + guard its scheduling. + properties: + name: + description: |- + Name of the scheduling gate. + Each scheduling gate must have a unique name field. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + securityContext: + description: |- + SecurityContext holds pod-level security attributes and common container settings. + Optional: Defaults to empty. See type description for default values of each field. + properties: + fsGroup: + description: |- + A special supplemental group that applies to all containers in a pod. + Some volume types allow the Kubelet to change the ownership of that volume + to be owned by the pod: + + + 1. The owning GID will be the FSGroup + 2. The setgid bit is set (new files created in the volume will be owned by FSGroup) + 3. The permission bits are OR'd with rw-rw---- + + + If unset, the Kubelet will not modify the ownership and permissions of any volume. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + fsGroupChangePolicy: + description: |- + fsGroupChangePolicy defines behavior of changing ownership and permission of the volume + before being exposed inside Pod. This field will only apply to + volume types which support fsGroup based ownership(and permissions). + It will have no effect on ephemeral volume types such as: secret, configmaps + and emptydir. + Valid values are "OnRootMismatch" and "Always". If not specified, "Always" is used. + Note that this field cannot be set when spec.os.name is windows. + type: string + runAsGroup: + description: |- + The GID to run the entrypoint of the container process. + Uses runtime default if unset. + May also be set in SecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence + for that container. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: |- + Indicates that the container must run as a non-root user. + If true, the Kubelet will validate the image at runtime to ensure that it + does not run as UID 0 (root) and fail to start the container if it does. + If unset or false, no such validation will be performed. + May also be set in SecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: |- + The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in SecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence + for that container. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: |- + The SELinux context to be applied to all containers. + If unspecified, the container runtime will allocate a random SELinux context for each + container. May also be set in SecurityContext. If set in + both SecurityContext and PodSecurityContext, the value specified in SecurityContext + takes precedence for that container. + Note that this field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies + to the container. + type: string + role: + description: Role is a SELinux role label that applies + to the container. + type: string + type: + description: Type is a SELinux type label that applies + to the container. + type: string + user: + description: User is a SELinux user label that applies + to the container. + type: string + type: object + seccompProfile: + description: |- + The seccomp options to use by the containers in this pod. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile defined in a file on the node should be used. + The profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be set for any other type. + type: string + type: + description: |- + type indicates which kind of seccomp profile will be applied. + Valid options are: + + + Localhost - a profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile should be used. + Unconfined - no profile should be applied. + type: string + required: + - type + type: object + supplementalGroups: + description: |- + A list of groups applied to the first process run in each container, in addition + to the container's primary GID, the fsGroup (if specified), and group memberships + defined in the container image for the uid of the container process. If unspecified, + no additional groups are added to any container. Note that group memberships + defined in the container image for the uid of the container process are still effective, + even if they are not included in this list. + Note that this field cannot be set when spec.os.name is windows. + items: + format: int64 + type: integer + type: array + sysctls: + description: |- + Sysctls hold a list of namespaced sysctls used for the pod. Pods with unsupported + sysctls (by the container runtime) might fail to launch. + Note that this field cannot be set when spec.os.name is windows. + items: + description: Sysctl defines a kernel parameter to be + set + properties: + name: + description: Name of a property to set + type: string + value: + description: Value of a property to set + type: string + required: + - name + - value + type: object + type: array + windowsOptions: + description: |- + The Windows specific settings applied to all containers. + If unspecified, the options within a container's SecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: |- + GMSACredentialSpec is where the GMSA admission webhook + (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the + GMSA credential spec named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of + the GMSA credential spec to use. + type: string + hostProcess: + description: |- + HostProcess determines if a container should be run as a 'Host Process' container. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: |- + The UserName in Windows to run the entrypoint of the container process. + Defaults to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: string + type: object + type: object + serviceAccount: + description: |- + DeprecatedServiceAccount is a depreciated alias for ServiceAccountName. + Deprecated: Use serviceAccountName instead. + type: string + serviceAccountName: + description: |- + ServiceAccountName is the name of the ServiceAccount to use to run this pod. + More info: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/ + type: string + setHostnameAsFQDN: + description: |- + If true the pod's hostname will be configured as the pod's FQDN, rather than the leaf name (the default). + In Linux containers, this means setting the FQDN in the hostname field of the kernel (the nodename field of struct utsname). + In Windows containers, this means setting the registry value of hostname for the registry key HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters to FQDN. + If a pod does not have FQDN, this has no effect. + Default to false. + type: boolean + shareProcessNamespace: + description: |- + Share a single process namespace between all of the containers in a pod. + When this is set containers will be able to view and signal processes from other containers + in the same pod, and the first process in each container will not be assigned PID 1. + HostPID and ShareProcessNamespace cannot both be set. + Optional: Default to false. + type: boolean + subdomain: + description: |- + If specified, the fully qualified Pod hostname will be "...svc.". + If not specified, the pod will not have a domainname at all. + type: string + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully. May be decreased in delete request. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + If this value is nil, the default grace period will be used instead. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + Defaults to 30 seconds. + format: int64 + type: integer + tolerations: + description: If specified, the pod's tolerations. + items: + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . + properties: + effect: + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. + type: string + operator: + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. + type: string + tolerationSeconds: + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. + format: int64 + type: integer + value: + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. + type: string + type: object + type: array + topologySpreadConstraints: + description: |- + TopologySpreadConstraints describes how a group of pods ought to spread across topology + domains. Scheduler will schedule pods in a way which abides by the constraints. + All topologySpreadConstraints are ANDed. + items: + description: TopologySpreadConstraint specifies how to spread + matching pods among the given topology. + properties: + labelSelector: + description: |- + LabelSelector is used to find matching pods. + Pods that match this label selector are counted to determine the number of pods + in their corresponding topology domain. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select the pods over which + spreading will be calculated. The keys are used to lookup values from the + incoming pod labels, those key-value labels are ANDed with labelSelector + to select the group of existing pods over which spreading will be calculated + for the incoming pod. The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + MatchLabelKeys cannot be set when LabelSelector isn't set. + Keys that don't exist in the incoming pod labels will + be ignored. A null or empty list means only match against labelSelector. + + + This is a beta field and requires the MatchLabelKeysInPodTopologySpread feature gate to be enabled (enabled by default). + items: + type: string + type: array + x-kubernetes-list-type: atomic + maxSkew: + description: |- + MaxSkew describes the degree to which pods may be unevenly distributed. + When `whenUnsatisfiable=DoNotSchedule`, it is the maximum permitted difference + between the number of matching pods in the target topology and the global minimum. + The global minimum is the minimum number of matching pods in an eligible domain + or zero if the number of eligible domains is less than MinDomains. + For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same + labelSelector spread as 2/2/1: + In this case, the global minimum is 1. + | zone1 | zone2 | zone3 | + | P P | P P | P | + - if MaxSkew is 1, incoming pod can only be scheduled to zone3 to become 2/2/2; + scheduling it onto zone1(zone2) would make the ActualSkew(3-1) on zone1(zone2) + violate MaxSkew(1). + - if MaxSkew is 2, incoming pod can be scheduled onto any zone. + When `whenUnsatisfiable=ScheduleAnyway`, it is used to give higher precedence + to topologies that satisfy it. + It's a required field. Default value is 1 and 0 is not allowed. + format: int32 + type: integer + minDomains: + description: |- + MinDomains indicates a minimum number of eligible domains. + When the number of eligible domains with matching topology keys is less than minDomains, + Pod Topology Spread treats "global minimum" as 0, and then the calculation of Skew is performed. + And when the number of eligible domains with matching topology keys equals or greater than minDomains, + this value has no effect on scheduling. + As a result, when the number of eligible domains is less than minDomains, + scheduler won't schedule more than maxSkew Pods to those domains. + If value is nil, the constraint behaves as if MinDomains is equal to 1. + Valid values are integers greater than 0. + When value is not nil, WhenUnsatisfiable must be DoNotSchedule. + + + For example, in a 3-zone cluster, MaxSkew is set to 2, MinDomains is set to 5 and pods with the same + labelSelector spread as 2/2/2: + | zone1 | zone2 | zone3 | + | P P | P P | P P | + The number of domains is less than 5(MinDomains), so "global minimum" is treated as 0. + In this situation, new pod with the same labelSelector cannot be scheduled, + because computed skew will be 3(3 - 0) if new Pod is scheduled to any of the three zones, + it will violate MaxSkew. + + + This is a beta field and requires the MinDomainsInPodTopologySpread feature gate to be enabled (enabled by default). + format: int32 + type: integer + nodeAffinityPolicy: + description: |- + NodeAffinityPolicy indicates how we will treat Pod's nodeAffinity/nodeSelector + when calculating pod topology spread skew. Options are: + - Honor: only nodes matching nodeAffinity/nodeSelector are included in the calculations. + - Ignore: nodeAffinity/nodeSelector are ignored. All nodes are included in the calculations. + + + If this value is nil, the behavior is equivalent to the Honor policy. + This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag. + type: string + nodeTaintsPolicy: + description: |- + NodeTaintsPolicy indicates how we will treat node taints when calculating + pod topology spread skew. Options are: + - Honor: nodes without taints, along with tainted nodes for which the incoming pod + has a toleration, are included. + - Ignore: node taints are ignored. All nodes are included. + + + If this value is nil, the behavior is equivalent to the Ignore policy. + This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag. + type: string + topologyKey: + description: |- + TopologyKey is the key of node labels. Nodes that have a label with this key + and identical values are considered to be in the same topology. + We consider each as a "bucket", and try to put balanced number + of pods into each bucket. + We define a domain as a particular instance of a topology. + Also, we define an eligible domain as a domain whose nodes meet the requirements of + nodeAffinityPolicy and nodeTaintsPolicy. + e.g. If TopologyKey is "kubernetes.io/hostname", each Node is a domain of that topology. + And, if TopologyKey is "topology.kubernetes.io/zone", each zone is a domain of that topology. + It's a required field. + type: string + whenUnsatisfiable: + description: |- + WhenUnsatisfiable indicates how to deal with a pod if it doesn't satisfy + the spread constraint. + - DoNotSchedule (default) tells the scheduler not to schedule it. + - ScheduleAnyway tells the scheduler to schedule the pod in any location, + but giving higher precedence to topologies that would help reduce the + skew. + A constraint is considered "Unsatisfiable" for an incoming pod + if and only if every possible node assignment for that pod would violate + "MaxSkew" on some topology. + For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same + labelSelector spread as 3/1/1: + | zone1 | zone2 | zone3 | + | P P P | P | P | + If WhenUnsatisfiable is set to DoNotSchedule, incoming pod can only be scheduled + to zone2(zone3) to become 3/2/1(3/1/2) as ActualSkew(2-1) on zone2(zone3) satisfies + MaxSkew(1). In other words, the cluster can still be imbalanced, but scheduler + won't make it *more* imbalanced. + It's a required field. + type: string + required: + - maxSkew + - topologyKey + - whenUnsatisfiable + type: object + type: array + x-kubernetes-list-map-keys: + - topologyKey + - whenUnsatisfiable + x-kubernetes-list-type: map + volumes: + description: |- + List of volumes that can be mounted by containers belonging to the pod. + More info: https://kubernetes.io/docs/concepts/storage/volumes + items: + description: Volume represents a named volume in a pod that + may be accessed by any container in the pod. + properties: + awsElasticBlockStore: + description: |- + awsElasticBlockStore represents an AWS Disk resource that is attached to a + kubelet's host machine and then exposed to the pod. + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + properties: + fsType: + description: |- + fsType is the filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + partition: + description: |- + partition is the partition in the volume that you want to mount. + If omitted, the default is to mount by volume name. + Examples: For volume /dev/sda1, you specify the partition as "1". + Similarly, the volume partition for /dev/sda is "0" (or you can leave the property empty). + format: int32 + type: integer + readOnly: + description: |- + readOnly value true will force the readOnly setting in VolumeMounts. + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + type: boolean + volumeID: + description: |- + volumeID is unique ID of the persistent disk resource in AWS (Amazon EBS volume). + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + type: string + required: + - volumeID + type: object + azureDisk: + description: azureDisk represents an Azure Data Disk + mount on the host and bind mount to the pod. + properties: + cachingMode: + description: 'cachingMode is the Host Caching mode: + None, Read Only, Read Write.' + type: string + diskName: + description: diskName is the Name of the data disk + in the blob storage + type: string + diskURI: + description: diskURI is the URI of data disk in + the blob storage + type: string + fsType: + description: |- + fsType is Filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + kind: + description: 'kind expected values are Shared: multiple + blob disks per storage account Dedicated: single + blob disk per storage account Managed: azure + managed data disk (only in managed availability + set). defaults to shared' + type: string + readOnly: + description: |- + readOnly Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + description: azureFile represents an Azure File Service + mount on the host and bind mount to the pod. + properties: + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretName: + description: secretName is the name of secret that + contains Azure Storage Account Name and Key + type: string + shareName: + description: shareName is the azure share Name + type: string + required: + - secretName + - shareName + type: object + cephfs: + description: cephFS represents a Ceph FS mount on the + host that shares a pod's lifetime + properties: + monitors: + description: |- + monitors is Required: Monitors is a collection of Ceph monitors + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + items: + type: string + type: array + path: + description: 'path is Optional: Used as the mounted + root, rather than the full Ceph tree, default + is /' + type: string + readOnly: + description: |- + readOnly is Optional: Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + type: boolean + secretFile: + description: |- + secretFile is Optional: SecretFile is the path to key ring for User, default is /etc/ceph/user.secret + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + type: string + secretRef: + description: |- + secretRef is Optional: SecretRef is reference to the authentication secret for User, default is empty. + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + 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 + user: + description: |- + user is optional: User is the rados user name, default is admin + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + type: string + required: + - monitors + type: object + cinder: + description: |- + cinder represents a cinder volume attached and mounted on kubelets host machine. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + type: string + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + type: boolean + secretRef: + description: |- + secretRef is optional: points to a secret object containing parameters used to connect + to OpenStack. + 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 + volumeID: + description: |- + volumeID used to identify the volume in cinder. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + type: string + required: + - volumeID + type: object + configMap: + description: configMap represents a configMap that should + populate this volume + properties: + defaultMode: + description: |- + defaultMode is optional: mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + items: + description: |- + items if unspecified, each key-value pair in the Data field of the referenced + ConfigMap will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the ConfigMap, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within + a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + 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 + optional: + description: optional specify whether the ConfigMap + or its keys must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + csi: + description: csi (Container Storage Interface) represents + ephemeral storage that is handled by certain external + CSI drivers (Beta feature). + properties: + driver: + description: |- + driver is the name of the CSI driver that handles this volume. + Consult with your admin for the correct name as registered in the cluster. + type: string + fsType: + description: |- + fsType to mount. Ex. "ext4", "xfs", "ntfs". + If not provided, the empty value is passed to the associated CSI driver + which will determine the default filesystem to apply. + type: string + nodePublishSecretRef: + description: |- + nodePublishSecretRef is a reference to the secret object containing + sensitive information to pass to the CSI driver to complete the CSI + NodePublishVolume and NodeUnpublishVolume calls. + This field is optional, and may be empty if no secret is required. If the + secret object contains more than one secret, all secret references are passed. + 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 + readOnly: + description: |- + readOnly specifies a read-only configuration for the volume. + Defaults to false (read/write). + type: boolean + volumeAttributes: + additionalProperties: + type: string + description: |- + volumeAttributes stores driver-specific properties that are passed to the CSI + driver. Consult your driver's documentation for supported values. + type: object + required: + - driver + type: object + downwardAPI: + description: downwardAPI represents downward API about + the pod that should populate this volume + properties: + defaultMode: + description: |- + Optional: mode bits to use on created files by default. Must be a + Optional: mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + items: + description: Items is a list of downward API volume + file + items: + description: DownwardAPIVolumeFile represents + information to create the file containing the + pod field + properties: + fieldRef: + description: 'Required: Selects a field of + the pod: only annotations, labels, name + and namespace are supported.' + properties: + apiVersion: + description: Version of the schema the + FieldPath is written in terms of, defaults + to "v1". + type: string + fieldPath: + description: Path of the field to select + in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + description: |- + Optional: mode bits used to set permissions on this file, must be an octal value + between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: 'Required: Path is the relative + path name of the file to be created. Must + not be absolute or contain the ''..'' path. + Must be utf-8 encoded. The first item of + the relative path must not start with ''..''' + type: string + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported. + properties: + containerName: + description: 'Container name: required + for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format + of the exposed resources, defaults to + "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + type: object + emptyDir: + description: |- + emptyDir represents a temporary directory that shares a pod's lifetime. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir + properties: + medium: + description: |- + medium represents what type of storage medium should back this directory. + The default is "" which means to use the node's default medium. + Must be an empty string (default) or Memory. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + description: |- + sizeLimit is the total amount of local storage required for this EmptyDir volume. + The size limit is also applicable for memory medium. + The maximum usage on memory medium EmptyDir would be the minimum value between + the SizeLimit specified here and the sum of memory limits of all containers in a pod. + The default is nil which means that the limit is undefined. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + description: |- + ephemeral represents a volume that is handled by a cluster storage driver. + The volume's lifecycle is tied to the pod that defines it - it will be created before the pod starts, + and deleted when the pod is removed. + + + Use this if: + a) the volume is only needed while the pod runs, + b) features of normal volumes like restoring from snapshot or capacity + tracking are needed, + c) the storage driver is specified through a storage class, and + d) the storage driver supports dynamic volume provisioning through + a PersistentVolumeClaim (see EphemeralVolumeSource for more + information on the connection between this volume type + and PersistentVolumeClaim). + + + Use PersistentVolumeClaim or one of the vendor-specific + APIs for volumes that persist for longer than the lifecycle + of an individual pod. + + + Use CSI for light-weight local ephemeral volumes if the CSI driver is meant to + be used that way - see the documentation of the driver for + more information. + + + A pod can use both types of ephemeral volumes and + persistent volumes at the same time. + properties: + volumeClaimTemplate: + description: |- + Will be used to create a stand-alone PVC to provision the volume. + The pod in which this EphemeralVolumeSource is embedded will be the + owner of the PVC, i.e. the PVC will be deleted together with the + pod. The name of the PVC will be `-` where + `` is the name from the `PodSpec.Volumes` array + entry. Pod validation will reject the pod if the concatenated name + is not valid for a PVC (for example, too long). + + + An existing PVC with that name that is not owned by the pod + will *not* be used for the pod to avoid using an unrelated + volume by mistake. Starting the pod is then blocked until + the unrelated PVC is removed. If such a pre-created PVC is + meant to be used by the pod, the PVC has to updated with an + owner reference to the pod once the pod exists. Normally + this should not be necessary, but it may be useful when + manually reconstructing a broken cluster. + + + This field is read-only and no changes will be made by Kubernetes + to the PVC after it has been created. + + + Required, must not be nil. + properties: + metadata: + description: |- + May contain labels and annotations that will be copied into the PVC + when creating it. No other fields are allowed and will be rejected during + validation. + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + description: |- + The specification for the PersistentVolumeClaim. The entire content is + copied unchanged into the PVC that gets created from this + template. The same fields as in a PersistentVolumeClaim + are also valid here. + properties: + accessModes: + description: |- + accessModes contains the desired access modes the volume should have. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1 + items: + type: string + type: array + dataSource: + description: |- + dataSource field can be used to specify either: + * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) + * An existing PVC (PersistentVolumeClaim) + If the provisioner or an external controller can support the specified data source, + it will create a new volume based on the contents of the specified data source. + When the AnyVolumeDataSource feature gate is enabled, dataSource contents will be copied to dataSourceRef, + and dataSourceRef contents will be copied to dataSource when dataSourceRef.namespace is not specified. + If the namespace is specified, then dataSourceRef will not be copied to dataSource. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource + being referenced + type: string + name: + description: Name is the name of resource + being referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + description: |- + dataSourceRef specifies the object from which to populate the volume with data, if a non-empty + volume is desired. This may be any object from a non-empty API group (non + core object) or a PersistentVolumeClaim object. + When this field is specified, volume binding will only succeed if the type of + the specified object matches some installed volume populator or dynamic + provisioner. + This field will replace the functionality of the dataSource field and as such + if both fields are non-empty, they must have the same value. For backwards + compatibility, when namespace isn't specified in dataSourceRef, + both fields (dataSource and dataSourceRef) will be set to the same + value automatically if one of them is empty and the other is non-empty. + When namespace is specified in dataSourceRef, + dataSource isn't set to the same value and must be empty. + There are three important differences between dataSource and dataSourceRef: + * While dataSource only allows two specific types of objects, dataSourceRef + allows any non-core object, as well as PersistentVolumeClaim objects. + * While dataSource ignores disallowed values (dropping them), dataSourceRef + preserves all values, and generates an error if a disallowed value is + specified. + * While dataSource only allows local objects, dataSourceRef allows objects + in any namespaces. + (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled. + (Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource + being referenced + type: string + name: + description: Name is the name of resource + being referenced + type: string + namespace: + description: |- + Namespace is the namespace of resource being referenced + Note that when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details. + (Alpha) This field requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + type: string + required: + - kind + - name + type: object + resources: + description: |- + resources represents the minimum resources the volume should have. + If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements + that are lower than previous value but must still be higher than capacity recorded in the + status field of the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + selector: + description: selector is a label query over + volumes to consider for binding. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + description: |- + storageClassName is the name of the StorageClass required by the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1 + type: string + volumeAttributesClassName: + description: |- + volumeAttributesClassName may be used to set the VolumeAttributesClass used by this claim. + If specified, the CSI driver will create or update the volume with the attributes defined + in the corresponding VolumeAttributesClass. This has a different purpose than storageClassName, + it can be changed after the claim is created. An empty string value means that no VolumeAttributesClass + will be applied to the claim but it's not allowed to reset this field to empty string once it is set. + If unspecified and the PersistentVolumeClaim is unbound, the default VolumeAttributesClass + will be set by the persistentvolume controller if it exists. + If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be + set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource + exists. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#volumeattributesclass + (Alpha) Using this field requires the VolumeAttributesClass feature gate to be enabled. + type: string + volumeMode: + description: |- + volumeMode defines what type of volume is required by the claim. + Value of Filesystem is implied when not included in claim spec. + type: string + volumeName: + description: volumeName is the binding reference + to the PersistentVolume backing this claim. + type: string + type: object + required: + - spec + type: object + type: object + fc: + description: fc represents a Fibre Channel resource + that is attached to a kubelet's host machine and then + exposed to the pod. + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + lun: + description: 'lun is Optional: FC target lun number' + format: int32 + type: integer + readOnly: + description: |- + readOnly is Optional: Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + targetWWNs: + description: 'targetWWNs is Optional: FC target + worldwide names (WWNs)' + items: + type: string + type: array + wwids: + description: |- + wwids Optional: FC volume world wide identifiers (wwids) + Either wwids or combination of targetWWNs and lun must be set, but not both simultaneously. + items: + type: string + type: array + type: object + flexVolume: + description: |- + flexVolume represents a generic volume resource that is + provisioned/attached using an exec based plugin. + properties: + driver: + description: driver is the name of the driver to + use for this volume. + type: string + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". The default filesystem depends on FlexVolume script. + type: string + options: + additionalProperties: + type: string + description: 'options is Optional: this field holds + extra command options if any.' + type: object + readOnly: + description: |- + readOnly is Optional: defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: |- + secretRef is Optional: secretRef is reference to the secret object containing + sensitive information to pass to the plugin scripts. This may be + empty if no secret object is specified. If the secret object + contains more than one secret, all secrets are passed to the plugin + scripts. + 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 + required: + - driver + type: object + flocker: + description: flocker represents a Flocker volume attached + to a kubelet's host machine. This depends on the Flocker + control service being running + properties: + datasetName: + description: |- + datasetName is Name of the dataset stored as metadata -> name on the dataset for Flocker + should be considered as deprecated + type: string + datasetUUID: + description: datasetUUID is the UUID of the dataset. + This is unique identifier of a Flocker dataset + type: string + type: object + gcePersistentDisk: + description: |- + gcePersistentDisk represents a GCE Disk resource that is attached to a + kubelet's host machine and then exposed to the pod. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + properties: + fsType: + description: |- + fsType is filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + partition: + description: |- + partition is the partition in the volume that you want to mount. + If omitted, the default is to mount by volume name. + Examples: For volume /dev/sda1, you specify the partition as "1". + Similarly, the volume partition for /dev/sda is "0" (or you can leave the property empty). + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + format: int32 + type: integer + pdName: + description: |- + pdName is unique name of the PD resource in GCE. Used to identify the disk in GCE. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + type: string + readOnly: + description: |- + readOnly here will force the ReadOnly setting in VolumeMounts. + Defaults to false. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + type: boolean + required: + - pdName + type: object + gitRepo: + description: |- + gitRepo represents a git repository at a particular revision. + DEPRECATED: GitRepo is deprecated. To provision a container with a git repo, mount an + EmptyDir into an InitContainer that clones the repo using git, then mount the EmptyDir + into the Pod's container. + properties: + directory: + description: |- + directory is the target directory name. + Must not contain or start with '..'. If '.' is supplied, the volume directory will be the + git repository. Otherwise, if specified, the volume will contain the git repository in + the subdirectory with the given name. + type: string + repository: + description: repository is the URL + type: string + revision: + description: revision is the commit hash for the + specified revision. + type: string + required: + - repository + type: object + glusterfs: + description: |- + glusterfs represents a Glusterfs mount on the host that shares a pod's lifetime. + More info: https://examples.k8s.io/volumes/glusterfs/README.md + properties: + endpoints: + description: |- + endpoints is the endpoint name that details Glusterfs topology. + More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod + type: string + path: + description: |- + path is the Glusterfs volume path. + More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod + type: string + readOnly: + description: |- + readOnly here will force the Glusterfs volume to be mounted with read-only permissions. + Defaults to false. + More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod + type: boolean + required: + - endpoints + - path + type: object + hostPath: + description: |- + hostPath represents a pre-existing file or directory on the host + machine that is directly exposed to the container. This is generally + used for system agents or other privileged things that are allowed + to see the host machine. Most containers will NOT need this. + More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + --- + TODO(jonesdl) We need to restrict who can use host directory mounts and who can/can not + mount host directories as read/write. + properties: + path: + description: |- + path of the directory on the host. + If the path is a symlink, it will follow the link to the real path. + More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + type: string + type: + description: |- + type for HostPath Volume + Defaults to "" + More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + type: string + required: + - path + type: object + iscsi: + description: |- + iscsi represents an ISCSI Disk resource that is attached to a + kubelet's host machine and then exposed to the pod. + More info: https://examples.k8s.io/volumes/iscsi/README.md + properties: + chapAuthDiscovery: + description: chapAuthDiscovery defines whether support + iSCSI Discovery CHAP authentication + type: boolean + chapAuthSession: + description: chapAuthSession defines whether support + iSCSI Session CHAP authentication + type: boolean + fsType: + description: |- + fsType is the filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#iscsi + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + initiatorName: + description: |- + initiatorName is the custom iSCSI Initiator Name. + If initiatorName is specified with iscsiInterface simultaneously, new iSCSI interface + : will be created for the connection. + type: string + iqn: + description: iqn is the target iSCSI Qualified Name. + type: string + iscsiInterface: + description: |- + iscsiInterface is the interface Name that uses an iSCSI transport. + Defaults to 'default' (tcp). + type: string + lun: + description: lun represents iSCSI Target Lun number. + format: int32 + type: integer + portals: + description: |- + portals is the iSCSI Target Portal List. The portal is either an IP or ip_addr:port if the port + is other than default (typically TCP ports 860 and 3260). + items: + type: string + type: array + readOnly: + description: |- + readOnly here will force the ReadOnly setting in VolumeMounts. + Defaults to false. + type: boolean + secretRef: + description: secretRef is the CHAP Secret for iSCSI + target and initiator authentication + 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 + targetPortal: + description: |- + targetPortal is iSCSI Target Portal. The Portal is either an IP or ip_addr:port if the port + is other than default (typically TCP ports 860 and 3260). + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + description: |- + name of the volume. + Must be a DNS_LABEL and unique within the pod. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + nfs: + description: |- + nfs represents an NFS mount on the host that shares a pod's lifetime + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + properties: + path: + description: |- + path that is exported by the NFS server. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + type: string + readOnly: + description: |- + readOnly here will force the NFS export to be mounted with read-only permissions. + Defaults to false. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + type: boolean + server: + description: |- + server is the hostname or IP address of the NFS server. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + description: |- + persistentVolumeClaimVolumeSource represents a reference to a + PersistentVolumeClaim in the same namespace. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims + properties: + claimName: + description: |- + claimName is the name of a PersistentVolumeClaim in the same namespace as the pod using this volume. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims + type: string + readOnly: + description: |- + readOnly Will force the ReadOnly setting in VolumeMounts. + Default false. + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + description: photonPersistentDisk represents a PhotonController + persistent disk attached and mounted on kubelets host + machine + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + pdID: + description: pdID is the ID that identifies Photon + Controller persistent disk + type: string + required: + - pdID + type: object + portworxVolume: + description: portworxVolume represents a portworx volume + attached and mounted on kubelets host machine + properties: + fsType: + description: |- + fSType represents the filesystem type to mount + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs". Implicitly inferred to be "ext4" if unspecified. + type: string + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + volumeID: + description: volumeID uniquely identifies a Portworx + volume + type: string + required: + - volumeID + type: object + projected: + description: projected items for all in one resources + secrets, configmaps, and downward API + properties: + defaultMode: + description: |- + defaultMode are the mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + sources: + description: sources is the list of volume projections + items: + description: Projection that may be projected + along with other supported volume types + properties: + clusterTrustBundle: + description: |- + ClusterTrustBundle allows a pod to access the `.spec.trustBundle` field + of ClusterTrustBundle objects in an auto-updating file. + + + Alpha, gated by the ClusterTrustBundleProjection feature gate. + + + ClusterTrustBundle objects can either be selected by name, or by the + combination of signer name and a label selector. + + + Kubelet performs aggressive normalization of the PEM contents written + into the pod filesystem. Esoteric PEM features such as inter-block + comments and block headers are stripped. Certificates are deduplicated. + The ordering of certificates within the file is arbitrary, and Kubelet + may change the order over time. + properties: + labelSelector: + description: |- + Select all ClusterTrustBundles that match this label selector. Only has + effect if signerName is set. Mutually-exclusive with name. If unset, + interpreted as "match nothing". If set but empty, interpreted as "match + everything". + properties: + matchExpressions: + description: matchExpressions is a + list of label selector requirements. + The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + name: + description: |- + Select a single ClusterTrustBundle by object name. Mutually-exclusive + with signerName and labelSelector. + type: string + optional: + description: |- + If true, don't block pod startup if the referenced ClusterTrustBundle(s) + aren't available. If using name, then the named ClusterTrustBundle is + allowed not to exist. If using signerName, then the combination of + signerName and labelSelector is allowed to match zero + ClusterTrustBundles. + type: boolean + path: + description: Relative path from the volume + root to write the bundle. + type: string + signerName: + description: |- + Select all ClusterTrustBundles that match this signer name. + Mutually-exclusive with name. The contents of all selected + ClusterTrustBundles will be unified and deduplicated. + type: string + required: + - path + type: object + configMap: + description: configMap information about the + configMap data to project + properties: + items: + description: |- + items if unspecified, each key-value pair in the Data field of the referenced + ConfigMap will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the ConfigMap, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a + path within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + 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 + optional: + description: optional specify whether + the ConfigMap or its keys must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + downwardAPI: + description: downwardAPI information about + the downwardAPI data to project + properties: + items: + description: Items is a list of DownwardAPIVolume + file + items: + description: DownwardAPIVolumeFile represents + information to create the file containing + the pod field + properties: + fieldRef: + description: 'Required: Selects + a field of the pod: only annotations, + labels, name and namespace are + supported.' + properties: + apiVersion: + description: Version of the + schema the FieldPath is written + in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field + to select in the specified + API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + description: |- + Optional: mode bits used to set permissions on this file, must be an octal value + between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: 'Required: Path is the + relative path name of the file + to be created. Must not be absolute + or contain the ''..'' path. Must + be utf-8 encoded. The first item + of the relative path must not + start with ''..''' + type: string + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported. + properties: + containerName: + description: 'Container name: + required for volumes, optional + for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output + format of the exposed resources, + defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource + to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + type: object + secret: + description: secret information about the + secret data to project + properties: + items: + description: |- + items if unspecified, each key-value pair in the Data field of the referenced + Secret will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the Secret, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a + path within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + 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 + optional: + description: optional field specify whether + the Secret or its key must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + serviceAccountToken: + description: serviceAccountToken is information + about the serviceAccountToken data to project + properties: + audience: + description: |- + audience is the intended audience of the token. A recipient of a token + must identify itself with an identifier specified in the audience of the + token, and otherwise should reject the token. The audience defaults to the + identifier of the apiserver. + type: string + expirationSeconds: + description: |- + expirationSeconds is the requested duration of validity of the service + account token. As the token approaches expiration, the kubelet volume + plugin will proactively rotate the service account token. The kubelet will + start trying to rotate the token if the token is older than 80 percent of + its time to live or if the token is older than 24 hours.Defaults to 1 hour + and must be at least 10 minutes. + format: int64 + type: integer + path: + description: |- + path is the path relative to the mount point of the file to project the + token into. + type: string + required: + - path + type: object + type: object + type: array + type: object + quobyte: + description: quobyte represents a Quobyte mount on the + host that shares a pod's lifetime + properties: + group: + description: |- + group to map volume access to + Default is no group + type: string + readOnly: + description: |- + readOnly here will force the Quobyte volume to be mounted with read-only permissions. + Defaults to false. + type: boolean + registry: + description: |- + registry represents a single or multiple Quobyte Registry services + specified as a string as host:port pair (multiple entries are separated with commas) + which acts as the central registry for volumes + type: string + tenant: + description: |- + tenant owning the given Quobyte volume in the Backend + Used with dynamically provisioned Quobyte volumes, value is set by the plugin + type: string + user: + description: |- + user to map volume access to + Defaults to serivceaccount user + type: string + volume: + description: volume is a string that references + an already created Quobyte volume by name. + type: string + required: + - registry + - volume + type: object + rbd: + description: |- + rbd represents a Rados Block Device mount on the host that shares a pod's lifetime. + More info: https://examples.k8s.io/volumes/rbd/README.md + properties: + fsType: + description: |- + fsType is the filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#rbd + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + image: + description: |- + image is the rados image name. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + keyring: + description: |- + keyring is the path to key ring for RBDUser. + Default is /etc/ceph/keyring. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + monitors: + description: |- + monitors is a collection of Ceph monitors. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + items: + type: string + type: array + pool: + description: |- + pool is the rados pool name. + Default is rbd. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + readOnly: + description: |- + readOnly here will force the ReadOnly setting in VolumeMounts. + Defaults to false. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: boolean + secretRef: + description: |- + secretRef is name of the authentication secret for RBDUser. If provided + overrides keyring. + Default is nil. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + 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 + user: + description: |- + user is the rados user name. + Default is admin. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + required: + - image + - monitors + type: object + scaleIO: + description: scaleIO represents a ScaleIO persistent + volume attached and mounted on Kubernetes nodes. + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". + Default is "xfs". + type: string + gateway: + description: gateway is the host address of the + ScaleIO API Gateway. + type: string + protectionDomain: + description: protectionDomain is the name of the + ScaleIO Protection Domain for the configured storage. + type: string + readOnly: + description: |- + readOnly Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: |- + secretRef references to the secret for ScaleIO user and other + sensitive information. If this is not provided, Login operation will fail. + 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 + sslEnabled: + description: sslEnabled Flag enable/disable SSL + communication with Gateway, default false + type: boolean + storageMode: + description: |- + storageMode indicates whether the storage for a volume should be ThickProvisioned or ThinProvisioned. + Default is ThinProvisioned. + type: string + storagePool: + description: storagePool is the ScaleIO Storage + Pool associated with the protection domain. + type: string + system: + description: system is the name of the storage system + as configured in ScaleIO. + type: string + volumeName: + description: |- + volumeName is the name of a volume already created in the ScaleIO system + that is associated with this volume source. + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + description: |- + secret represents a secret that should populate this volume. + More info: https://kubernetes.io/docs/concepts/storage/volumes#secret + properties: + defaultMode: + description: |- + defaultMode is Optional: mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values + for mode bits. Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + items: + description: |- + items If unspecified, each key-value pair in the Data field of the referenced + Secret will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the Secret, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within + a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + optional: + description: optional field specify whether the + Secret or its keys must be defined + type: boolean + secretName: + description: |- + secretName is the name of the secret in the pod's namespace to use. + More info: https://kubernetes.io/docs/concepts/storage/volumes#secret + type: string + type: object + storageos: + description: storageOS represents a StorageOS volume + attached and mounted on Kubernetes nodes. + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: |- + secretRef specifies the secret to use for obtaining the StorageOS API + credentials. If not specified, default values will be attempted. + 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 + volumeName: + description: |- + volumeName is the human-readable name of the StorageOS volume. Volume + names are only unique within a namespace. + type: string + volumeNamespace: + description: |- + volumeNamespace specifies the scope of the volume within StorageOS. If no + namespace is specified then the Pod's namespace will be used. This allows the + Kubernetes name scoping to be mirrored within StorageOS for tighter integration. + Set VolumeName to any name to override the default behaviour. + Set to "default" if you are not using namespaces within StorageOS. + Namespaces that do not pre-exist within StorageOS will be created. + type: string + type: object + vsphereVolume: + description: vsphereVolume represents a vSphere volume + attached and mounted on kubelets host machine + properties: + fsType: + description: |- + fsType is filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + storagePolicyID: + description: storagePolicyID is the storage Policy + Based Management (SPBM) profile ID associated + with the StoragePolicyName. + type: string + storagePolicyName: + description: storagePolicyName is the storage Policy + Based Management (SPBM) profile name. + type: string + volumePath: + description: volumePath is the path that identifies + vSphere volume vmdk + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + required: + - containers + type: object + type: object + updateStrategy: + description: |- + Indicates the StatefulSetUpdateStrategy that will be + employed to update Pods in the InstanceSet when a revision is made to + Template. + UpdateStrategy.Type will be set to appsv1.OnDeleteStatefulSetStrategyType if MemberUpdateStrategy is not nil + + + Note: This field will be removed in future version. + properties: + rollingUpdate: + description: RollingUpdate is used to communicate parameters when + Type is RollingUpdateStatefulSetStrategyType. + properties: + maxUnavailable: + anyOf: + - type: integer + - type: string + description: |- + The maximum number of pods that can be unavailable during the update. + Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). + Absolute number is calculated from percentage by rounding up. This can not be 0. + Defaults to 1. This field is alpha-level and is only honored by servers that enable the + MaxUnavailableStatefulSet feature. The field applies to all pods in the range 0 to + Replicas-1. That means if there is any unavailable pod in the range 0 to Replicas-1, it + will be counted towards MaxUnavailable. + x-kubernetes-int-or-string: true + partition: + description: |- + Partition indicates the ordinal at which the StatefulSet should be partitioned + for updates. During a rolling update, all pods from ordinal Replicas-1 to + Partition are updated. All pods from ordinal Partition-1 to 0 remain untouched. + This is helpful in being able to do a canary based deployment. The default value is 0. + format: int32 + type: integer + type: object + type: + description: |- + Type indicates the type of the StatefulSetUpdateStrategy. + Default is RollingUpdate. + type: string + type: object + volumeClaimTemplates: + description: |- + Specifies a list of PersistentVolumeClaim templates that define the storage requirements for each replica. + Each template specifies the desired characteristics of a persistent volume, such as storage class, + size, and access modes. + These templates are used to dynamically provision persistent volumes for replicas upon their creation. + The final name of each PVC is generated by appending the pod's identifier to the name specified in volumeClaimTemplates[*].name. + items: + description: PersistentVolumeClaim is a user's request for and claim + to a persistent volume + 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: + description: |- + Standard object's metadata. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + description: |- + spec defines the desired characteristics of a volume requested by a pod author. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims + properties: + accessModes: + description: |- + accessModes contains the desired access modes the volume should have. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1 + items: + type: string + type: array + dataSource: + description: |- + dataSource field can be used to specify either: + * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) + * An existing PVC (PersistentVolumeClaim) + If the provisioner or an external controller can support the specified data source, + it will create a new volume based on the contents of the specified data source. + When the AnyVolumeDataSource feature gate is enabled, dataSource contents will be copied to dataSourceRef, + and dataSourceRef contents will be copied to dataSource when dataSourceRef.namespace is not specified. + If the namespace is specified, then dataSourceRef will not be copied to dataSource. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + description: |- + dataSourceRef specifies the object from which to populate the volume with data, if a non-empty + volume is desired. This may be any object from a non-empty API group (non + core object) or a PersistentVolumeClaim object. + When this field is specified, volume binding will only succeed if the type of + the specified object matches some installed volume populator or dynamic + provisioner. + This field will replace the functionality of the dataSource field and as such + if both fields are non-empty, they must have the same value. For backwards + compatibility, when namespace isn't specified in dataSourceRef, + both fields (dataSource and dataSourceRef) will be set to the same + value automatically if one of them is empty and the other is non-empty. + When namespace is specified in dataSourceRef, + dataSource isn't set to the same value and must be empty. + There are three important differences between dataSource and dataSourceRef: + * While dataSource only allows two specific types of objects, dataSourceRef + allows any non-core object, as well as PersistentVolumeClaim objects. + * While dataSource ignores disallowed values (dropping them), dataSourceRef + preserves all values, and generates an error if a disallowed value is + specified. + * While dataSource only allows local objects, dataSourceRef allows objects + in any namespaces. + (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled. + (Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + namespace: + description: |- + Namespace is the namespace of resource being referenced + Note that when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details. + (Alpha) This field requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + type: string + required: + - kind + - name + type: object + resources: + description: |- + resources represents the minimum resources the volume should have. + If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements + that are lower than previous value but must still be higher than capacity recorded in the + status field of the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + selector: + description: selector is a label query over volumes to consider + for binding. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + description: |- + storageClassName is the name of the StorageClass required by the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1 + type: string + volumeAttributesClassName: + description: |- + volumeAttributesClassName may be used to set the VolumeAttributesClass used by this claim. + If specified, the CSI driver will create or update the volume with the attributes defined + in the corresponding VolumeAttributesClass. This has a different purpose than storageClassName, + it can be changed after the claim is created. An empty string value means that no VolumeAttributesClass + will be applied to the claim but it's not allowed to reset this field to empty string once it is set. + If unspecified and the PersistentVolumeClaim is unbound, the default VolumeAttributesClass + will be set by the persistentvolume controller if it exists. + If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be + set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource + exists. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#volumeattributesclass + (Alpha) Using this field requires the VolumeAttributesClass feature gate to be enabled. + type: string + volumeMode: + description: |- + volumeMode defines what type of volume is required by the claim. + Value of Filesystem is implied when not included in claim spec. + type: string + volumeName: + description: volumeName is the binding reference to the + PersistentVolume backing this claim. + type: string + type: object + status: + description: |- + status represents the current information/status of a persistent volume claim. + Read-only. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims + properties: + accessModes: + description: |- + accessModes contains the actual access modes the volume backing the PVC has. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1 + items: + type: string + type: array + allocatedResourceStatuses: + additionalProperties: + description: |- + When a controller receives persistentvolume claim update with ClaimResourceStatus for a resource + that it does not recognizes, then it should ignore that update and let other controllers + handle it. + type: string + description: "allocatedResourceStatuses stores status of + resource being resized for the given PVC.\nKey names follow + standard Kubernetes label syntax. Valid values are either:\n\t* + Un-prefixed keys:\n\t\t- storage - the capacity of the + volume.\n\t* Custom resources must use implementation-defined + prefixed names such as \"example.com/my-custom-resource\"\nApart + from above values - keys that are unprefixed or have kubernetes.io + prefix are considered\nreserved and hence may not be used.\n\n\nClaimResourceStatus + can be in any of following states:\n\t- ControllerResizeInProgress:\n\t\tState + set when resize controller starts resizing the volume + in control-plane.\n\t- ControllerResizeFailed:\n\t\tState + set when resize has failed in resize controller with a + terminal error.\n\t- NodeResizePending:\n\t\tState set + when resize controller has finished resizing the volume + but further resizing of\n\t\tvolume is needed on the node.\n\t- + NodeResizeInProgress:\n\t\tState set when kubelet starts + resizing the volume.\n\t- NodeResizeFailed:\n\t\tState + set when resizing has failed in kubelet with a terminal + error. Transient errors don't set\n\t\tNodeResizeFailed.\nFor + example: if expanding a PVC for more capacity - this field + can be one of the following states:\n\t- pvc.status.allocatedResourceStatus['storage'] + = \"ControllerResizeInProgress\"\n - pvc.status.allocatedResourceStatus['storage'] + = \"ControllerResizeFailed\"\n - pvc.status.allocatedResourceStatus['storage'] + = \"NodeResizePending\"\n - pvc.status.allocatedResourceStatus['storage'] + = \"NodeResizeInProgress\"\n - pvc.status.allocatedResourceStatus['storage'] + = \"NodeResizeFailed\"\nWhen this field is not set, it + means that no resize operation is in progress for the + given PVC.\n\n\nA controller that receives PVC update + with previously unknown resourceName or ClaimResourceStatus\nshould + ignore the update for the purpose it was designed. For + example - a controller that\nonly is responsible for resizing + capacity of the volume, should ignore PVC updates that + change other valid\nresources associated with PVC.\n\n\nThis + is an alpha field and requires enabling RecoverVolumeExpansionFailure + feature." + type: object + x-kubernetes-map-type: granular + allocatedResources: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: "allocatedResources tracks the resources allocated + to a PVC including its capacity.\nKey names follow standard + Kubernetes label syntax. Valid values are either:\n\t* + Un-prefixed keys:\n\t\t- storage - the capacity of the + volume.\n\t* Custom resources must use implementation-defined + prefixed names such as \"example.com/my-custom-resource\"\nApart + from above values - keys that are unprefixed or have kubernetes.io + prefix are considered\nreserved and hence may not be used.\n\n\nCapacity + reported here may be larger than the actual capacity when + a volume expansion operation\nis requested.\nFor storage + quota, the larger value from allocatedResources and PVC.spec.resources + is used.\nIf allocatedResources is not set, PVC.spec.resources + alone is used for quota calculation.\nIf a volume expansion + capacity request is lowered, allocatedResources is only\nlowered + if there are no expansion operations in progress and if + the actual volume capacity\nis equal or lower than the + requested capacity.\n\n\nA controller that receives PVC + update with previously unknown resourceName\nshould ignore + the update for the purpose it was designed. For example + - a controller that\nonly is responsible for resizing + capacity of the volume, should ignore PVC updates that + change other valid\nresources associated with PVC.\n\n\nThis + is an alpha field and requires enabling RecoverVolumeExpansionFailure + feature." + type: object + capacity: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: capacity represents the actual resources of + the underlying volume. + type: object + conditions: + description: |- + conditions is the current Condition of persistent volume claim. If underlying persistent volume is being + resized then the Condition will be set to 'ResizeStarted'. + items: + description: PersistentVolumeClaimCondition contains details + about state of pvc + properties: + lastProbeTime: + description: lastProbeTime is the time we probed the + condition. + format: date-time + type: string + lastTransitionTime: + description: lastTransitionTime is the time the condition + transitioned from one status to another. + format: date-time + type: string + message: + description: message is the human-readable message + indicating details about last transition. + type: string + reason: + description: |- + reason is a unique, this should be a short, machine understandable string that gives the reason + for condition's last transition. If it reports "ResizeStarted" that means the underlying + persistent volume is being resized. + type: string + status: + type: string + type: + description: PersistentVolumeClaimConditionType is + a valid value of PersistentVolumeClaimCondition.Type + type: string + required: + - status + - type + type: object + type: array + currentVolumeAttributesClassName: + description: |- + currentVolumeAttributesClassName is the current name of the VolumeAttributesClass the PVC is using. + When unset, there is no VolumeAttributeClass applied to this PersistentVolumeClaim + This is an alpha field and requires enabling VolumeAttributesClass feature. + type: string + modifyVolumeStatus: + description: |- + ModifyVolumeStatus represents the status object of ControllerModifyVolume operation. + When this is unset, there is no ModifyVolume operation being attempted. + This is an alpha field and requires enabling VolumeAttributesClass feature. + properties: + status: + description: "status is the status of the ControllerModifyVolume + operation. It can be in any of following states:\n + - Pending\n Pending indicates that the PersistentVolumeClaim + cannot be modified due to unmet requirements, such + as\n the specified VolumeAttributesClass not existing.\n + - InProgress\n InProgress indicates that the volume + is being modified.\n - Infeasible\n Infeasible indicates + that the request has been rejected as invalid by the + CSI driver. To\n\t resolve the error, a valid VolumeAttributesClass + needs to be specified.\nNote: New statuses can be + added in the future. Consumers should check for unknown + statuses and fail appropriately." + type: string + targetVolumeAttributesClassName: + description: targetVolumeAttributesClassName is the + name of the VolumeAttributesClass the PVC currently + being reconciled + type: string + required: + - status + type: object + phase: + description: phase represents the current phase of PersistentVolumeClaim. + type: string + type: object + type: object + type: array + required: + - selector + - template + type: object + status: + description: Represents the current information about the state machine. + This data may be out of date. + properties: + availableReplicas: + description: Total number of available instances (ready for at least + minReadySeconds) targeted by this InstanceSet. + format: int32 + type: integer + conditions: + description: |- + Represents the latest available observations of an instanceset's current state. + Known .status.conditions.type are: "InstanceFailure", "InstanceReady" + items: + description: "Condition contains details for one aspect of the current + state of this API Resource.\n---\nThis struct is intended for + direct use as an array at the field path .status.conditions. For + example,\n\n\n\ttype FooStatus struct{\n\t // Represents the + observations of a foo's current state.\n\t // Known .status.conditions.type + are: \"Available\", \"Progressing\", and \"Degraded\"\n\t // + +patchMergeKey=type\n\t // +patchStrategy=merge\n\t // +listType=map\n\t + \ // +listMapKey=type\n\t Conditions []metav1.Condition `json:\"conditions,omitempty\" + patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t + \ // other fields\n\t}" + 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 + currentReplicas: + description: |- + currentReplicas is the number of instances created by the InstanceSet controller from the InstanceSet version + indicated by CurrentRevisions. + format: int32 + type: integer + currentRevision: + description: |- + currentRevision, if not empty, indicates the version of the InstanceSet used to generate instances in the + sequence [0,currentReplicas). + type: string + currentRevisions: + additionalProperties: + type: string + description: |- + currentRevisions, if not empty, indicates the old version of the InstanceSet used to generate the underlying workload. + key is the pod name, value is the revision. + type: object + initReplicas: + description: |- + Defines the initial number of instances when the cluster is first initialized. + This value is set to spec.Replicas at the time of object creation and remains constant thereafter. + Used only when spec.roles set. + format: int32 + type: integer + membersStatus: + description: Provides the status of each member in the cluster. + items: + properties: + podName: + default: Unknown + description: Represents the name of the pod. + type: string + role: + description: Defines the role of the replica in the cluster. + properties: + accessMode: + default: ReadWrite + description: Specifies the service capabilities of this + member. + enum: + - None + - Readonly + - ReadWrite + type: string + canVote: + default: true + description: Indicates if this member has voting rights. + type: boolean + isLeader: + default: false + description: Determines if this member is the leader. + type: boolean + name: + default: leader + description: Defines the role name of the replica. + type: string + required: + - accessMode + - name + type: object + required: + - podName + type: object + type: array + observedGeneration: + description: |- + observedGeneration is the most recent generation observed for this InstanceSet. It corresponds to the + InstanceSet's generation, which is updated on mutation by the API Server. + format: int64 + type: integer + readyInitReplicas: + description: |- + Represents the number of instances that have already reached the MembersStatus during the cluster initialization stage. + This value remains constant once it equals InitReplicas. + Used only when spec.roles set. + format: int32 + type: integer + readyReplicas: + description: readyReplicas is the number of instances created for + this InstanceSet with a Ready Condition. + format: int32 + type: integer + readyWithoutPrimary: + description: Indicates whether it is required for the InstanceSet + to have at least one primary instance ready. + type: boolean + replicas: + description: replicas is the number of instances created by the InstanceSet + controller. + format: int32 + type: integer + templatesStatus: + description: TemplatesStatus represents status of each instance generated + by InstanceTemplates + items: + description: InstanceTemplateStatus aggregates the status of replicas + for each InstanceTemplate + properties: + availableReplicas: + description: AvailableReplicas is the number of Pods that ready + for at least minReadySeconds. + format: int32 + type: integer + currentReplicas: + description: |- + currentReplicas is the number of instances created by the InstanceSet controller from the InstanceSet version + indicated by CurrentRevisions. + format: int32 + type: integer + name: + description: Name, the name of the InstanceTemplate. + type: string + readyReplicas: + description: ReadyReplicas is the number of Pods that have a + Ready Condition. + format: int32 + type: integer + replicas: + description: Replicas is the number of replicas of the InstanceTemplate. + format: int32 + type: integer + updatedReplicas: + description: |- + UpdatedReplicas is the number of Pods created by the InstanceSet controller from the InstanceSet version + indicated by UpdateRevisions. + format: int32 + type: integer + required: + - name + type: object + type: array + updateRevision: + description: |- + updateRevision, if not empty, indicates the version of the InstanceSet used to generate instances in the sequence + [replicas-updatedReplicas,replicas) + type: string + updateRevisions: + additionalProperties: + type: string + description: |- + updateRevisions, if not empty, indicates the new version of the InstanceSet used to generate the underlying workload. + key is the pod name, value is the revision. + type: object + updatedReplicas: + description: |- + updatedReplicas is the number of instances created by the InstanceSet controller from the InstanceSet version + indicated by UpdateRevisions. + format: int32 + type: integer + required: + - replicas + type: object + type: object + served: true + storage: true + subresources: + scale: + specReplicasPath: .spec.replicas + statusReplicasPath: .status.replicas + status: {} - additionalPrinterColumns: - description: leader instance name. jsonPath: .status.membersStatus[?(@.role.isLeader==true)].podName @@ -13092,7 +26171,7 @@ spec: type: object type: object served: true - storage: true + storage: false subresources: scale: specReplicasPath: .spec.replicas diff --git a/docs/developer_docs/api-reference/cluster.md b/docs/developer_docs/api-reference/cluster.md index cfaccb53995..4150fd1fb98 100644 --- a/docs/developer_docs/api-reference/cluster.md +++ b/docs/developer_docs/api-reference/cluster.md @@ -18,6 +18,9 @@ sidebar_label: Cluster apps.kubeblocks.io/v1beta1
  • +workloads.kubeblocks.io/v1 +
  • +
  • workloads.kubeblocks.io/v1alpha1
  • @@ -29752,6 +29755,2022 @@ string
    +

    workloads.kubeblocks.io/v1

    +
    +
    +Resource Types: + +

    InstanceSet +

    +
    +

    InstanceSet is the Schema for the instancesets API.

    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    FieldDescription
    +apiVersion
    +string
    +workloads.kubeblocks.io/v1 +
    +kind
    +string +
    InstanceSet
    +metadata
    + + +Kubernetes meta/v1.ObjectMeta + + +
    +

    Contains the metadata for the particular object, such as name, namespace, labels, and annotations.

    +Refer to the Kubernetes API documentation for the fields of the +metadata field. +
    +spec
    + + +InstanceSetSpec + + +
    +

    Defines the desired state of the state machine. It includes the configuration details for the state machine.

    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +replicas
    + +int32 + +
    +(Optional) +

    Specifies the desired number of replicas of the given Template. +These replicas are instantiations of the same Template, with each having a consistent identity. +Defaults to 1 if unspecified.

    +
    +defaultTemplateOrdinals
    + + +Ordinals + + +
    +

    Specifies the desired Ordinals of the default template. +The Ordinals used to specify the ordinal of the instance (pod) names to be generated under the default template.

    +

    For example, if Ordinals is {ranges: [{start: 0, end: 1}], discrete: [7]}, +then the instance names generated under the default template would be +$(cluster.name)-$(component.name)-0、$(cluster.name)-$(component.name)-1 and $(cluster.name)-$(component.name)-7

    +
    +minReadySeconds
    + +int32 + +
    +(Optional) +

    Defines the minimum number of seconds a newly created pod should be ready +without any of its container crashing to be considered available. +Defaults to 0, meaning the pod will be considered available as soon as it is ready.

    +
    +selector
    + + +Kubernetes meta/v1.LabelSelector + + +
    +

    Represents a label query over pods that should match the desired replica count indicated by the replica field. +It must match the labels defined in the pod template. +More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors

    +
    +service
    + + +Kubernetes core/v1.Service + + +
    +(Optional) +

    Defines the behavior of a service spec. +Provides read-write service. +https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status

    +

    Note: This field will be removed in future version.

    +
    +template
    + + +Kubernetes core/v1.PodTemplateSpec + + +
    +
    +instances
    + + +[]InstanceTemplate + + +
    +(Optional) +

    Overrides values in default Template.

    +

    Instance is the fundamental unit managed by KubeBlocks. +It represents a Pod with additional objects such as PVCs, Services, ConfigMaps, etc. +An InstanceSet manages instances with a total count of Replicas, +and by default, all these instances are generated from the same template. +The InstanceTemplate provides a way to override values in the default template, +allowing the InstanceSet to manage instances from different templates.

    +

    The naming convention for instances (pods) based on the InstanceSet Name, InstanceTemplate Name, and ordinal. +The constructed instance name follows the pattern: $(instance_set.name)-$(template.name)-$(ordinal). +By default, the ordinal starts from 0 for each InstanceTemplate. +It is important to ensure that the Name of each InstanceTemplate is unique.

    +

    The sum of replicas across all InstanceTemplates should not exceed the total number of Replicas specified for the InstanceSet. +Any remaining replicas will be generated using the default template and will follow the default naming rules.

    +
    +offlineInstances
    + +[]string + +
    +(Optional) +

    Specifies the names of instances to be transitioned to offline status.

    +

    Marking an instance as offline results in the following:

    +
      +
    1. The associated pod is stopped, and its PersistentVolumeClaim (PVC) is retained for potential +future reuse or data recovery, but it is no longer actively used.
    2. +
    3. The ordinal number assigned to this instance is preserved, ensuring it remains unique +and avoiding conflicts with new instances.
    4. +
    +

    Setting instances to offline allows for a controlled scale-in process, preserving their data and maintaining +ordinal consistency within the cluster. +Note that offline instances and their associated resources, such as PVCs, are not automatically deleted. +The cluster administrator must manually manage the cleanup and removal of these resources when they are no longer needed.

    +
    +volumeClaimTemplates
    + + +[]Kubernetes core/v1.PersistentVolumeClaim + + +
    +(Optional) +

    Specifies a list of PersistentVolumeClaim templates that define the storage requirements for each replica. +Each template specifies the desired characteristics of a persistent volume, such as storage class, +size, and access modes. +These templates are used to dynamically provision persistent volumes for replicas upon their creation. +The final name of each PVC is generated by appending the pod’s identifier to the name specified in volumeClaimTemplates[*].name.

    +
    +podManagementPolicy
    + + +Kubernetes apps/v1.PodManagementPolicyType + + +
    +(Optional) +

    Controls how pods are created during initial scale up, +when replacing pods on nodes, or when scaling down.

    +

    The default policy is OrderedReady, where pods are created in increasing order and the controller waits until each pod is ready before +continuing. When scaling down, the pods are removed in the opposite order. +The alternative policy is Parallel which will create pods in parallel +to match the desired scale without waiting, and on scale down will delete +all pods at once.

    +

    Note: This field will be removed in future version.

    +
    +parallelPodManagementConcurrency
    + + +Kubernetes api utils intstr.IntOrString + + +
    +(Optional) +

    Controls the concurrency of pods during initial scale up, when replacing pods on nodes, +or when scaling down. It only used when PodManagementPolicy is set to Parallel. +The default Concurrency is 100%.

    +
    +podUpdatePolicy
    + + +PodUpdatePolicyType + + +
    +(Optional) +

    PodUpdatePolicy indicates how pods should be updated

    +
      +
    • StrictInPlace indicates that only allows in-place upgrades. +Any attempt to modify other fields will be rejected.
    • +
    • PreferInPlace indicates that we will first attempt an in-place upgrade of the Pod. +If that fails, it will fall back to the ReCreate, where pod will be recreated. +Default value is “PreferInPlace”
    • +
    +
    +updateStrategy
    + + +Kubernetes apps/v1.StatefulSetUpdateStrategy + + +
    +

    Indicates the StatefulSetUpdateStrategy that will be +employed to update Pods in the InstanceSet when a revision is made to +Template. +UpdateStrategy.Type will be set to appsv1.OnDeleteStatefulSetStrategyType if MemberUpdateStrategy is not nil

    +

    Note: This field will be removed in future version.

    +
    +roles
    + + +[]ReplicaRole + + +
    +(Optional) +

    A list of roles defined in the system.

    +
    +roleProbe
    + + +RoleProbe + + +
    +(Optional) +

    Provides method to probe role.

    +
    +membershipReconfiguration
    + + +MembershipReconfiguration + + +
    +(Optional) +

    Provides actions to do membership dynamic reconfiguration.

    +
    +memberUpdateStrategy
    + + +MemberUpdateStrategy + + +
    +(Optional) +

    Members(Pods) update strategy.

    +
      +
    • serial: update Members one by one that guarantee minimum component unavailable time.
    • +
    • bestEffortParallel: update Members in parallel that guarantee minimum component un-writable time.
    • +
    • parallel: force parallel
    • +
    +
    +paused
    + +bool + +
    +(Optional) +

    Indicates that the InstanceSet is paused, meaning the reconciliation of this InstanceSet object will be paused.

    +
    +credential
    + + +Credential + + +
    +(Optional) +

    Credential used to connect to DB engine

    +
    +
    +status
    + + +InstanceSetStatus + + +
    +

    Represents the current information about the state machine. This data may be out of date.

    +
    +

    AccessMode +(string alias)

    +

    +(Appears on:ReplicaRole) +

    +
    +

    AccessMode defines SVC access mode enums.

    +
    + + + + + + + + + + + + + + +
    ValueDescription

    "None"

    "ReadWrite"

    "Readonly"

    +

    Action +

    +

    +(Appears on:MembershipReconfiguration, RoleProbe) +

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

    Refers to the utility image that contains the command which can be utilized to retrieve or process role information.

    +
    +command
    + +[]string + +
    +

    A set of instructions that will be executed within the Container to retrieve or process role information. This field is required.

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

    Additional parameters used to perform specific statements. This field is optional.

    +
    +

    ConditionType +(string alias)

    +
    +
    + + + + + + + + + + + + + + + + +
    ValueDescription

    "InstanceAvailable"

    InstanceAvailable ConditionStatus will be True if all instances(pods) are in the ready condition +and continue for “MinReadySeconds” seconds. Otherwise, it will be set to False.

    +

    "InstanceFailure"

    InstanceFailure is added in an instance set when at least one of its instances(pods) is in a Failed phase.

    +

    "InstanceReady"

    InstanceReady is added in an instance set when at least one of its instances(pods) is in a Ready condition. +ConditionStatus will be True if all its instances(pods) are in a Ready condition. +Or, a NotReady reason with not ready instances encoded in the Message filed will be set.

    +

    "InstanceUpdateRestricted"

    InstanceUpdateRestricted represents a ConditionType that indicates updates to an InstanceSet are blocked(when the +PodUpdatePolicy is set to StrictInPlace but the pods cannot be updated in-place).

    +
    +

    Credential +

    +

    +(Appears on:InstanceSetSpec) +

    +
    +
    + + + + + + + + + + + + + + + + + +
    FieldDescription
    +username
    + + +CredentialVar + + +
    +

    Defines the user’s name for the credential. +The corresponding environment variable will be KB_ITS_USERNAME.

    +
    +password
    + + +CredentialVar + + +
    +

    Represents the user’s password for the credential. +The corresponding environment variable will be KB_ITS_PASSWORD.

    +
    +

    CredentialVar +

    +

    +(Appears on:Credential) +

    +
    +
    + + + + + + + + + + + + + + + + + +
    FieldDescription
    +value
    + +string + +
    +(Optional) +

    Specifies the value of the environment variable. This field is optional and defaults to an empty string. +The value can include variable references in the format $(VAR_NAME) which will be expanded using previously defined environment variables in the container and any service environment variables.

    +

    If a variable cannot be resolved, the reference in the input string will remain unchanged. +Double $$ can be used to escape the $(VAR_NAME) syntax, resulting in a single $ and producing the string literal “$(VAR_NAME)”. +Escaped references will not be expanded, regardless of whether the variable exists or not.

    +
    +valueFrom
    + + +Kubernetes core/v1.EnvVarSource + + +
    +(Optional) +

    Defines the source for the environment variable’s value. This field is optional and cannot be used if the ‘Value’ field is not empty.

    +
    +

    InstanceSetSpec +

    +

    +(Appears on:InstanceSet) +

    +
    +

    InstanceSetSpec defines the desired state of InstanceSet

    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    FieldDescription
    +replicas
    + +int32 + +
    +(Optional) +

    Specifies the desired number of replicas of the given Template. +These replicas are instantiations of the same Template, with each having a consistent identity. +Defaults to 1 if unspecified.

    +
    +defaultTemplateOrdinals
    + + +Ordinals + + +
    +

    Specifies the desired Ordinals of the default template. +The Ordinals used to specify the ordinal of the instance (pod) names to be generated under the default template.

    +

    For example, if Ordinals is {ranges: [{start: 0, end: 1}], discrete: [7]}, +then the instance names generated under the default template would be +$(cluster.name)-$(component.name)-0、$(cluster.name)-$(component.name)-1 and $(cluster.name)-$(component.name)-7

    +
    +minReadySeconds
    + +int32 + +
    +(Optional) +

    Defines the minimum number of seconds a newly created pod should be ready +without any of its container crashing to be considered available. +Defaults to 0, meaning the pod will be considered available as soon as it is ready.

    +
    +selector
    + + +Kubernetes meta/v1.LabelSelector + + +
    +

    Represents a label query over pods that should match the desired replica count indicated by the replica field. +It must match the labels defined in the pod template. +More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors

    +
    +service
    + + +Kubernetes core/v1.Service + + +
    +(Optional) +

    Defines the behavior of a service spec. +Provides read-write service. +https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status

    +

    Note: This field will be removed in future version.

    +
    +template
    + + +Kubernetes core/v1.PodTemplateSpec + + +
    +
    +instances
    + + +[]InstanceTemplate + + +
    +(Optional) +

    Overrides values in default Template.

    +

    Instance is the fundamental unit managed by KubeBlocks. +It represents a Pod with additional objects such as PVCs, Services, ConfigMaps, etc. +An InstanceSet manages instances with a total count of Replicas, +and by default, all these instances are generated from the same template. +The InstanceTemplate provides a way to override values in the default template, +allowing the InstanceSet to manage instances from different templates.

    +

    The naming convention for instances (pods) based on the InstanceSet Name, InstanceTemplate Name, and ordinal. +The constructed instance name follows the pattern: $(instance_set.name)-$(template.name)-$(ordinal). +By default, the ordinal starts from 0 for each InstanceTemplate. +It is important to ensure that the Name of each InstanceTemplate is unique.

    +

    The sum of replicas across all InstanceTemplates should not exceed the total number of Replicas specified for the InstanceSet. +Any remaining replicas will be generated using the default template and will follow the default naming rules.

    +
    +offlineInstances
    + +[]string + +
    +(Optional) +

    Specifies the names of instances to be transitioned to offline status.

    +

    Marking an instance as offline results in the following:

    +
      +
    1. The associated pod is stopped, and its PersistentVolumeClaim (PVC) is retained for potential +future reuse or data recovery, but it is no longer actively used.
    2. +
    3. The ordinal number assigned to this instance is preserved, ensuring it remains unique +and avoiding conflicts with new instances.
    4. +
    +

    Setting instances to offline allows for a controlled scale-in process, preserving their data and maintaining +ordinal consistency within the cluster. +Note that offline instances and their associated resources, such as PVCs, are not automatically deleted. +The cluster administrator must manually manage the cleanup and removal of these resources when they are no longer needed.

    +
    +volumeClaimTemplates
    + + +[]Kubernetes core/v1.PersistentVolumeClaim + + +
    +(Optional) +

    Specifies a list of PersistentVolumeClaim templates that define the storage requirements for each replica. +Each template specifies the desired characteristics of a persistent volume, such as storage class, +size, and access modes. +These templates are used to dynamically provision persistent volumes for replicas upon their creation. +The final name of each PVC is generated by appending the pod’s identifier to the name specified in volumeClaimTemplates[*].name.

    +
    +podManagementPolicy
    + + +Kubernetes apps/v1.PodManagementPolicyType + + +
    +(Optional) +

    Controls how pods are created during initial scale up, +when replacing pods on nodes, or when scaling down.

    +

    The default policy is OrderedReady, where pods are created in increasing order and the controller waits until each pod is ready before +continuing. When scaling down, the pods are removed in the opposite order. +The alternative policy is Parallel which will create pods in parallel +to match the desired scale without waiting, and on scale down will delete +all pods at once.

    +

    Note: This field will be removed in future version.

    +
    +parallelPodManagementConcurrency
    + + +Kubernetes api utils intstr.IntOrString + + +
    +(Optional) +

    Controls the concurrency of pods during initial scale up, when replacing pods on nodes, +or when scaling down. It only used when PodManagementPolicy is set to Parallel. +The default Concurrency is 100%.

    +
    +podUpdatePolicy
    + + +PodUpdatePolicyType + + +
    +(Optional) +

    PodUpdatePolicy indicates how pods should be updated

    +
      +
    • StrictInPlace indicates that only allows in-place upgrades. +Any attempt to modify other fields will be rejected.
    • +
    • PreferInPlace indicates that we will first attempt an in-place upgrade of the Pod. +If that fails, it will fall back to the ReCreate, where pod will be recreated. +Default value is “PreferInPlace”
    • +
    +
    +updateStrategy
    + + +Kubernetes apps/v1.StatefulSetUpdateStrategy + + +
    +

    Indicates the StatefulSetUpdateStrategy that will be +employed to update Pods in the InstanceSet when a revision is made to +Template. +UpdateStrategy.Type will be set to appsv1.OnDeleteStatefulSetStrategyType if MemberUpdateStrategy is not nil

    +

    Note: This field will be removed in future version.

    +
    +roles
    + + +[]ReplicaRole + + +
    +(Optional) +

    A list of roles defined in the system.

    +
    +roleProbe
    + + +RoleProbe + + +
    +(Optional) +

    Provides method to probe role.

    +
    +membershipReconfiguration
    + + +MembershipReconfiguration + + +
    +(Optional) +

    Provides actions to do membership dynamic reconfiguration.

    +
    +memberUpdateStrategy
    + + +MemberUpdateStrategy + + +
    +(Optional) +

    Members(Pods) update strategy.

    +
      +
    • serial: update Members one by one that guarantee minimum component unavailable time.
    • +
    • bestEffortParallel: update Members in parallel that guarantee minimum component un-writable time.
    • +
    • parallel: force parallel
    • +
    +
    +paused
    + +bool + +
    +(Optional) +

    Indicates that the InstanceSet is paused, meaning the reconciliation of this InstanceSet object will be paused.

    +
    +credential
    + + +Credential + + +
    +(Optional) +

    Credential used to connect to DB engine

    +
    +

    InstanceSetStatus +

    +

    +(Appears on:InstanceSet) +

    +
    +

    InstanceSetStatus defines the observed state of InstanceSet

    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    FieldDescription
    +observedGeneration
    + +int64 + +
    +(Optional) +

    observedGeneration is the most recent generation observed for this InstanceSet. It corresponds to the +InstanceSet’s generation, which is updated on mutation by the API Server.

    +
    +replicas
    + +int32 + +
    +

    replicas is the number of instances created by the InstanceSet controller.

    +
    +readyReplicas
    + +int32 + +
    +

    readyReplicas is the number of instances created for this InstanceSet with a Ready Condition.

    +
    +currentReplicas
    + +int32 + +
    +

    currentReplicas is the number of instances created by the InstanceSet controller from the InstanceSet version +indicated by CurrentRevisions.

    +
    +updatedReplicas
    + +int32 + +
    +

    updatedReplicas is the number of instances created by the InstanceSet controller from the InstanceSet version +indicated by UpdateRevisions.

    +
    +currentRevision
    + +string + +
    +

    currentRevision, if not empty, indicates the version of the InstanceSet used to generate instances in the +sequence [0,currentReplicas).

    +
    +updateRevision
    + +string + +
    +

    updateRevision, if not empty, indicates the version of the InstanceSet used to generate instances in the sequence +[replicas-updatedReplicas,replicas)

    +
    +conditions
    + + +[]Kubernetes meta/v1.Condition + + +
    +(Optional) +

    Represents the latest available observations of an instanceset’s current state. +Known .status.conditions.type are: “InstanceFailure”, “InstanceReady”

    +
    +availableReplicas
    + +int32 + +
    +(Optional) +

    Total number of available instances (ready for at least minReadySeconds) targeted by this InstanceSet.

    +
    +initReplicas
    + +int32 + +
    +(Optional) +

    Defines the initial number of instances when the cluster is first initialized. +This value is set to spec.Replicas at the time of object creation and remains constant thereafter. +Used only when spec.roles set.

    +
    +readyInitReplicas
    + +int32 + +
    +(Optional) +

    Represents the number of instances that have already reached the MembersStatus during the cluster initialization stage. +This value remains constant once it equals InitReplicas. +Used only when spec.roles set.

    +
    +membersStatus
    + + +[]MemberStatus + + +
    +(Optional) +

    Provides the status of each member in the cluster.

    +
    +readyWithoutPrimary
    + +bool + +
    +(Optional) +

    Indicates whether it is required for the InstanceSet to have at least one primary instance ready.

    +
    +currentRevisions
    + +map[string]string + +
    +(Optional) +

    currentRevisions, if not empty, indicates the old version of the InstanceSet used to generate the underlying workload. +key is the pod name, value is the revision.

    +
    +updateRevisions
    + +map[string]string + +
    +(Optional) +

    updateRevisions, if not empty, indicates the new version of the InstanceSet used to generate the underlying workload. +key is the pod name, value is the revision.

    +
    +templatesStatus
    + + +[]InstanceTemplateStatus + + +
    +(Optional) +

    TemplatesStatus represents status of each instance generated by InstanceTemplates

    +
    +

    InstanceTemplate +

    +

    +(Appears on:InstanceSetSpec) +

    +
    +

    InstanceTemplate allows customization of individual replica configurations within a Component, +without altering the base component template defined in ClusterComponentSpec. +It enables the application of distinct settings to specific instances (replicas), +providing flexibility while maintaining a common configuration baseline.

    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    FieldDescription
    +name
    + +string + +
    +

    Name specifies the unique name of the instance Pod created using this InstanceTemplate. +This name is constructed by concatenating the component’s name, the template’s name, and the instance’s ordinal +using the pattern: $(cluster.name)-$(component.name)-$(template.name)-$(ordinal). Ordinals start from 0. +The specified name overrides any default naming conventions or patterns.

    +
    +replicas
    + +int32 + +
    +(Optional) +

    Specifies the number of instances (Pods) to create from this InstanceTemplate. +This field allows setting how many replicated instances of the component, +with the specific overrides in the InstanceTemplate, are created. +The default value is 1. A value of 0 disables instance creation.

    +
    +ordinals
    + + +Ordinals + + +
    +

    Specifies the desired Ordinals of this InstanceTemplate. +The Ordinals used to specify the ordinal of the instance (pod) names to be generated under this InstanceTemplate.

    +

    For example, if Ordinals is {ranges: [{start: 0, end: 1}], discrete: [7]}, +then the instance names generated under this InstanceTemplate would be +$(cluster.name)-$(component.name)-$(template.name)-0、$(cluster.name)-$(component.name)-$(template.name)-1 and +$(cluster.name)-$(component.name)-$(template.name)-7

    +
    +annotations
    + +map[string]string + +
    +(Optional) +

    Specifies a map of key-value pairs to be merged into the Pod’s existing annotations. +Existing keys will have their values overwritten, while new keys will be added to the annotations.

    +
    +labels
    + +map[string]string + +
    +(Optional) +

    Specifies a map of key-value pairs that will be merged into the Pod’s existing labels. +Values for existing keys will be overwritten, and new keys will be added.

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

    Specifies an override for the first container’s image in the pod.

    +
    +schedulingPolicy
    + + +SchedulingPolicy + + +
    +(Optional) +

    Specifies the scheduling policy for the Component.

    +
    +resources
    + + +Kubernetes core/v1.ResourceRequirements + + +
    +(Optional) +

    Specifies an override for the resource requirements of the first container in the Pod. +This field allows for customizing resource allocation (CPU, memory, etc.) for the container.

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

    Defines Env to override. +Add new or override existing envs.

    +
    +volumes
    + + +[]Kubernetes core/v1.Volume + + +
    +(Optional) +

    Defines Volumes to override. +Add new or override existing volumes.

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

    Defines VolumeMounts to override. +Add new or override existing volume mounts of the first container in the pod.

    +
    +volumeClaimTemplates
    + + +[]Kubernetes core/v1.PersistentVolumeClaim + + +
    +(Optional) +

    Defines VolumeClaimTemplates to override. +Add new or override existing volume claim templates.

    +
    +

    InstanceTemplateStatus +

    +

    +(Appears on:InstanceSetStatus) +

    +
    +

    InstanceTemplateStatus aggregates the status of replicas for each InstanceTemplate

    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    FieldDescription
    +name
    + +string + +
    +

    Name, the name of the InstanceTemplate.

    +
    +replicas
    + +int32 + +
    +(Optional) +

    Replicas is the number of replicas of the InstanceTemplate.

    +
    +readyReplicas
    + +int32 + +
    +(Optional) +

    ReadyReplicas is the number of Pods that have a Ready Condition.

    +
    +availableReplicas
    + +int32 + +
    +(Optional) +

    AvailableReplicas is the number of Pods that ready for at least minReadySeconds.

    +
    +currentReplicas
    + +int32 + +
    +

    currentReplicas is the number of instances created by the InstanceSet controller from the InstanceSet version +indicated by CurrentRevisions.

    +
    +updatedReplicas
    + +int32 + +
    +(Optional) +

    UpdatedReplicas is the number of Pods created by the InstanceSet controller from the InstanceSet version +indicated by UpdateRevisions.

    +
    +

    MemberStatus +

    +

    +(Appears on:InstanceSetStatus) +

    +
    +
    + + + + + + + + + + + + + + + + + +
    FieldDescription
    +podName
    + +string + +
    +

    Represents the name of the pod.

    +
    +role
    + + +ReplicaRole + + +
    +(Optional) +

    Defines the role of the replica in the cluster.

    +
    +

    MemberUpdateStrategy +(string alias)

    +

    +(Appears on:InstanceSetSpec) +

    +
    +

    MemberUpdateStrategy defines Cluster Component update strategy.

    +
    + + + + + + + + + + + + + + +
    ValueDescription

    "BestEffortParallel"

    "Parallel"

    "Serial"

    +

    MembershipReconfiguration +

    +

    +(Appears on:InstanceSetSpec) +

    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    FieldDescription
    +switchoverAction
    + + +Action + + +
    +(Optional) +

    Specifies the environment variables that can be used in all following Actions: +- KB_ITS_USERNAME: Represents the username part of the credential +- KB_ITS_PASSWORD: Represents the password part of the credential +- KB_ITS_LEADER_HOST: Represents the leader host +- KB_ITS_TARGET_HOST: Represents the target host +- KB_ITS_SERVICE_PORT: Represents the service port

    +

    Defines the action to perform a switchover. +If the Image is not configured, the latest BusyBox image will be used.

    +
    +memberJoinAction
    + + +Action + + +
    +(Optional) +

    Defines the action to add a member. +If the Image is not configured, the Image from the previous non-nil action will be used.

    +
    +memberLeaveAction
    + + +Action + + +
    +(Optional) +

    Defines the action to remove a member. +If the Image is not configured, the Image from the previous non-nil action will be used.

    +
    +logSyncAction
    + + +Action + + +
    +(Optional) +

    Defines the action to trigger the new member to start log syncing. +If the Image is not configured, the Image from the previous non-nil action will be used.

    +
    +promoteAction
    + + +Action + + +
    +(Optional) +

    Defines the action to inform the cluster that the new member can join voting now. +If the Image is not configured, the Image from the previous non-nil action will be used.

    +
    +

    Ordinals +

    +

    +(Appears on:InstanceSetSpec, InstanceTemplate) +

    +
    +

    Ordinals represents a combination of continuous segments and individual values.

    +
    + + + + + + + + + + + + + + + + + +
    FieldDescription
    +ranges
    + + +[]Range + + +
    +
    +discrete
    + +[]int32 + +
    +
    +

    PodUpdatePolicyType +(string alias)

    +

    +(Appears on:InstanceSetSpec) +

    +
    +
    + + + + + + + + + + + + +
    ValueDescription

    "PreferInPlace"

    PreferInPlacePodUpdatePolicyType indicates that we will first attempt an in-place upgrade of the Pod. +If that fails, it will fall back to the ReCreate, where pod will be recreated.

    +

    "StrictInPlace"

    StrictInPlacePodUpdatePolicyType indicates that only allows in-place upgrades. +Any attempt to modify other fields will be rejected.

    +
    +

    Range +

    +

    +(Appears on:Ordinals) +

    +
    +

    Range represents a range with a start and an end value. +It is used to define a continuous segment.

    +
    + + + + + + + + + + + + + + + + + +
    FieldDescription
    +start
    + +int32 + +
    +
    +end
    + +int32 + +
    +
    +

    ReplicaRole +

    +

    +(Appears on:InstanceSetSpec, MemberStatus) +

    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + +
    FieldDescription
    +name
    + +string + +
    +

    Defines the role name of the replica.

    +
    +accessMode
    + + +AccessMode + + +
    +

    Specifies the service capabilities of this member.

    +
    +canVote
    + +bool + +
    +(Optional) +

    Indicates if this member has voting rights.

    +
    +isLeader
    + +bool + +
    +(Optional) +

    Determines if this member is the leader.

    +
    +

    RoleProbe +

    +

    +(Appears on:InstanceSetSpec) +

    +
    +

    RoleProbe defines how to observe role

    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    FieldDescription
    +customHandler
    + + +[]Action + + +
    +(Optional) +

    Defines a custom method for role probing. +Actions defined here are executed in series. +Upon completion of all actions, the final output should be a single string representing the role name defined in spec.Roles. +The latest BusyBox image will be used if Image is not configured. +Environment variables can be used in Command: +- v_KB_ITS_LASTSTDOUT: stdout from the last action, watch for ‘v’ prefix +- KB_ITS_USERNAME: username part of the credential +- KB_ITS_PASSWORD: password part of the credential

    +
    +initialDelaySeconds
    + +int32 + +
    +(Optional) +

    Specifies the number of seconds to wait after the container has started before initiating role probing.

    +
    +timeoutSeconds
    + +int32 + +
    +(Optional) +

    Specifies the number of seconds after which the probe times out.

    +
    +periodSeconds
    + +int32 + +
    +(Optional) +

    Specifies the frequency (in seconds) of probe execution.

    +
    +successThreshold
    + +int32 + +
    +(Optional) +

    Specifies the minimum number of consecutive successes for the probe to be considered successful after having failed.

    +
    +failureThreshold
    + +int32 + +
    +(Optional) +

    Specifies the minimum number of consecutive failures for the probe to be considered failed after having succeeded.

    +
    +roleUpdateMechanism
    + + +RoleUpdateMechanism + + +
    +(Optional) +

    Specifies the method for updating the pod role label.

    +
    +

    RoleUpdateMechanism +(string alias)

    +

    +(Appears on:RoleProbe) +

    +
    +

    RoleUpdateMechanism defines the way how pod role label being updated.

    +
    + + + + + + + + + + + + +
    ValueDescription

    "DirectAPIServerEventUpdate"

    "ReadinessProbeEventUpdate"

    +

    SchedulingPolicy +

    +

    +(Appears on:InstanceTemplate) +

    +
    +

    SchedulingPolicy the scheduling policy. +Deprecated: Unify with apps/v1alpha1.SchedulingPolicy

    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    FieldDescription
    +schedulerName
    + +string + +
    +(Optional) +

    If specified, the Pod will be dispatched by specified scheduler. +If not specified, the Pod will be dispatched by default scheduler.

    +
    +nodeSelector
    + +map[string]string + +
    +(Optional) +

    NodeSelector is a selector which must be true for the Pod to fit on a node. +Selector which must match a node’s labels for the Pod to be scheduled on that node. +More info: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/

    +
    +nodeName
    + +string + +
    +(Optional) +

    NodeName is a request to schedule this Pod onto a specific node. If it is non-empty, +the scheduler simply schedules this Pod onto that node, assuming that it fits resource +requirements.

    +
    +affinity
    + + +Kubernetes core/v1.Affinity + + +
    +(Optional) +

    Specifies a group of affinity scheduling rules of the Cluster, including NodeAffinity, PodAffinity, and PodAntiAffinity.

    +
    +tolerations
    + + +[]Kubernetes core/v1.Toleration + + +
    +(Optional) +

    Allows Pods to be scheduled onto nodes with matching taints. +Each toleration in the array allows the Pod to tolerate node taints based on +specified key, value, effect, and operator.

    +
      +
    • The key, value, and effect identify the taint that the toleration matches.
    • +
    • The operator determines how the toleration matches the taint.
    • +
    +

    Pods with matching tolerations are allowed to be scheduled on tainted nodes, typically reserved for specific purposes.

    +
    +topologySpreadConstraints
    + + +[]Kubernetes core/v1.TopologySpreadConstraint + + +
    +(Optional) +

    TopologySpreadConstraints describes how a group of Pods ought to spread across topology +domains. Scheduler will schedule Pods in a way which abides by the constraints. +All topologySpreadConstraints are ANDed.

    +
    +

    workloads.kubeblocks.io/v1alpha1

    diff --git a/pkg/controller/builder/builder_instance_set.go b/pkg/controller/builder/builder_instance_set.go index d05696011a8..2dc3541df59 100644 --- a/pkg/controller/builder/builder_instance_set.go +++ b/pkg/controller/builder/builder_instance_set.go @@ -25,7 +25,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/intstr" - workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" + workloads "github.com/apecloud/kubeblocks/apis/workloads/v1" ) type InstanceSetBuilder struct { diff --git a/pkg/controller/builder/builder_instance_set_test.go b/pkg/controller/builder/builder_instance_set_test.go index 522439d183e..c2e53272e0e 100644 --- a/pkg/controller/builder/builder_instance_set_test.go +++ b/pkg/controller/builder/builder_instance_set_test.go @@ -29,7 +29,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/intstr" - workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" + workloads "github.com/apecloud/kubeblocks/apis/workloads/v1" ) var _ = Describe("instance_set builder", func() { diff --git a/pkg/controller/component/its_convertor.go b/pkg/controller/component/its_convertor.go index 2cc9fb9e5d5..af8af9b5d16 100644 --- a/pkg/controller/component/its_convertor.go +++ b/pkg/controller/component/its_convertor.go @@ -28,7 +28,7 @@ import ( "k8s.io/apimachinery/pkg/util/intstr" kbappsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" - workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" + workloads "github.com/apecloud/kubeblocks/apis/workloads/v1" "github.com/apecloud/kubeblocks/pkg/constant" viper "github.com/apecloud/kubeblocks/pkg/viperx" ) diff --git a/pkg/controller/component/lifecycle/kbagent.go b/pkg/controller/component/lifecycle/kbagent.go index 0204a2a650e..5dcbba85edc 100644 --- a/pkg/controller/component/lifecycle/kbagent.go +++ b/pkg/controller/component/lifecycle/kbagent.go @@ -30,7 +30,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" - workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" + workloads "github.com/apecloud/kubeblocks/apis/workloads/v1" "github.com/apecloud/kubeblocks/pkg/constant" "github.com/apecloud/kubeblocks/pkg/controller/component" "github.com/apecloud/kubeblocks/pkg/controller/instanceset" diff --git a/pkg/controller/component/vars.go b/pkg/controller/component/vars.go index e7e9ea9ef70..b946aa838ac 100644 --- a/pkg/controller/component/vars.go +++ b/pkg/controller/component/vars.go @@ -40,7 +40,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" - workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" + workloads "github.com/apecloud/kubeblocks/apis/workloads/v1" "github.com/apecloud/kubeblocks/pkg/common" "github.com/apecloud/kubeblocks/pkg/constant" "github.com/apecloud/kubeblocks/pkg/controller/instanceset" diff --git a/pkg/controller/component/workload_utils.go b/pkg/controller/component/workload_utils.go index 4eca5ee4623..ff76e3f8a08 100644 --- a/pkg/controller/component/workload_utils.go +++ b/pkg/controller/component/workload_utils.go @@ -31,7 +31,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" - workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" + workloads "github.com/apecloud/kubeblocks/apis/workloads/v1" "github.com/apecloud/kubeblocks/pkg/constant" "github.com/apecloud/kubeblocks/pkg/controller/instanceset" "github.com/apecloud/kubeblocks/pkg/generics" diff --git a/pkg/controller/factory/builder.go b/pkg/controller/factory/builder.go index bafb54e7352..67922193882 100644 --- a/pkg/controller/factory/builder.go +++ b/pkg/controller/factory/builder.go @@ -33,7 +33,7 @@ import ( appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1beta1 "github.com/apecloud/kubeblocks/apis/apps/v1beta1" dpv1alpha1 "github.com/apecloud/kubeblocks/apis/dataprotection/v1alpha1" - workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" + workloads "github.com/apecloud/kubeblocks/apis/workloads/v1" "github.com/apecloud/kubeblocks/pkg/common" cfgcm "github.com/apecloud/kubeblocks/pkg/configuration/config_manager" "github.com/apecloud/kubeblocks/pkg/constant" diff --git a/pkg/controller/factory/builder_test.go b/pkg/controller/factory/builder_test.go index fa88eb8e116..e9f289d80e4 100644 --- a/pkg/controller/factory/builder_test.go +++ b/pkg/controller/factory/builder_test.go @@ -33,7 +33,7 @@ import ( appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1beta1 "github.com/apecloud/kubeblocks/apis/apps/v1beta1" - workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" + workloads "github.com/apecloud/kubeblocks/apis/workloads/v1" cfgcm "github.com/apecloud/kubeblocks/pkg/configuration/config_manager" "github.com/apecloud/kubeblocks/pkg/constant" "github.com/apecloud/kubeblocks/pkg/controller/component" diff --git a/pkg/controller/handler/handler_builder_test.go b/pkg/controller/handler/handler_builder_test.go index 298bc0bdb88..76b34e72160 100644 --- a/pkg/controller/handler/handler_builder_test.go +++ b/pkg/controller/handler/handler_builder_test.go @@ -34,7 +34,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/event" "sigs.k8s.io/controller-runtime/pkg/reconcile" - workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" + workloads "github.com/apecloud/kubeblocks/apis/workloads/v1" "github.com/apecloud/kubeblocks/pkg/constant" "github.com/apecloud/kubeblocks/pkg/controller/builder" "github.com/apecloud/kubeblocks/pkg/controller/model" diff --git a/pkg/controller/handler/suite_test.go b/pkg/controller/handler/suite_test.go index 218013f34af..37ba635b995 100644 --- a/pkg/controller/handler/suite_test.go +++ b/pkg/controller/handler/suite_test.go @@ -28,7 +28,7 @@ import ( "github.com/golang/mock/gomock" - workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" + workloads "github.com/apecloud/kubeblocks/apis/workloads/v1" "github.com/apecloud/kubeblocks/pkg/controller/model" testutil "github.com/apecloud/kubeblocks/pkg/testutil/k8s" "github.com/apecloud/kubeblocks/pkg/testutil/k8s/mocks" diff --git a/pkg/controller/instanceset/in_place_update_util.go b/pkg/controller/instanceset/in_place_update_util.go index 92c78de4f56..2070e85d757 100644 --- a/pkg/controller/instanceset/in_place_update_util.go +++ b/pkg/controller/instanceset/in_place_update_util.go @@ -28,7 +28,7 @@ import ( corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" - workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" + workloads "github.com/apecloud/kubeblocks/apis/workloads/v1" "github.com/apecloud/kubeblocks/pkg/constant" intctrlutil "github.com/apecloud/kubeblocks/pkg/controllerutil" viper "github.com/apecloud/kubeblocks/pkg/viperx" diff --git a/pkg/controller/instanceset/instance_template_util.go b/pkg/controller/instanceset/instance_template_util.go index 635faaf2c6e..7302e0d6402 100644 --- a/pkg/controller/instanceset/instance_template_util.go +++ b/pkg/controller/instanceset/instance_template_util.go @@ -22,7 +22,7 @@ package instanceset import ( corev1 "k8s.io/api/core/v1" - workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" + workloads "github.com/apecloud/kubeblocks/apis/workloads/v1" ) // TODO: remove these after extract the Schema of the API types from Kubeblocks into a separate Go package. diff --git a/pkg/controller/instanceset/instance_util.go b/pkg/controller/instanceset/instance_util.go index 670e1e89a9a..d65068cbf61 100644 --- a/pkg/controller/instanceset/instance_util.go +++ b/pkg/controller/instanceset/instance_util.go @@ -39,7 +39,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" - workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" + workloads "github.com/apecloud/kubeblocks/apis/workloads/v1" "github.com/apecloud/kubeblocks/pkg/constant" "github.com/apecloud/kubeblocks/pkg/controller/builder" "github.com/apecloud/kubeblocks/pkg/controller/kubebuilderx" diff --git a/pkg/controller/instanceset/instance_util_test.go b/pkg/controller/instanceset/instance_util_test.go index 81aeac2d9c2..c0980223e4d 100644 --- a/pkg/controller/instanceset/instance_util_test.go +++ b/pkg/controller/instanceset/instance_util_test.go @@ -35,7 +35,7 @@ import ( "k8s.io/utils/pointer" "sigs.k8s.io/controller-runtime/pkg/client" - workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" + workloads "github.com/apecloud/kubeblocks/apis/workloads/v1" "github.com/apecloud/kubeblocks/pkg/constant" "github.com/apecloud/kubeblocks/pkg/controller/builder" "github.com/apecloud/kubeblocks/pkg/controller/kubebuilderx" diff --git a/pkg/controller/instanceset/object_builder.go b/pkg/controller/instanceset/object_builder.go index 097f5835f7a..d2378ad9dbe 100644 --- a/pkg/controller/instanceset/object_builder.go +++ b/pkg/controller/instanceset/object_builder.go @@ -28,7 +28,7 @@ import ( corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/util/intstr" - workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" + workloads "github.com/apecloud/kubeblocks/apis/workloads/v1" "github.com/apecloud/kubeblocks/pkg/constant" "github.com/apecloud/kubeblocks/pkg/controller/builder" "github.com/apecloud/kubeblocks/pkg/controllerutil" diff --git a/pkg/controller/instanceset/object_builder_test.go b/pkg/controller/instanceset/object_builder_test.go index 8953c57ed97..59e4e366247 100644 --- a/pkg/controller/instanceset/object_builder_test.go +++ b/pkg/controller/instanceset/object_builder_test.go @@ -28,7 +28,7 @@ import ( corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/util/intstr" - workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" + workloads "github.com/apecloud/kubeblocks/apis/workloads/v1" "github.com/apecloud/kubeblocks/pkg/constant" "github.com/apecloud/kubeblocks/pkg/controller/builder" ) diff --git a/pkg/controller/instanceset/pod_role_event_handler.go b/pkg/controller/instanceset/pod_role_event_handler.go index 28df2bbd9c0..0359e14ed8c 100644 --- a/pkg/controller/instanceset/pod_role_event_handler.go +++ b/pkg/controller/instanceset/pod_role_event_handler.go @@ -33,7 +33,7 @@ import ( "k8s.io/client-go/tools/record" "sigs.k8s.io/controller-runtime/pkg/client" - workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" + workloads "github.com/apecloud/kubeblocks/apis/workloads/v1" "github.com/apecloud/kubeblocks/pkg/common" "github.com/apecloud/kubeblocks/pkg/constant" "github.com/apecloud/kubeblocks/pkg/controller/multicluster" diff --git a/pkg/controller/instanceset/pod_role_event_handler_test.go b/pkg/controller/instanceset/pod_role_event_handler_test.go index 369b9f4394e..eb94949c9b8 100644 --- a/pkg/controller/instanceset/pod_role_event_handler_test.go +++ b/pkg/controller/instanceset/pod_role_event_handler_test.go @@ -31,7 +31,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" logf "sigs.k8s.io/controller-runtime/pkg/log" - workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" + workloads "github.com/apecloud/kubeblocks/apis/workloads/v1" "github.com/apecloud/kubeblocks/pkg/constant" "github.com/apecloud/kubeblocks/pkg/controller/builder" intctrlutil "github.com/apecloud/kubeblocks/pkg/controllerutil" diff --git a/pkg/controller/instanceset/reconciler_assistant_object.go b/pkg/controller/instanceset/reconciler_assistant_object.go index c1052a408a1..0b46c287d68 100644 --- a/pkg/controller/instanceset/reconciler_assistant_object.go +++ b/pkg/controller/instanceset/reconciler_assistant_object.go @@ -24,7 +24,7 @@ import ( "k8s.io/apimachinery/pkg/util/sets" "sigs.k8s.io/controller-runtime/pkg/client" - workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" + workloads "github.com/apecloud/kubeblocks/apis/workloads/v1" "github.com/apecloud/kubeblocks/pkg/controller/kubebuilderx" "github.com/apecloud/kubeblocks/pkg/controller/model" intctrlutil "github.com/apecloud/kubeblocks/pkg/controllerutil" diff --git a/pkg/controller/instanceset/reconciler_instance_alignment.go b/pkg/controller/instanceset/reconciler_instance_alignment.go index 642ba794d08..a00dc0310be 100644 --- a/pkg/controller/instanceset/reconciler_instance_alignment.go +++ b/pkg/controller/instanceset/reconciler_instance_alignment.go @@ -24,7 +24,7 @@ import ( corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/util/sets" - workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" + workloads "github.com/apecloud/kubeblocks/apis/workloads/v1" "github.com/apecloud/kubeblocks/pkg/controller/kubebuilderx" "github.com/apecloud/kubeblocks/pkg/controller/model" ) diff --git a/pkg/controller/instanceset/reconciler_instance_alignment_test.go b/pkg/controller/instanceset/reconciler_instance_alignment_test.go index 85551603291..53d2b93784c 100644 --- a/pkg/controller/instanceset/reconciler_instance_alignment_test.go +++ b/pkg/controller/instanceset/reconciler_instance_alignment_test.go @@ -31,7 +31,7 @@ import ( "k8s.io/apimachinery/pkg/util/intstr" "sigs.k8s.io/controller-runtime/pkg/client" - workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" + workloads "github.com/apecloud/kubeblocks/apis/workloads/v1" "github.com/apecloud/kubeblocks/pkg/controller/builder" "github.com/apecloud/kubeblocks/pkg/controller/kubebuilderx" ) diff --git a/pkg/controller/instanceset/reconciler_revision_update.go b/pkg/controller/instanceset/reconciler_revision_update.go index 2408a4dc6bb..29482207810 100644 --- a/pkg/controller/instanceset/reconciler_revision_update.go +++ b/pkg/controller/instanceset/reconciler_revision_update.go @@ -23,7 +23,7 @@ import ( corev1 "k8s.io/api/core/v1" "sigs.k8s.io/controller-runtime/pkg/client" - workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" + workloads "github.com/apecloud/kubeblocks/apis/workloads/v1" "github.com/apecloud/kubeblocks/pkg/controller/kubebuilderx" "github.com/apecloud/kubeblocks/pkg/controller/model" ) diff --git a/pkg/controller/instanceset/reconciler_revision_update_test.go b/pkg/controller/instanceset/reconciler_revision_update_test.go index 197006419c7..4af0e562694 100644 --- a/pkg/controller/instanceset/reconciler_revision_update_test.go +++ b/pkg/controller/instanceset/reconciler_revision_update_test.go @@ -25,7 +25,7 @@ import ( corev1 "k8s.io/api/core/v1" - workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" + workloads "github.com/apecloud/kubeblocks/apis/workloads/v1" "github.com/apecloud/kubeblocks/pkg/controller/builder" "github.com/apecloud/kubeblocks/pkg/controller/kubebuilderx" ) diff --git a/pkg/controller/instanceset/reconciler_status.go b/pkg/controller/instanceset/reconciler_status.go index 205bb57c410..88cd62c1ff9 100644 --- a/pkg/controller/instanceset/reconciler_status.go +++ b/pkg/controller/instanceset/reconciler_status.go @@ -30,7 +30,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/sets" - workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" + workloads "github.com/apecloud/kubeblocks/apis/workloads/v1" "github.com/apecloud/kubeblocks/pkg/constant" "github.com/apecloud/kubeblocks/pkg/controller/kubebuilderx" "github.com/apecloud/kubeblocks/pkg/controller/model" diff --git a/pkg/controller/instanceset/reconciler_status_test.go b/pkg/controller/instanceset/reconciler_status_test.go index 89f2a7e6092..054827e55fe 100644 --- a/pkg/controller/instanceset/reconciler_status_test.go +++ b/pkg/controller/instanceset/reconciler_status_test.go @@ -30,7 +30,7 @@ import ( corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" + workloads "github.com/apecloud/kubeblocks/apis/workloads/v1" "github.com/apecloud/kubeblocks/pkg/controller/builder" "github.com/apecloud/kubeblocks/pkg/controller/kubebuilderx" ) diff --git a/pkg/controller/instanceset/reconciler_update.go b/pkg/controller/instanceset/reconciler_update.go index 26adbd0fb42..353cd4604e9 100644 --- a/pkg/controller/instanceset/reconciler_update.go +++ b/pkg/controller/instanceset/reconciler_update.go @@ -29,7 +29,7 @@ import ( "k8s.io/apimachinery/pkg/util/intstr" "k8s.io/apimachinery/pkg/util/sets" - workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" + workloads "github.com/apecloud/kubeblocks/apis/workloads/v1" "github.com/apecloud/kubeblocks/pkg/controller/kubebuilderx" "github.com/apecloud/kubeblocks/pkg/controller/model" ) diff --git a/pkg/controller/instanceset/reconciler_update_test.go b/pkg/controller/instanceset/reconciler_update_test.go index 8ed437941b1..6d26f39c5d7 100644 --- a/pkg/controller/instanceset/reconciler_update_test.go +++ b/pkg/controller/instanceset/reconciler_update_test.go @@ -32,7 +32,7 @@ import ( "k8s.io/apimachinery/pkg/util/intstr" "sigs.k8s.io/controller-runtime/pkg/client" - workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" + workloads "github.com/apecloud/kubeblocks/apis/workloads/v1" "github.com/apecloud/kubeblocks/pkg/controller/builder" "github.com/apecloud/kubeblocks/pkg/controller/kubebuilderx" ) diff --git a/pkg/controller/instanceset/revision_util.go b/pkg/controller/instanceset/revision_util.go index ba138cf50f6..6f9ea5c2193 100644 --- a/pkg/controller/instanceset/revision_util.go +++ b/pkg/controller/instanceset/revision_util.go @@ -36,7 +36,7 @@ import ( "k8s.io/apimachinery/pkg/util/dump" "k8s.io/apimachinery/pkg/util/rand" - workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" + workloads "github.com/apecloud/kubeblocks/apis/workloads/v1" "github.com/apecloud/kubeblocks/pkg/controller/model" "github.com/apecloud/kubeblocks/pkg/lru" viper "github.com/apecloud/kubeblocks/pkg/viperx" diff --git a/pkg/controller/instanceset/revision_util_test.go b/pkg/controller/instanceset/revision_util_test.go index 93906594371..9347a12da3a 100644 --- a/pkg/controller/instanceset/revision_util_test.go +++ b/pkg/controller/instanceset/revision_util_test.go @@ -25,7 +25,7 @@ import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" - workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" + workloads "github.com/apecloud/kubeblocks/apis/workloads/v1" ) var _ = Describe("revision util test", func() { diff --git a/pkg/controller/instanceset/suite_test.go b/pkg/controller/instanceset/suite_test.go index 9f59ed2a8ab..5debe98c6b6 100644 --- a/pkg/controller/instanceset/suite_test.go +++ b/pkg/controller/instanceset/suite_test.go @@ -39,7 +39,7 @@ import ( "k8s.io/apimachinery/pkg/util/rand" logf "sigs.k8s.io/controller-runtime/pkg/log" - workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" + workloads "github.com/apecloud/kubeblocks/apis/workloads/v1" "github.com/apecloud/kubeblocks/pkg/constant" "github.com/apecloud/kubeblocks/pkg/controller/builder" "github.com/apecloud/kubeblocks/pkg/controller/kubebuilderx" diff --git a/pkg/controller/instanceset/tree_loader.go b/pkg/controller/instanceset/tree_loader.go index 322c7334c5e..ea3de56d94c 100644 --- a/pkg/controller/instanceset/tree_loader.go +++ b/pkg/controller/instanceset/tree_loader.go @@ -30,7 +30,7 @@ import ( ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" - workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" + workloads "github.com/apecloud/kubeblocks/apis/workloads/v1" "github.com/apecloud/kubeblocks/pkg/controller/kubebuilderx" "github.com/apecloud/kubeblocks/pkg/controller/model" ) diff --git a/pkg/controller/instanceset/tree_loader_test.go b/pkg/controller/instanceset/tree_loader_test.go index 87224e12196..d539917bd21 100644 --- a/pkg/controller/instanceset/tree_loader_test.go +++ b/pkg/controller/instanceset/tree_loader_test.go @@ -33,7 +33,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" logf "sigs.k8s.io/controller-runtime/pkg/log" - workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" + workloads "github.com/apecloud/kubeblocks/apis/workloads/v1" "github.com/apecloud/kubeblocks/pkg/controller/builder" "github.com/apecloud/kubeblocks/pkg/controller/model" testutil "github.com/apecloud/kubeblocks/pkg/testutil/k8s" diff --git a/pkg/controller/instanceset/update_plan.go b/pkg/controller/instanceset/update_plan.go index 2d7c0ede9c9..7c05e6aa60a 100644 --- a/pkg/controller/instanceset/update_plan.go +++ b/pkg/controller/instanceset/update_plan.go @@ -24,7 +24,7 @@ import ( corev1 "k8s.io/api/core/v1" - workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" + workloads "github.com/apecloud/kubeblocks/apis/workloads/v1" "github.com/apecloud/kubeblocks/pkg/controller/graph" "github.com/apecloud/kubeblocks/pkg/controller/model" intctrlutil "github.com/apecloud/kubeblocks/pkg/controllerutil" diff --git a/pkg/controller/instanceset/update_plan_test.go b/pkg/controller/instanceset/update_plan_test.go index ad1032f5438..a789130d9d5 100644 --- a/pkg/controller/instanceset/update_plan_test.go +++ b/pkg/controller/instanceset/update_plan_test.go @@ -27,7 +27,7 @@ import ( corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/util/sets" - workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" + workloads "github.com/apecloud/kubeblocks/apis/workloads/v1" "github.com/apecloud/kubeblocks/pkg/controller/builder" ) diff --git a/pkg/controller/instanceset/utils.go b/pkg/controller/instanceset/utils.go index c3d2419f938..b9ec43c7e00 100644 --- a/pkg/controller/instanceset/utils.go +++ b/pkg/controller/instanceset/utils.go @@ -31,7 +31,7 @@ import ( "k8s.io/apimachinery/pkg/util/sets" "k8s.io/utils/integer" - workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" + workloads "github.com/apecloud/kubeblocks/apis/workloads/v1" "github.com/apecloud/kubeblocks/pkg/constant" ) diff --git a/pkg/controller/instanceset/utils_test.go b/pkg/controller/instanceset/utils_test.go index 3cfc7cf4df8..69da686fc1b 100644 --- a/pkg/controller/instanceset/utils_test.go +++ b/pkg/controller/instanceset/utils_test.go @@ -28,7 +28,7 @@ import ( corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/util/intstr" - workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" + workloads "github.com/apecloud/kubeblocks/apis/workloads/v1" "github.com/apecloud/kubeblocks/pkg/controller/builder" ) diff --git a/pkg/controller/kubebuilderx/plan_builder.go b/pkg/controller/kubebuilderx/plan_builder.go index befa285e526..510091a5738 100644 --- a/pkg/controller/kubebuilderx/plan_builder.go +++ b/pkg/controller/kubebuilderx/plan_builder.go @@ -34,7 +34,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" - workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" + workloads "github.com/apecloud/kubeblocks/apis/workloads/v1" "github.com/apecloud/kubeblocks/pkg/controller/graph" "github.com/apecloud/kubeblocks/pkg/controller/model" ) diff --git a/pkg/controller/kubebuilderx/plan_builder_test.go b/pkg/controller/kubebuilderx/plan_builder_test.go index 8aaa44691a6..114610cc4cd 100644 --- a/pkg/controller/kubebuilderx/plan_builder_test.go +++ b/pkg/controller/kubebuilderx/plan_builder_test.go @@ -33,7 +33,7 @@ import ( "k8s.io/apimachinery/pkg/api/resource" "sigs.k8s.io/controller-runtime/pkg/client" - workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" + workloads "github.com/apecloud/kubeblocks/apis/workloads/v1" "github.com/apecloud/kubeblocks/pkg/constant" "github.com/apecloud/kubeblocks/pkg/controller/builder" "github.com/apecloud/kubeblocks/pkg/controller/model" diff --git a/pkg/controllerutil/instance_set_utils.go b/pkg/controllerutil/instance_set_utils.go index f1fdb4b0196..399f3e0e315 100644 --- a/pkg/controllerutil/instance_set_utils.go +++ b/pkg/controllerutil/instance_set_utils.go @@ -26,7 +26,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/client" - workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" + workloads "github.com/apecloud/kubeblocks/apis/workloads/v1" ) // GetPodListByInstanceSet gets ITS pod list. diff --git a/pkg/generics/type.go b/pkg/generics/type.go index afffae03549..da6004215ac 100644 --- a/pkg/generics/type.go +++ b/pkg/generics/type.go @@ -34,7 +34,7 @@ import ( appsv1beta1 "github.com/apecloud/kubeblocks/apis/apps/v1beta1" dpv1alpha1 "github.com/apecloud/kubeblocks/apis/dataprotection/v1alpha1" extensionsv1alpha1 "github.com/apecloud/kubeblocks/apis/extensions/v1alpha1" - workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" + workloads "github.com/apecloud/kubeblocks/apis/workloads/v1" ) // Object a generic representation of various resource object types diff --git a/pkg/testutil/apps/cluster_instance_set_test_util.go b/pkg/testutil/apps/cluster_instance_set_test_util.go index f74625f4a7e..61343e50c7e 100644 --- a/pkg/testutil/apps/cluster_instance_set_test_util.go +++ b/pkg/testutil/apps/cluster_instance_set_test_util.go @@ -34,7 +34,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" - workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" + workloads "github.com/apecloud/kubeblocks/apis/workloads/v1" "github.com/apecloud/kubeblocks/pkg/constant" "github.com/apecloud/kubeblocks/pkg/testutil" ) diff --git a/pkg/testutil/apps/instance_set_factoy.go b/pkg/testutil/apps/instance_set_factoy.go index 62ddd938d94..e8a12b99077 100644 --- a/pkg/testutil/apps/instance_set_factoy.go +++ b/pkg/testutil/apps/instance_set_factoy.go @@ -24,7 +24,7 @@ import ( corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" + workloads "github.com/apecloud/kubeblocks/apis/workloads/v1" "github.com/apecloud/kubeblocks/pkg/constant" ) diff --git a/pkg/testutil/k8s/instance_set_util.go b/pkg/testutil/k8s/instance_set_util.go index f7cff71dde0..5f9e819c2c3 100644 --- a/pkg/testutil/k8s/instance_set_util.go +++ b/pkg/testutil/k8s/instance_set_util.go @@ -27,7 +27,7 @@ import ( "k8s.io/apimachinery/pkg/types" "sigs.k8s.io/controller-runtime/pkg/client" - workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" + workloads "github.com/apecloud/kubeblocks/apis/workloads/v1" "github.com/apecloud/kubeblocks/pkg/constant" "github.com/apecloud/kubeblocks/pkg/testutil" ) From f0ca07db99e86d3e5a704cd56bb43dcb05a89edb Mon Sep 17 00:00:00 2001 From: Leon Date: Mon, 9 Sep 2024 13:17:33 +0800 Subject: [PATCH 10/15] add legacy definition back --- apis/apps/v1alpha1/cluster_conversion.go | 31 + apis/apps/v1alpha1/cluster_types.go | 28 + .../v1alpha1/clusterdefinition_conversion.go | 105 +- apis/apps/v1alpha1/clusterdefinition_types.go | 54 + .../clusterdefinition_types_legacy.go | 976 ++ apis/apps/v1alpha1/component_conversion.go | 64 +- .../componentdefinition_conversion.go | 24 + .../v1alpha1/componentdefinition_types.go | 462 +- .../v1alpha1/componentversion_conversion.go | 77 +- .../v1alpha1/servicedescriptor_conversion.go | 57 +- apis/apps/v1alpha1/type.go | 58 +- apis/apps/v1alpha1/zz_generated.deepcopy.go | 1042 +- .../v1alpha1/instanceset_conversion.go | 25 + ...apps.kubeblocks.io_clusterdefinitions.yaml | 9881 +++++++++++++++++ .../bases/apps.kubeblocks.io_clusters.yaml | 42 + ...ps.kubeblocks.io_componentdefinitions.yaml | 4158 +++++-- ...apps.kubeblocks.io_clusterdefinitions.yaml | 9881 +++++++++++++++++ .../crds/apps.kubeblocks.io_clusters.yaml | 42 + ...ps.kubeblocks.io_componentdefinitions.yaml | 4158 +++++-- docs/developer_docs/api-reference/cluster.md | 4408 ++++++-- go.mod | 1 + go.sum | 2 + 22 files changed, 32053 insertions(+), 3523 deletions(-) create mode 100644 apis/apps/v1alpha1/clusterdefinition_types_legacy.go diff --git a/apis/apps/v1alpha1/cluster_conversion.go b/apis/apps/v1alpha1/cluster_conversion.go index 6b26cb289da..8849725995a 100644 --- a/apis/apps/v1alpha1/cluster_conversion.go +++ b/apis/apps/v1alpha1/cluster_conversion.go @@ -20,15 +20,46 @@ along with this program. If not, see . package v1alpha1 import ( + "github.com/jinzhu/copier" "sigs.k8s.io/controller-runtime/pkg/conversion" + + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" ) // ConvertTo converts this Cluster to the Hub version (v1). func (r *Cluster) ConvertTo(dstRaw conversion.Hub) error { + dst := dstRaw.(*appsv1.Cluster) + + // objectMeta + dst.ObjectMeta = r.ObjectMeta + + // spec + copier.Copy(&dst.Spec, &r.Spec) + // TODO(v1.0): + // 1. add original Cluster definition back + // 2. changed fields + + // status + copier.Copy(&dst.Status, &r.Status) + return nil } // ConvertFrom converts from the Hub version (v1) to this version. func (r *Cluster) ConvertFrom(srcRaw conversion.Hub) error { + src := srcRaw.(*appsv1.Cluster) + + // objectMeta + r.ObjectMeta = src.ObjectMeta + + // spec + copier.Copy(&r.Spec, &src.Spec) + // TODO(v1.0): + // 1. add original Cluster definition back + // 2. changed fields + + // status + copier.Copy(&r.Status, &src.Status) + return nil } diff --git a/apis/apps/v1alpha1/cluster_types.go b/apis/apps/v1alpha1/cluster_types.go index 2324c4baf86..fc83f5f487c 100644 --- a/apis/apps/v1alpha1/cluster_types.go +++ b/apis/apps/v1alpha1/cluster_types.go @@ -606,6 +606,16 @@ type ClusterComponentSpec struct { // +optional ServiceVersion string `json:"serviceVersion,omitempty"` + // References the class defined in ComponentClassDefinition. + // + // Deprecated since v0.9. + // This field is maintained for backward compatibility and its use is discouraged. + // Existing usage should be updated to the current preferred approach to avoid compatibility issues in future releases. + // + // +kubebuilder:deprecatedversion:warning="This field has been deprecated since 0.9.0" + // +optional + ClassDefRef *ClassDefRef `json:"classDefRef,omitempty"` + // Defines a list of ServiceRef for a Component, enabling access to both external services and // Services provided by other Clusters. // @@ -800,6 +810,9 @@ type ClusterComponentSpec struct { // +optional UpdateStrategy *UpdateStrategy `json:"updateStrategy,omitempty"` + // TODO(v1.0): ? + // InstanceUpdateStrategy *InstanceUpdateStrategy + // Controls the concurrency of pods during initial scale up, when replacing pods on nodes, // or when scaling down. It only used when `PodManagementPolicy` is set to `Parallel`. // The default Concurrency is 100%. @@ -1299,6 +1312,21 @@ type ClusterComponentConfigSource struct { // - Local file } +// ClassDefRef is deprecated since v0.9. +type ClassDefRef struct { + // Specifies the name of the ComponentClassDefinition. + // + // +kubebuilder:validation:MaxLength=63 + // +kubebuilder:validation:Pattern:=`^[a-z0-9]([a-z0-9\.\-]*[a-z0-9])?$` + // +optional + Name string `json:"name,omitempty"` + + // Defines the name of the class that is defined in the ComponentClassDefinition. + // + // +kubebuilder:validation:Required + Class string `json:"class"` +} + // ClusterNetwork is deprecated since v0.9. type ClusterNetwork struct { // Indicates whether the host network can be accessed. By default, this is set to false. diff --git a/apis/apps/v1alpha1/clusterdefinition_conversion.go b/apis/apps/v1alpha1/clusterdefinition_conversion.go index b626dab9de0..d87ea9ba4b4 100644 --- a/apis/apps/v1alpha1/clusterdefinition_conversion.go +++ b/apis/apps/v1alpha1/clusterdefinition_conversion.go @@ -20,6 +20,7 @@ along with this program. If not, see . package v1alpha1 import ( + "github.com/jinzhu/copier" "sigs.k8s.io/controller-runtime/pkg/conversion" appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" @@ -33,13 +34,13 @@ func (r *ClusterDefinition) ConvertTo(dstRaw conversion.Hub) error { dst.ObjectMeta = r.ObjectMeta // spec - dst.Spec.Topologies = r.topologiesTo(r.Spec.Topologies) + copier.Copy(&dst.Spec, &r.Spec) + // TODO(v1.0): + // 1. add original ClusterDefinition definition back + // 2. changed fields // status - dst.Status.ObservedGeneration = r.Status.ObservedGeneration - dst.Status.Phase = appsv1.Phase(r.Status.Phase) - dst.Status.Message = r.Status.Message - dst.Status.Topologies = r.Status.Topologies + copier.Copy(&dst.Status, &r.Status) return nil } @@ -52,97 +53,13 @@ func (r *ClusterDefinition) ConvertFrom(srcRaw conversion.Hub) error { r.ObjectMeta = src.ObjectMeta // spec - r.Spec.Topologies = r.topologiesFrom(src.Spec.Topologies) + copier.Copy(&r.Spec, &src.Spec) + // TODO(v1.0): + // 1. add original ClusterDefinition definition back + // 2. changed fields // status - r.Status.ObservedGeneration = src.Status.ObservedGeneration - r.Status.Phase = Phase(src.Status.Phase) - r.Status.Message = src.Status.Message - r.Status.Topologies = src.Status.Topologies + copier.Copy(&r.Status, &src.Status) return nil } - -func (r *ClusterDefinition) topologiesTo(src []ClusterTopology) []appsv1.ClusterTopology { - if src != nil { - topologies := make([]appsv1.ClusterTopology, 0) - for _, topology := range src { - topologies = append(topologies, appsv1.ClusterTopology{ - Name: topology.Name, - Components: r.topologyComponentTo(topology.Components), - Orders: r.topologyOrdersTo(topology.Orders), - Default: topology.Default, - }) - } - return topologies - } - return nil -} - -func (r *ClusterDefinition) topologyComponentTo(src []ClusterTopologyComponent) []appsv1.ClusterTopologyComponent { - if src != nil { - comps := make([]appsv1.ClusterTopologyComponent, 0) - for _, comp := range src { - comps = append(comps, appsv1.ClusterTopologyComponent{ - Name: comp.Name, - CompDef: comp.CompDef, - }) - } - return comps - } - return nil -} - -func (r *ClusterDefinition) topologyOrdersTo(src *ClusterTopologyOrders) *appsv1.ClusterTopologyOrders { - if src != nil { - return &appsv1.ClusterTopologyOrders{ - Provision: src.Provision, - Terminate: src.Terminate, - Update: src.Update, - } - } - return nil -} - -func (r *ClusterDefinition) topologiesFrom(src []appsv1.ClusterTopology) []ClusterTopology { - if src != nil { - topologies := make([]ClusterTopology, 0) - for _, topology := range src { - topologies = append(topologies, ClusterTopology{ - Name: topology.Name, - Components: r.topologyComponentFrom(topology.Components), - Orders: r.topologyOrdersFrom(topology.Orders), - Default: topology.Default, - }) - } - return topologies - } - return nil -} - -func (r *ClusterDefinition) topologyComponentFrom(src []appsv1.ClusterTopologyComponent) []ClusterTopologyComponent { - if src != nil { - comps := make([]ClusterTopologyComponent, 0) - for _, comp := range src { - comps = append(comps, ClusterTopologyComponent{ - Name: comp.Name, - CompDef: comp.CompDef, - }) - } - return comps - } - return nil -} - -func (r *ClusterDefinition) topologyOrdersFrom(src *appsv1.ClusterTopologyOrders) *ClusterTopologyOrders { - if src != nil { - if src != nil { - return &ClusterTopologyOrders{ - Provision: src.Provision, - Terminate: src.Terminate, - Update: src.Update, - } - } - } - return nil -} diff --git a/apis/apps/v1alpha1/clusterdefinition_types.go b/apis/apps/v1alpha1/clusterdefinition_types.go index 3612f577700..607469df0d9 100644 --- a/apis/apps/v1alpha1/clusterdefinition_types.go +++ b/apis/apps/v1alpha1/clusterdefinition_types.go @@ -22,6 +22,60 @@ import ( // ClusterDefinitionSpec defines the desired state of ClusterDefinition. type ClusterDefinitionSpec struct { + // Specifies the well-known database type, such as mysql, redis, or mongodb. + // + // Deprecated since v0.9. + // This field is maintained for backward compatibility and its use is discouraged. + // Existing usage should be updated to the current preferred approach to avoid compatibility issues in future releases. + // + // +kubebuilder:validation:MaxLength=24 + // +kubebuilder:validation:Pattern:=`^[a-z0-9]([a-z0-9\-]*[a-z0-9])?$` + // +kubebuilder:deprecatedversion:warning="This field has been deprecated since 0.9.0" + // +optional + Type string `json:"type,omitempty"` + + // Provides the definitions for the cluster components. + // + // Deprecated since v0.9. + // Components should now be individually defined using ComponentDefinition and + // collectively referenced via `topology.components`. + // This field is maintained for backward compatibility and its use is discouraged. + // Existing usage should be updated to the current preferred approach to avoid compatibility issues in future releases. + // + // +kubebuilder:deprecatedversion:warning="This field has been deprecated since 0.9.0" + // +patchMergeKey=name + // +patchStrategy=merge,retainKeys + // +listType=map + // +listMapKey=name + // +optional + ComponentDefs []ClusterComponentDefinition `json:"componentDefs" patchStrategy:"merge,retainKeys" patchMergeKey:"name"` + + // Connection credential template used for creating a connection credential secret for cluster objects. + // + // Built-in objects are: + // + // - `$(RANDOM_PASSWD)` random 8 characters. + // - `$(STRONG_RANDOM_PASSWD)` random 16 characters, with mixed cases, digits and symbols. + // - `$(UUID)` generate a random UUID v4 string. + // - `$(UUID_B64)` generate a random UUID v4 BASE64 encoded string. + // - `$(UUID_STR_B64)` generate a random UUID v4 string then BASE64 encoded. + // - `$(UUID_HEX)` generate a random UUID v4 HEX representation. + // - `$(HEADLESS_SVC_FQDN)` headless service FQDN placeholder, value pattern is `$(CLUSTER_NAME)-$(1ST_COMP_NAME)-headless.$(NAMESPACE).svc`, + // where 1ST_COMP_NAME is the 1st component that provide `ClusterDefinition.spec.componentDefs[].service` attribute; + // - `$(SVC_FQDN)` service FQDN placeholder, value pattern is `$(CLUSTER_NAME)-$(1ST_COMP_NAME).$(NAMESPACE).svc`, + // where 1ST_COMP_NAME is the 1st component that provide `ClusterDefinition.spec.componentDefs[].service` attribute; + // - `$(SVC_PORT_{PORT-NAME})` is ServicePort's port value with specified port name, i.e, a servicePort JSON struct: + // `{"name": "mysql", "targetPort": "mysqlContainerPort", "port": 3306}`, and `$(SVC_PORT_mysql)` in the + // connection credential value is 3306. + // + // Deprecated since v0.9. + // This field is maintained for backward compatibility and its use is discouraged. + // Existing usage should be updated to the current preferred approach to avoid compatibility issues in future releases. + // + // +kubebuilder:deprecatedversion:warning="This field has been deprecated since 0.9.0" + // +optional + ConnectionCredential map[string]string `json:"connectionCredential,omitempty"` + // Topologies defines all possible topologies within the cluster. // // +kubebuilder:validation:MinItems=1 diff --git a/apis/apps/v1alpha1/clusterdefinition_types_legacy.go b/apis/apps/v1alpha1/clusterdefinition_types_legacy.go new file mode 100644 index 00000000000..d68d9de9329 --- /dev/null +++ b/apis/apps/v1alpha1/clusterdefinition_types_legacy.go @@ -0,0 +1,976 @@ +/* +Copyright (C) 2022-2024 ApeCloud Co., Ltd + +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 ( + appsv1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/util/intstr" + + workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" +) + +// ClusterComponentDefinition defines a Component within a ClusterDefinition but is deprecated and +// has been replaced by ComponentDefinition. +// +// Deprecated: Use ComponentDefinition instead. This type is deprecated as of version 0.8. +// +// +kubebuilder:validation:XValidation:rule="has(self.workloadType) && self.workloadType == 'Consensus' ? (has(self.consensusSpec) || has(self.rsmSpec)) : !has(self.consensusSpec)",message="componentDefs.consensusSpec(deprecated) or componentDefs.rsmSpec(recommended) is required when componentDefs.workloadType is Consensus, and forbidden otherwise" +type ClusterComponentDefinition struct { + // This name could be used as default name of `cluster.spec.componentSpecs.name`, and needs to conform with same + // validation rules as `cluster.spec.componentSpecs.name`, currently complying with IANA Service Naming rule. + // This name will apply to cluster objects as the value of label "apps.kubeblocks.io/component-name". + // + // +kubebuilder:validation:Required + // +kubebuilder:validation:MaxLength=22 + // +kubebuilder:validation:Pattern:=`^[a-z]([a-z0-9\-]*[a-z0-9])?$` + Name string `json:"name"` + + // Description of the component definition. + // + // +optional + Description string `json:"description,omitempty"` + + // Defines the type of the workload. + // + // - `Stateless` describes stateless applications. + // - `Stateful` describes common stateful applications. + // - `Consensus` describes applications based on consensus protocols, such as raft and paxos. + // - `Replication` describes applications based on the primary-secondary data replication protocol. + // + // +kubebuilder:validation:Required + WorkloadType WorkloadType `json:"workloadType"` + + // Defines well-known database component name, such as mongos(mongodb), proxy(redis), mariadb(mysql). + // + // +optional + CharacterType string `json:"characterType,omitempty"` + + // Defines the template of configurations. + // + // +patchMergeKey=name + // +patchStrategy=merge,retainKeys + // +listType=map + // +listMapKey=name + // +optional + ConfigSpecs []ComponentConfigSpec `json:"configSpecs,omitempty"` + + // Defines the template of scripts. + // + // +patchMergeKey=name + // +patchStrategy=merge,retainKeys + // +listType=map + // +listMapKey=name + // +optional + ScriptSpecs []ComponentTemplateSpec `json:"scriptSpecs,omitempty"` + + // Settings for health checks. + // + // +optional + Probes *ClusterDefinitionProbes `json:"probes,omitempty"` + + // Specify the logging files which can be observed and configured by cluster users. + // + // +patchMergeKey=name + // +patchStrategy=merge,retainKeys + // +listType=map + // +listMapKey=name + // +optional + LogConfigs []LogConfig `json:"logConfigs,omitempty" patchStrategy:"merge,retainKeys" patchMergeKey:"name"` + + // Defines the pod spec template of component. + // + // +kubebuilder:pruning:PreserveUnknownFields + // +optional + PodSpec *corev1.PodSpec `json:"podSpec,omitempty"` + + // Defines the service spec. + // + // +optional + Service *ServiceSpec `json:"service,omitempty"` + + // Defines spec for `Stateless` workloads. + // + // +kubebuilder:deprecatedversion:warning="This field is deprecated from KB 0.7.0, use RSMSpec instead." + // +optional + StatelessSpec *StatelessSetSpec `json:"statelessSpec,omitempty"` + + // Defines spec for `Stateful` workloads. + // + // +kubebuilder:deprecatedversion:warning="This field is deprecated from KB 0.7.0, use RSMSpec instead." + // +optional + StatefulSpec *StatefulSetSpec `json:"statefulSpec,omitempty"` + + // Defines spec for `Consensus` workloads. It's required if the workload type is `Consensus`. + // + // +kubebuilder:deprecatedversion:warning="This field is deprecated from KB 0.7.0, use RSMSpec instead." + // +optional + ConsensusSpec *ConsensusSetSpec `json:"consensusSpec,omitempty"` + + // Defines spec for `Replication` workloads. + // + // +kubebuilder:deprecatedversion:warning="This field is deprecated from KB 0.7.0, use RSMSpec instead." + // +optional + ReplicationSpec *ReplicationSetSpec `json:"replicationSpec,omitempty"` + + // Defines workload spec of this component. + // From KB 0.7.0, RSM(InstanceSetSpec) will be the underlying CR which powers all kinds of workload in KB. + // RSM is an enhanced stateful workload extension dedicated for heavy-state workloads like databases. + // + // +optional + RSMSpec *RSMSpec `json:"rsmSpec,omitempty"` + + // Defines the behavior of horizontal scale. + // + // +optional + HorizontalScalePolicy *HorizontalScalePolicy `json:"horizontalScalePolicy,omitempty"` + + // Defines system accounts needed to manage the component, and the statement to create them. + // + // +optional + SystemAccounts *SystemAccountSpec `json:"systemAccounts,omitempty"` + + // Used to describe the purpose of the volumes mapping the name of the VolumeMounts in the PodSpec.Container field, + // such as data volume, log volume, etc. When backing up the volume, the volume can be correctly backed up according + // to the volumeType. + // + // For example: + // + // - `name: data, type: data` means that the volume named `data` is used to store `data`. + // - `name: binlog, type: log` means that the volume named `binlog` is used to store `log`. + // + // NOTE: When volumeTypes is not defined, the backup function will not be supported, even if a persistent volume has + // been specified. + // + // +listType=map + // +listMapKey=name + // +optional + VolumeTypes []VolumeTypeSpec `json:"volumeTypes,omitempty"` + + // Used for custom label tags which you want to add to the component resources. + // + // +listType=map + // +listMapKey=key + // +optional + CustomLabelSpecs []CustomLabelSpec `json:"customLabelSpecs,omitempty"` + + // Defines command to do switchover. + // In particular, when workloadType=Replication, the command defined in switchoverSpec will only be executed under + // the condition of cluster.componentSpecs[x].SwitchPolicy.type=Noop. + // + // +optional + SwitchoverSpec *SwitchoverSpec `json:"switchoverSpec,omitempty"` + + // Defines the command to be executed when the component is ready, and the command will only be executed once after + // the component becomes ready. + // + // +optional + PostStartSpec *PostStartAction `json:"postStartSpec,omitempty"` + + // Defines settings to do volume protect. + // + // +optional + VolumeProtectionSpec *VolumeProtectionSpec `json:"volumeProtectionSpec,omitempty"` + + // Used to inject values from other components into the current component. Values will be saved and updated in a + // configmap and mounted to the current component. + // + // +patchMergeKey=componentDefName + // +patchStrategy=merge,retainKeys + // +listType=map + // +listMapKey=componentDefName + // +optional + ComponentDefRef []ComponentDefRef `json:"componentDefRef,omitempty" patchStrategy:"merge" patchMergeKey:"componentDefName"` + + // Used to declare the service reference of the current component. + // + // +optional + ServiceRefDeclarations []ServiceRefDeclaration `json:"serviceRefDeclarations,omitempty"` + + // Defines the metrics exporter. + // + // +optional + Exporter *Exporter `json:"exporter,omitempty"` + + // Deprecated since v0.9 + // monitor is monitoring config which provided by provider. + // + // +kubebuilder:deprecatedversion:warning="This field has been deprecated since 0.10.0" + // +optional + Monitor *MonitorConfig `json:"monitor,omitempty"` +} + +// WorkloadType defines the type of workload for the components of the ClusterDefinition. +// It can be one of the following: `Stateless`, `Stateful`, `Consensus`, or `Replication`. +// +// Deprecated since v0.8. +// +// +enum +// +kubebuilder:validation:Enum={Stateless,Stateful,Consensus,Replication} +type WorkloadType string + +const ( + // Stateless represents a workload type where components do not maintain state, and instances are interchangeable. + Stateless WorkloadType = "Stateless" + + // Stateful represents a workload type where components maintain state, and each instance has a unique identity. + Stateful WorkloadType = "Stateful" + + // Consensus represents a workload type involving distributed consensus algorithms for coordinated decision-making. + Consensus WorkloadType = "Consensus" + + // Replication represents a workload type that involves replication, typically used for achieving high availability + // and fault tolerance. + Replication WorkloadType = "Replication" +) + +// ClusterDefinitionProbes is deprecated since v0.8. +type ClusterDefinitionProbes struct { + // Specifies the probe used for checking the running status of the component. + // + // +optional + RunningProbe *ClusterDefinitionProbe `json:"runningProbe,omitempty"` + + // Specifies the probe used for checking the status of the component. + // + // +optional + StatusProbe *ClusterDefinitionProbe `json:"statusProbe,omitempty"` + + // Specifies the probe used for checking the role of the component. + // + // +kubebuilder:deprecatedversion:warning="This field is deprecated from KB 0.7.0, use RSMSpec instead." + // +optional + RoleProbe *ClusterDefinitionProbe `json:"roleProbe,omitempty"` + + // Defines the timeout (in seconds) for the role probe after all pods of the component are ready. + // The system will check if the application is available in the pod. + // If pods exceed the InitializationTimeoutSeconds time without a role label, this component will enter the + // Failed/Abnormal phase. + // + // Note that this configuration will only take effect if the component supports RoleProbe + // and will not affect the life cycle of the pod. default values are 60 seconds. + // + // +kubebuilder:validation:Minimum=30 + // +optional + RoleProbeTimeoutAfterPodsReady int32 `json:"roleProbeTimeoutAfterPodsReady,omitempty"` +} + +// ClusterDefinitionProbe is deprecated since v0.8. +type ClusterDefinitionProbe struct { + // How often (in seconds) to perform the probe. + // + // +kubebuilder:default=1 + // +kubebuilder:validation:Minimum=1 + PeriodSeconds int32 `json:"periodSeconds,omitempty"` + + // Number of seconds after which the probe times out. Defaults to 1 second. + // + // +kubebuilder:default=1 + // +kubebuilder:validation:Minimum=1 + TimeoutSeconds int32 `json:"timeoutSeconds,omitempty"` + + // Minimum consecutive failures for the probe to be considered failed after having succeeded. + // + // +kubebuilder:default=3 + // +kubebuilder:validation:Minimum=2 + FailureThreshold int32 `json:"failureThreshold,omitempty"` + + // Commands used to execute for probe. + // + // +optional + Commands *ClusterDefinitionProbeCMDs `json:"commands,omitempty"` +} + +// ClusterDefinitionProbeCMDs is deprecated since v0.8. +type ClusterDefinitionProbeCMDs struct { + // Defines write checks that are executed on the probe sidecar. + // + // +optional + Writes []string `json:"writes,omitempty"` + + // Defines read checks that are executed on the probe sidecar. + // + // +optional + Queries []string `json:"queries,omitempty"` +} + +// ServiceSpec is deprecated since v0.8. +type ServiceSpec struct { + // The list of ports that are exposed by this service. + // More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + // + // +patchMergeKey=port + // +patchStrategy=merge + // +listType=map + // +listMapKey=port + // +listMapKey=protocol + // +optional + Ports []ServicePort `json:"ports,omitempty" patchStrategy:"merge" patchMergeKey:"port" protobuf:"bytes,1,rep,name=ports"` + + // NOTES: name also need to be key +} + +// ServicePort is deprecated since v0.8. +type ServicePort struct { + // The name of this port within the service. This must be a DNS_LABEL. + // All ports within a ServiceSpec must have unique names. When considering + // the endpoints for a Service, this must match the 'name' field in the + // EndpointPort. + // +kubebuilder:validation:Required + Name string `json:"name,omitempty" protobuf:"bytes,1,opt,name=name"` + + // The IP protocol for this port. Supports "TCP", "UDP", and "SCTP". + // Default is TCP. + // +kubebuilder:validation:Enum={TCP,UDP,SCTP} + // +default="TCP" + // +optional + Protocol corev1.Protocol `json:"protocol,omitempty" protobuf:"bytes,2,opt,name=protocol,casttype=Protocol"` + + // The application protocol for this port. + // This field follows standard Kubernetes label syntax. + // Un-prefixed names are reserved for IANA standard service names (as per + // RFC-6335 and https://www.iana.org/assignments/service-names). + // Non-standard protocols should use prefixed names such as + // mycompany.com/my-custom-protocol. + // +optional + AppProtocol *string `json:"appProtocol,omitempty" protobuf:"bytes,6,opt,name=appProtocol"` + + // The port that will be exposed by this service. + Port int32 `json:"port" protobuf:"varint,3,opt,name=port"` + + // Number or name of the port to access on the pods targeted by the service. + // + // Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + // + // - If this is a string, it will be looked up as a named port in the target Pod's container ports. + // - If this is not specified, the value of the `port` field is used (an identity map). + // + // This field is ignored for services with clusterIP=None, and should be + // omitted or set equal to the `port` field. + // + // More info: https://kubernetes.io/docs/concepts/services-networking/service/#defining-a-service + // + // +kubebuilder:validation:XIntOrString + // +optional + TargetPort intstr.IntOrString `json:"targetPort,omitempty" protobuf:"bytes,4,opt,name=targetPort"` +} + +// StatelessSetSpec is deprecated since v0.7. +type StatelessSetSpec struct { + // Specifies the deployment strategy that will be used to replace existing pods with new ones. + // + // +patchStrategy=retainKeys + // +optional + UpdateStrategy appsv1.DeploymentStrategy `json:"updateStrategy,omitempty"` +} + +// StatefulSetSpec is deprecated since v0.7. +type StatefulSetSpec struct { + // Specifies the strategy for updating Pods. + // For workloadType=`Consensus`, the update strategy can be one of the following: + // + // - `Serial`: Updates Members sequentially to minimize component downtime. + // - `BestEffortParallel`: Updates Members in parallel to minimize component write downtime. Majority remains online + // at all times. + // - `Parallel`: Forces parallel updates. + // + // +kubebuilder:default=Serial + // +optional + UpdateStrategy UpdateStrategy `json:"updateStrategy,omitempty"` + + // Controls the creation of pods during initial scale up, replacement of pods on nodes, and scaling down. + // + // - `OrderedReady`: Creates pods in increasing order (pod-0, then pod-1, etc). The controller waits until each pod + // is ready before continuing. Pods are removed in reverse order when scaling down. + // - `Parallel`: Creates pods in parallel to match the desired scale without waiting. All pods are deleted at once + // when scaling down. + // + // +optional + LLPodManagementPolicy appsv1.PodManagementPolicyType `json:"llPodManagementPolicy,omitempty"` + + // Specifies the low-level StatefulSetUpdateStrategy to be used when updating Pods in the StatefulSet upon a + // revision to the Template. + // `UpdateStrategy` will be ignored if this is provided. + // + // +optional + LLUpdateStrategy *appsv1.StatefulSetUpdateStrategy `json:"llUpdateStrategy,omitempty"` +} + +// ConsensusSetSpec is deprecated since v0.7. +type ConsensusSetSpec struct { + StatefulSetSpec `json:",inline"` + + // Represents a single leader in the consensus set. + // + // +kubebuilder:validation:Required + Leader ConsensusMember `json:"leader"` + + // Members of the consensus set that have voting rights but are not the leader. + // + // +optional + Followers []ConsensusMember `json:"followers,omitempty"` + + // Represents a member of the consensus set that does not have voting rights. + // + // +optional + Learner *ConsensusMember `json:"learner,omitempty"` +} + +// ReplicationSetSpec is deprecated since v0.7. +type ReplicationSetSpec struct { + StatefulSetSpec `json:",inline"` +} + +// ConsensusMember is deprecated since v0.7. +type ConsensusMember struct { + // Specifies the name of the consensus member. + // + // +kubebuilder:validation:Required + // +kubebuilder:default=leader + Name string `json:"name"` + + // Specifies the services that this member is capable of providing. + // + // +kubebuilder:validation:Required + // +kubebuilder:default=ReadWrite + AccessMode AccessMode `json:"accessMode"` + + // Indicates the number of Pods that perform this role. + // The default is 1 for `Leader`, 0 for `Learner`, others for `Followers`. + // + // +kubebuilder:default=0 + // +kubebuilder:validation:Minimum=0 + // +optional + Replicas *int32 `json:"replicas,omitempty"` +} + +// RSMSpec is deprecated since v0.8. +type RSMSpec struct { + // Specifies a list of roles defined within the system. + // + // +optional + Roles []workloads.ReplicaRole `json:"roles,omitempty"` + + // Defines the method used to probe a role. + // + // +optional + RoleProbe *workloads.RoleProbe `json:"roleProbe,omitempty"` + + // Indicates the actions required for dynamic membership reconfiguration. + // + // +optional + MembershipReconfiguration *workloads.MembershipReconfiguration `json:"membershipReconfiguration,omitempty"` + + // Describes the strategy for updating Members (Pods). + // + // - `Serial`: Updates Members sequentially to ensure minimum component downtime. + // - `BestEffortParallel`: Updates Members in parallel to ensure minimum component write downtime. + // - `Parallel`: Forces parallel updates. + // + // +kubebuilder:validation:Enum={Serial,BestEffortParallel,Parallel} + // +optional + MemberUpdateStrategy *workloads.MemberUpdateStrategy `json:"memberUpdateStrategy,omitempty"` +} + +// HorizontalScalePolicy is deprecated since v0.8. +type HorizontalScalePolicy struct { + // Determines the data synchronization method when a component scales out. + // The policy can be one of the following: {None, CloneVolume}. The default policy is `None`. + // + // - `None`: This is the default policy. It creates an empty volume without data cloning. + // - `CloneVolume`: This policy clones data to newly scaled pods. It first tries to use a volume snapshot. + // If volume snapshot is not enabled, it will attempt to use a backup tool. If neither method works, it will report an error. + // - `Snapshot`: This policy is deprecated and is an alias for CloneVolume. + // + // +kubebuilder:default=None + // +optional + Type HScaleDataClonePolicyType `json:"type,omitempty"` + + // Refers to the backup policy template. + // + // +optional + BackupPolicyTemplateName string `json:"backupPolicyTemplateName,omitempty"` + + // Specifies the volumeMount of the container to backup. + // This only works if Type is not None. If not specified, the first volumeMount will be selected. + // + // +optional + VolumeMountsName string `json:"volumeMountsName,omitempty"` +} + +// HScaleDataClonePolicyType defines the data clone policy to be used during horizontal scaling. +// This policy determines how data is handled when new nodes are added to the cluster. +// The policy can be set to `None`, `CloneVolume`, or `Snapshot`. +// +// +enum +// +kubebuilder:validation:Enum={None,CloneVolume,Snapshot} +type HScaleDataClonePolicyType string + +const ( + // HScaleDataClonePolicyNone indicates that no data cloning will occur during horizontal scaling. + HScaleDataClonePolicyNone HScaleDataClonePolicyType = "None" + + // HScaleDataClonePolicyCloneVolume indicates that data will be cloned from existing volumes during horizontal scaling. + HScaleDataClonePolicyCloneVolume HScaleDataClonePolicyType = "CloneVolume" + + // HScaleDataClonePolicyFromSnapshot indicates that data will be cloned from a snapshot during horizontal scaling. + HScaleDataClonePolicyFromSnapshot HScaleDataClonePolicyType = "Snapshot" +) + +// SystemAccountSpec specifies information to create system accounts. +// +// Deprecated since v0.8, be replaced by `componentDefinition.spec.systemAccounts` and +// `componentDefinition.spec.lifecycleActions.accountProvision`. +type SystemAccountSpec struct { + // Configures how to obtain the client SDK and execute statements. + // + // +kubebuilder:validation:Required + CmdExecutorConfig *CmdExecutorConfig `json:"cmdExecutorConfig"` + + // Defines the pattern used to generate passwords for system accounts. + // + // +kubebuilder:validation:Required + PasswordConfig PasswordConfig `json:"passwordConfig"` + + // Defines the configuration settings for system accounts. + // + // +kubebuilder:validation:Required + // +kubebuilder:validation:MinItems=1 + // +patchMergeKey=name + // +patchStrategy=merge,retainKeys + // +listType=map + // +listMapKey=name + Accounts []SystemAccountConfig `json:"accounts" patchStrategy:"merge,retainKeys" patchMergeKey:"name"` +} + +// CmdExecutorConfig specifies how to perform creation and deletion statements. +// +// Deprecated since v0.8. +type CmdExecutorConfig struct { + CommandExecutorEnvItem `json:",inline"` + CommandExecutorItem `json:",inline"` +} + +// CommandExecutorEnvItem is deprecated since v0.8. +type CommandExecutorEnvItem struct { + // Specifies the image used to execute the command. + // + // +kubebuilder:validation:Required + Image string `json:"image"` + + // A list of environment variables that will be injected into the command execution context. + // + // +kubebuilder:pruning:PreserveUnknownFields + // +patchMergeKey=name + // +patchStrategy=merge,retainKeys + // +optional + Env []corev1.EnvVar `json:"env,omitempty" patchStrategy:"merge" patchMergeKey:"name"` +} + +// CommandExecutorItem is deprecated since v0.8. +type CommandExecutorItem struct { + // The command to be executed. + // + // +kubebuilder:validation:Required + // +kubebuilder:validation:MinItems=1 + Command []string `json:"command"` + + // Additional parameters used in the execution of the command. + // + // +optional + Args []string `json:"args,omitempty"` +} + +// SystemAccountConfig specifies how to create and delete system accounts. +// +// Deprecated since v0.9. +type SystemAccountConfig struct { + // The unique identifier of a system account. + // + // +kubebuilder:validation:Required + Name AccountName `json:"name"` + + // Outlines the strategy for creating the account. + // + // +kubebuilder:validation:Required + ProvisionPolicy ProvisionPolicy `json:"provisionPolicy"` +} + +// AccountName defines system account names. +// +enum +// +kubebuilder:validation:Enum={kbadmin,kbdataprotection,kbprobe,kbmonitoring,kbreplicator} +type AccountName string + +const ( + AdminAccount AccountName = "kbadmin" + DataprotectionAccount AccountName = "kbdataprotection" + ProbeAccount AccountName = "kbprobe" + MonitorAccount AccountName = "kbmonitoring" + ReplicatorAccount AccountName = "kbreplicator" +) + +// ProvisionPolicy defines the policy details for creating accounts. +// +// Deprecated since v0.9. +type ProvisionPolicy struct { + // Specifies the method to provision an account. + // + // +kubebuilder:validation:Required + Type ProvisionPolicyType `json:"type"` + + // Defines the scope within which the account is provisioned. + // + // +kubebuilder:default=AnyPods + Scope ProvisionScope `json:"scope"` + + // The statement to provision an account. + // + // +optional + Statements *ProvisionStatements `json:"statements,omitempty"` + + // The external secret to refer. + // + // +optional + SecretRef *ProvisionSecretRef `json:"secretRef,omitempty"` +} + +// ProvisionPolicyType defines the policy for creating accounts. +// +// +enum +// +kubebuilder:validation:Enum={CreateByStmt,ReferToExisting} +type ProvisionPolicyType string + +const ( + // CreateByStmt will create account w.r.t. deletion and creation statement given by provider. + CreateByStmt ProvisionPolicyType = "CreateByStmt" + + // ReferToExisting will not create account, but create a secret by copying data from referred secret file. + ReferToExisting ProvisionPolicyType = "ReferToExisting" +) + +// ProvisionScope defines the scope of provision within a component. +// +// +enum +type ProvisionScope string + +const ( + // AllPods indicates that accounts will be created for all pods within the component. + AllPods ProvisionScope = "AllPods" + + // AnyPods indicates that accounts will be created only on a single pod within the component. + AnyPods ProvisionScope = "AnyPods" +) + +// ProvisionStatements defines the statements used to create accounts. +// +// Deprecated since v0.9. +type ProvisionStatements struct { + // Specifies the statement required to create a new account with the necessary privileges. + // + // +kubebuilder:validation:Required + CreationStatement string `json:"creation"` + + // Defines the statement required to update the password of an existing account. + // + // +optional + UpdateStatement string `json:"update,omitempty"` + + // Defines the statement required to delete an existing account. + // Typically used in conjunction with the creation statement to delete an account before recreating it. + // For example, one might use a `drop user if exists` statement followed by a `create user` statement to ensure a fresh account. + // + // Deprecated: This field is deprecated and the update statement should be used instead. + // + // +optional + DeletionStatement string `json:"deletion,omitempty"` +} + +// VolumeTypeSpec is deprecated since v0.9, replaced with ComponentVolume. +type VolumeTypeSpec struct { + // Corresponds to the name of the VolumeMounts field in PodSpec.Container. + // + // +kubebuilder:validation:Required + // +kubebuilder:validation:Pattern:=`^[a-z0-9]([a-z0-9\.\-]*[a-z0-9])?$` + Name string `json:"name"` + + // Type of data the volume will persistent. + // + // +optional + Type VolumeType `json:"type,omitempty"` +} + +// VolumeType defines the type of volume, specifically distinguishing between volumes used for backup data and those used for logs. +// +// +enum +// +kubebuilder:validation:Enum={data,log} +type VolumeType string + +const ( + // VolumeTypeData indicates a volume designated for storing backup data. This type of volume is optimized for the + // storage and retrieval of data backups, ensuring data persistence and reliability. + VolumeTypeData VolumeType = "data" + + // VolumeTypeLog indicates a volume designated for storing logs. This type of volume is optimized for log data, + // facilitating efficient log storage, retrieval, and management. + VolumeTypeLog VolumeType = "log" +) + +// CustomLabelSpec is deprecated since v0.8. +type CustomLabelSpec struct { + // The key of the label. + // + // +kubebuilder:validation:Required + Key string `json:"key"` + + // The value of the label. + // + // +kubebuilder:validation:Required + Value string `json:"value"` + + // The resources that will be patched with the label. + // + // +kubebuilder:validation:Required + Resources []GVKResource `json:"resources,omitempty"` +} + +// GVKResource is deprecated since v0.8. +type GVKResource struct { + // Represents the GVK of a resource, such as "v1/Pod", "apps/v1/StatefulSet", etc. + // When a resource matching this is found by the selector, a custom label will be added if it doesn't already exist, + // or updated if it does. + // + // +kubebuilder:validation:Required + GVK string `json:"gvk"` + + // A label query used to filter a set of resources. + // + // +optional + Selector map[string]string `json:"selector,omitempty"` +} + +// SwitchoverSpec is deprecated since v0.8. +type SwitchoverSpec struct { + // Represents the action of switching over to a specified candidate primary or leader instance. + // + // +optional + WithCandidate *SwitchoverAction `json:"withCandidate,omitempty"` + + // Represents the action of switching over without specifying a candidate primary or leader instance. + // + // +optional + WithoutCandidate *SwitchoverAction `json:"withoutCandidate,omitempty"` +} + +// SwitchoverAction is deprecated since v0.8. +type SwitchoverAction struct { + // Specifies the switchover command. + // + // +kubebuilder:validation:Required + CmdExecutorConfig *CmdExecutorConfig `json:"cmdExecutorConfig"` + + // Used to select the script that need to be referenced. + // When defined, the scripts defined in scriptSpecs can be referenced within the SwitchoverAction.CmdExecutorConfig. + // + // +kubebuilder:deprecatedversion:warning="This field is deprecated from KB 0.9.0" + // +optional + ScriptSpecSelectors []ScriptSpecSelector `json:"scriptSpecSelectors,omitempty"` +} + +type ScriptSpecSelector struct { + // Represents the name of the ScriptSpec referent. + // + // +kubebuilder:validation:Required + // +kubebuilder:validation:MaxLength=63 + // +kubebuilder:validation:Pattern:=`^[a-z0-9]([a-z0-9\.\-]*[a-z0-9])?$` + Name string `json:"name"` +} + +// PostStartAction is deprecated since v0.8. +type PostStartAction struct { + // Specifies the post-start command to be executed. + // + // +kubebuilder:validation:Required + CmdExecutorConfig CmdExecutorConfig `json:"cmdExecutorConfig"` + + // Used to select the script that need to be referenced. + // When defined, the scripts defined in scriptSpecs can be referenced within the CmdExecutorConfig. + // + // +optional + ScriptSpecSelectors []ScriptSpecSelector `json:"scriptSpecSelectors,omitempty"` +} + +// VolumeProtectionSpec is deprecated since v0.9, replaced with ComponentVolume.HighWatermark. +type VolumeProtectionSpec struct { + // The high watermark threshold for volume space usage. + // If there is any specified volumes who's space usage is over the threshold, the pre-defined "LOCK" action + // will be triggered to degrade the service to protect volume from space exhaustion, such as to set the instance + // as read-only. And after that, if all volumes' space usage drops under the threshold later, the pre-defined + // "UNLOCK" action will be performed to recover the service normally. + // + // +kubebuilder:validation:Maximum=100 + // +kubebuilder:validation:Minimum=0 + // +kubebuilder:default=90 + // +optional + HighWatermark int `json:"highWatermark,omitempty"` + + // The Volumes to be protected. + // + // +optional + Volumes []ProtectedVolume `json:"volumes,omitempty"` +} + +type ProtectedVolume struct { + // The Name of the volume to protect. + // + // +optional + Name string `json:"name,omitempty"` + + // Defines the high watermark threshold for the volume, it will override the component level threshold. + // If the value is invalid, it will be ignored and the component level threshold will be used. + // + // +kubebuilder:validation:Maximum=100 + // +kubebuilder:validation:Minimum=0 + // +optional + HighWatermark *int `json:"highWatermark,omitempty"` +} + +// ComponentDefRef is used to select the component and its fields to be referenced. +// +// Deprecated since v0.8. +type ComponentDefRef struct { + // The name of the componentDef to be selected. + // + // +kubebuilder:validation:Required + ComponentDefName string `json:"componentDefName"` + + // Defines the policy to be followed in case of a failure in finding the component. + // + // +kubebuilder:validation:Enum={Ignore,Fail} + // +default="Ignore" + // +optional + FailurePolicy FailurePolicyType `json:"failurePolicy,omitempty"` + + // The values that are to be injected as environment variables into each component. + // + // +kbubebuilder:validation:Required + // +patchMergeKey=name + // +patchStrategy=merge,retainKeys + // +listType=map + // +listMapKey=name + // +optional + ComponentRefEnvs []ComponentRefEnv `json:"componentRefEnv" patchStrategy:"merge" patchMergeKey:"name"` +} + +// ComponentRefEnv specifies name and value of an env. +// +// Deprecated since v0.8. +type ComponentRefEnv struct { + // The name of the env, it must be a C identifier. + // + // +kubebuilder:validation:Required + // +kubebuilder:validation:Pattern=`^[A-Za-z_][A-Za-z0-9_]*$` + Name string `json:"name"` + + // The value of the env. + // + // +optional + Value string `json:"value,omitempty"` + + // The source from which the value of the env. + // + // +optional + ValueFrom *ComponentValueFrom `json:"valueFrom,omitempty"` +} + +// ComponentValueFrom is deprecated since v0.8. +type ComponentValueFrom struct { + // Specifies the source to select. It can be one of three types: `FieldRef`, `ServiceRef`, `HeadlessServiceRef`. + // + // +kubebuilder:validation:Enum={FieldRef,ServiceRef,HeadlessServiceRef} + // +kubebuilder:validation:Required + Type ComponentValueFromType `json:"type"` + + // The jsonpath of the source to select when the Type is `FieldRef`. + // Two objects are registered in the jsonpath: `componentDef` and `components`: + // + // - `componentDef` is the component definition object specified in `componentRef.componentDefName`. + // - `components` are the component list objects referring to the component definition object. + // + // +optional + FieldPath string `json:"fieldPath,omitempty"` + + // Defines the format of each headless service address. + // Three builtin variables can be used as placeholders: `$POD_ORDINAL`, `$POD_FQDN`, `$POD_NAME` + // + // - `$POD_ORDINAL` represents the ordinal of the pod. + // - `$POD_FQDN` represents the fully qualified domain name of the pod. + // - `$POD_NAME` represents the name of the pod. + // + // +kubebuilder:default=="$POD_FQDN" + // +optional + Format string `json:"format,omitempty"` + + // The string used to join the values of headless service addresses. + // + // +kubebuilder:default="," + // +optional + JoinWith string `json:"joinWith,omitempty"` +} + +// ComponentValueFromType specifies the type of component value from which the data is derived. +// +// Deprecated since v0.8. +// +// +enum +// +kubebuilder:validation:Enum={FieldRef,ServiceRef,HeadlessServiceRef} +type ComponentValueFromType string + +const ( + // FromFieldRef refers to the value of a specific field in the object. + FromFieldRef ComponentValueFromType = "FieldRef" + // FromServiceRef refers to a service within the same namespace as the object. + FromServiceRef ComponentValueFromType = "ServiceRef" + // FromHeadlessServiceRef refers to a headless service within the same namespace as the object. + FromHeadlessServiceRef ComponentValueFromType = "HeadlessServiceRef" +) + +type MonitorConfig struct { + // builtIn is a switch to enable KubeBlocks builtIn monitoring. + // If BuiltIn is set to true, monitor metrics will be scraped automatically. + // If BuiltIn is set to false, the provider should set ExporterConfig and Sidecar container own. + // +kubebuilder:default=false + // +optional + BuiltIn bool `json:"builtIn,omitempty"` + + // exporterConfig provided by provider, which specify necessary information to Time Series Database. + // exporterConfig is valid when builtIn is false. + // +optional + Exporter *ExporterConfig `json:"exporterConfig,omitempty"` +} + +type ExporterConfig struct { + // scrapePort is exporter port for Time Series Database to scrape metrics. + // +kubebuilder:validation:Required + // +kubebuilder:validation:XIntOrString + ScrapePort intstr.IntOrString `json:"scrapePort"` + + // scrapePath is exporter url path for Time Series Database to scrape metrics. + // +kubebuilder:validation:MaxLength=128 + // +kubebuilder:default="/metrics" + // +optional + ScrapePath string `json:"scrapePath,omitempty"` +} diff --git a/apis/apps/v1alpha1/component_conversion.go b/apis/apps/v1alpha1/component_conversion.go index 9a150bb4ed0..703f9875ee7 100644 --- a/apis/apps/v1alpha1/component_conversion.go +++ b/apis/apps/v1alpha1/component_conversion.go @@ -20,8 +20,14 @@ along with this program. If not, see . package v1alpha1 import ( - appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" + "encoding/json" + "k8s.io/apimachinery/pkg/runtime" + + "github.com/jinzhu/copier" + corev1 "k8s.io/api/core/v1" "sigs.k8s.io/controller-runtime/pkg/conversion" + + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" ) // ConvertTo converts this Component to the Hub version (v1). @@ -32,13 +38,16 @@ func (r *Component) ConvertTo(dstRaw conversion.Hub) error { dst.ObjectMeta = r.ObjectMeta // spec - // TODO(v1.0) + copier.Copy(&dst.Spec, &r.Spec) + convertor := &incrementConvertor{ + deleted: &componentDeleted{}, + } + if err := convertor.convertTo(r, dst); err != nil { + return err + } // status - dst.Status.ObservedGeneration = r.Status.ObservedGeneration - dst.Status.Conditions = r.Status.Conditions - dst.Status.Phase = appsv1.ClusterComponentPhase(r.Status.Phase) - dst.Status.Message = r.Status.Message + copier.Copy(&dst.Status, &r.Status) return nil } @@ -51,13 +60,46 @@ func (r *Component) ConvertFrom(srcRaw conversion.Hub) error { r.ObjectMeta = src.ObjectMeta // spec - // TODO(v1.0) + copier.Copy(&r.Spec, &src.Spec) + convertor := &incrementConvertor{ + deleted: &componentDeleted{}, + } + if err := convertor.convertFrom(src, r); err != nil { + return err + } // status - r.Status.ObservedGeneration = src.Status.ObservedGeneration - r.Status.Conditions = src.Status.Conditions - r.Status.Phase = ClusterComponentPhase(src.Status.Phase) - r.Status.Message = src.Status.Message + copier.Copy(&r.Status, &src.Status) + + return nil +} + +type componentDeleted struct { + affinity *Affinity `json:"affinity,omitempty"` + tolerations []corev1.Toleration `json:"tolerations,omitempty"` +} + +func (r *componentDeleted) To(obj runtime.Object) ([]byte, error) { + comp := obj.(*Component) + diff := &componentDeleted{ + affinity: comp.Spec.Affinity, + tolerations: comp.Spec.Tolerations, + } + out, err := json.Marshal(diff) + if err != nil { + return nil, err + } + return out, nil +} +func (r *componentDeleted) From(data []byte, obj runtime.Object) error { + diff := &componentDeleted{} + err := json.Unmarshal(data, diff) + if err != nil { + return err + } + comp := obj.(*Component) + comp.Spec.Affinity = diff.affinity + comp.Spec.Tolerations = diff.tolerations return nil } diff --git a/apis/apps/v1alpha1/componentdefinition_conversion.go b/apis/apps/v1alpha1/componentdefinition_conversion.go index 7eb6e7d4caf..4e6417adc59 100644 --- a/apis/apps/v1alpha1/componentdefinition_conversion.go +++ b/apis/apps/v1alpha1/componentdefinition_conversion.go @@ -20,15 +20,39 @@ along with this program. If not, see . package v1alpha1 import ( + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" + "github.com/jinzhu/copier" "sigs.k8s.io/controller-runtime/pkg/conversion" ) // ConvertTo converts this ComponentDefinition to the Hub version (v1). func (r *ComponentDefinition) ConvertTo(dstRaw conversion.Hub) error { + dst := dstRaw.(*appsv1.ComponentDefinition) + + // objectMeta + dst.ObjectMeta = r.ObjectMeta + + // spec + copier.Copy(&dst.Spec, &r.Spec) // TODO(v1.0): changed fields + + // status + copier.Copy(&dst.Status, &r.Status) + return nil } // ConvertFrom converts from the Hub version (v1) to this version. func (r *ComponentDefinition) ConvertFrom(srcRaw conversion.Hub) error { + src := srcRaw.(*appsv1.ComponentDefinition) + + // objectMeta + r.ObjectMeta = src.ObjectMeta + + // spec + copier.Copy(&r.Spec, &src.Spec) // TODO(v1.0): changed fields + + // status + copier.Copy(&r.Status, &src.Status) + return nil } diff --git a/apis/apps/v1alpha1/componentdefinition_types.go b/apis/apps/v1alpha1/componentdefinition_types.go index 250fab10dd5..56dc16e8d9d 100644 --- a/apis/apps/v1alpha1/componentdefinition_types.go +++ b/apis/apps/v1alpha1/componentdefinition_types.go @@ -17,6 +17,7 @@ limitations under the License. package v1alpha1 import ( + "k8s.io/apimachinery/pkg/util/intstr" "time" appsv1 "k8s.io/api/apps/v1" @@ -193,6 +194,13 @@ type ComponentDefinitionSpec struct { // +kubebuilder:validation:Required Runtime corev1.PodSpec `json:"runtime"` + // Deprecated since v0.9 + // monitor is monitoring config which provided by provider. + // + // +kubebuilder:deprecatedversion:warning="This field has been deprecated since 0.10.0" + // +optional + Monitor *MonitorConfig `json:"monitor,omitempty"` + // Defines the built-in metrics exporter container. // // +optional @@ -466,6 +474,16 @@ type ComponentDefinitionSpec struct { // +optional Roles []ReplicaRole `json:"roles,omitempty"` + // This field has been deprecated since v0.9. + // This field is maintained for backward compatibility and its use is discouraged. + // Existing usage should be updated to the current preferred approach to avoid compatibility issues in future releases. + // + // This field is immutable. + // + // +kubebuilder:default=External + // +optional + RoleArbitrator *RoleArbitrator `json:"roleArbitrator,omitempty"` + // Defines a set of hooks and procedures that customize the behavior of a Component throughout its lifecycle. // Actions are triggered at specific lifecycle stages: // @@ -644,6 +662,18 @@ type Exporter struct { ScrapeScheme PrometheusScheme `json:"scrapeScheme,omitempty"` } +// RoleArbitrator defines how to arbitrate the role of replicas. +// +// Deprecated since v0.9 +// +enum +// +kubebuilder:validation:Enum={External,Lorry} +type RoleArbitrator string + +const ( + ExternalRoleArbitrator RoleArbitrator = "External" + LorryRoleArbitrator RoleArbitrator = "Lorry" +) + // ReplicaRole represents a role that can be assumed by a component instance. type ReplicaRole struct { // Defines the role's identifier. It is used to set the "apps.kubeblocks.io/role" label value @@ -696,28 +726,48 @@ const ( OrdinalSelector TargetPodSelector = "Ordinal" ) -// ExecAction describes an Action that executes a command inside a container. -type ExecAction struct { - // Specifies the container image to be used for running the Action. +// HTTPAction describes an Action that triggers HTTP requests. +// HTTPAction is to be implemented in future version. +type HTTPAction struct { + // Specifies the endpoint to be requested on the HTTP server. // - // When specified, a dedicated container will be created using this image to execute the Action. - // All actions with same image will share the same container. + // +optional + Path string `json:"path,omitempty"` + + // Specifies the target port for the HTTP request. + // It can be specified either as a numeric value in the range of 1 to 65535, + // or as a named port that meets the IANA_SVC_NAME specification. + Port intstr.IntOrString `json:"port"` + + // Indicates the server's domain name or IP address. Defaults to the Pod's IP. + // Prefer setting the "Host" header in httpHeaders when needed. // - // This field cannot be updated. + // +optional + Host string `json:"host,omitempty"` + + // Designates the protocol used to make the request, such as HTTP or HTTPS. + // If not specified, HTTP is used by default. // // +optional - Image string `json:"image,omitempty"` + Scheme corev1.URIScheme `json:"scheme,omitempty"` - // Represents a list of environment variables that will be injected into the container. - // These variables enable the container to adapt its behavior based on the environment it's running in. + // Represents the type of HTTP request to be made, such as "GET," "POST," "PUT," etc. + // If not specified, "GET" is the default method. // - // This field cannot be updated. + // +optional + Method string `json:"method,omitempty"` + + // Allows for the inclusion of custom headers in the request. + // HTTP permits the use of repeated headers. // // +optional - // +patchMergeKey=name - // +patchStrategy=merge - Env []corev1.EnvVar `json:"env,omitempty" patchStrategy:"merge" patchMergeKey:"name"` + HTTPHeaders []corev1.HTTPHeader `json:"httpHeaders,omitempty"` +} +// ExecAction describes an Action that executes a command inside a container. +// Which may run as a K8s job or be executed inside the Lorry sidecar container, depending on the implementation. +// Future implementations will standardize execution within Lorry. +type ExecAction struct { // Specifies the command to be executed inside the container. // The working directory for this command is the container's root directory('/'). // Commands are executed directly without a shell environment, meaning shell-specific syntax ('|', etc.) is not supported. @@ -726,51 +776,12 @@ type ExecAction struct { // A successful execution is indicated by an exit status of 0; any non-zero status signifies a failure. // // +optional - Command []string `json:"command,omitempty"` + Command []string `json:"command,omitempty" protobuf:"bytes,1,rep,name=command"` // Args represents the arguments that are passed to the `command` for execution. // // +optional Args []string `json:"args,omitempty"` - - // Defines the criteria used to select the target Pod(s) for executing the Action. - // This is useful when there is no default target replica identified. - // It allows for precise control over which Pod(s) the Action should run in. - // - // If not specified, the Action will be executed in the pod where the Action is triggered, such as the pod - // to be removed or added; or a random pod if the Action is triggered at the component level, such as - // post-provision or pre-terminate of the component. - // - // This field cannot be updated. - // - // +optional - TargetPodSelector TargetPodSelector `json:"targetPodSelector,omitempty"` - - // Used in conjunction with the `targetPodSelector` field to refine the selection of target pod(s) for Action execution. - // The impact of this field depends on the `targetPodSelector` value: - // - // - When `targetPodSelector` is set to `Any` or `All`, this field will be ignored. - // - When `targetPodSelector` is set to `Role`, only those replicas whose role matches the `matchingKey` - // will be selected for the Action. - // - // This field cannot be updated. - // - // +optional - MatchingKey string `json:"matchingKey,omitempty"` - - // Specifies the name of the container within the same pod whose resources will be shared with the action. - // This allows the action to utilize the specified container's resources without executing within it. - // - // The name must match one of the containers defined in `componentDefinition.spec.runtime`. - // - // The resources that can be shared are included: - // - // - volume mounts - // - // This field cannot be updated. - // - // +optional - Container string `json:"container,omitempty"` } type RetryPolicy struct { @@ -825,6 +836,8 @@ const ( // Actions can be executed in different ways: // // - ExecAction: Executes a command inside a container. +// which may run as a K8s job or be executed inside the Lorry sidecar container, depending on the implementation. +// Future implementations will standardize execution within Lorry. // A set of predefined environment variables are available and can be leveraged within the `exec.command` // to access context information such as details about pods, components, the overall cluster state, // or database connection credentials. @@ -845,6 +858,16 @@ const ( // - If an action encounters any errors, error messages should be written to stderr, // or detailed in the HTTP response with the appropriate non-200 status code. type Action struct { + // Specifies the container image to be used for running the Action. + // + // When specified, a dedicated container will be created using this image to execute the Action. + // This field is mutually exclusive with the `container` field; only one of them should be provided. + // + // This field cannot be updated. + // + // +optional + Image string `json:"image,omitempty"` + // Defines the command to run. // // This field cannot be updated. @@ -852,6 +875,63 @@ type Action struct { // +optional Exec *ExecAction `json:"exec,omitempty"` + // Specifies the HTTP request to perform. + // + // This field cannot be updated. + // + // Note: HTTPAction is to be implemented in future version. + // + // +optional + HTTP *HTTPAction `json:"http,omitempty"` + + // Represents a list of environment variables that will be injected into the container. + // These variables enable the container to adapt its behavior based on the environment it's running in. + // + // This field cannot be updated. + // + // +optional + // +patchMergeKey=name + // +patchStrategy=merge + Env []corev1.EnvVar `json:"env,omitempty" patchStrategy:"merge" patchMergeKey:"name"` + + // Defines the criteria used to select the target Pod(s) for executing the Action. + // This is useful when there is no default target replica identified. + // It allows for precise control over which Pod(s) the Action should run in. + // + // This field cannot be updated. + // + // Note: This field is reserved for future use and is not currently active. + // + // +optional + TargetPodSelector TargetPodSelector `json:"targetPodSelector,omitempty"` + + // Used in conjunction with the `targetPodSelector` field to refine the selection of target pod(s) for Action execution. + // The impact of this field depends on the `targetPodSelector` value: + // + // - When `targetPodSelector` is set to `Any` or `All`, this field will be ignored. + // - When `targetPodSelector` is set to `Role`, only those replicas whose role matches the `matchingKey` + // will be selected for the Action. + // + // This field cannot be updated. + // + // Note: This field is reserved for future use and is not currently active. + // + // +optional + MatchingKey string `json:"matchingKey,omitempty"` + + // Defines the name of the container within the target Pod where the action will be executed. + // + // This name must correspond to one of the containers defined in `componentDefinition.spec.runtime`. + // If this field is not specified, the default behavior is to use the first container listed in + // `componentDefinition.spec.runtime`. + // + // This field cannot be updated. + // + // Note: This field is reserved for future use and is not currently active. + // + // +optional + Container string `json:"container,omitempty"` + // Specifies the maximum duration in seconds that the Action is allowed to run. // // If the Action does not complete within this time frame, it will be terminated. @@ -930,10 +1010,34 @@ type ComponentLifecycleActions struct { // // The PostProvision Action is intended to run only once. // + // The container executing this action has access to following environment variables: + // + // - KB_CLUSTER_POD_IP_LIST: Comma-separated list of the cluster's pod IP addresses (e.g., "podIp1,podIp2"). + // - KB_CLUSTER_POD_NAME_LIST: Comma-separated list of the cluster's pod names (e.g., "pod1,pod2"). + // - KB_CLUSTER_POD_HOST_NAME_LIST: Comma-separated list of host names, each corresponding to a pod in + // KB_CLUSTER_POD_NAME_LIST (e.g., "hostName1,hostName2"). + // - KB_CLUSTER_POD_HOST_IP_LIST: Comma-separated list of host IP addresses, each corresponding to a pod in + // KB_CLUSTER_POD_NAME_LIST (e.g., "hostIp1,hostIp2"). + // + // - KB_CLUSTER_COMPONENT_POD_NAME_LIST: Comma-separated list of all pod names within the component + // (e.g., "pod1,pod2"). + // - KB_CLUSTER_COMPONENT_POD_IP_LIST: Comma-separated list of pod IP addresses, + // matching the order of pods in KB_CLUSTER_COMPONENT_POD_NAME_LIST (e.g., "podIp1,podIp2"). + // - KB_CLUSTER_COMPONENT_POD_HOST_NAME_LIST: Comma-separated list of host names for each pod, + // matching the order of pods in KB_CLUSTER_COMPONENT_POD_NAME_LIST (e.g., "hostName1,hostName2"). + // - KB_CLUSTER_COMPONENT_POD_HOST_IP_LIST: Comma-separated list of host IP addresses for each pod, + // matching the order of pods in KB_CLUSTER_COMPONENT_POD_NAME_LIST (e.g., "hostIp1,hostIp2"). + // + // - KB_CLUSTER_COMPONENT_LIST: Comma-separated list of all cluster components (e.g., "comp1,comp2"). + // - KB_CLUSTER_COMPONENT_DELETING_LIST: Comma-separated list of components that are currently being deleted + // (e.g., "comp1,comp2"). + // - KB_CLUSTER_COMPONENT_UNDELETED_LIST: Comma-separated list of components that are not being deleted + // (e.g., "comp1,comp2"). + // // Note: This field is immutable once it has been set. // // +optional - PostProvision *Action `json:"postProvision,omitempty"` + PostProvision *LifecycleActionHandler `json:"postProvision,omitempty"` // Specifies the hook to be executed prior to terminating a component. // @@ -943,14 +1047,44 @@ type ComponentLifecycleActions struct { // The actual termination and cleanup of the Component and its associated resources will not proceed // until the PreTerminate action has completed successfully. // + // The container executing this action has access to following environment variables: + // + // - KB_CLUSTER_POD_IP_LIST: Comma-separated list of the cluster's pod IP addresses (e.g., "podIp1,podIp2"). + // - KB_CLUSTER_POD_NAME_LIST: Comma-separated list of the cluster's pod names (e.g., "pod1,pod2"). + // - KB_CLUSTER_POD_HOST_NAME_LIST: Comma-separated list of host names, each corresponding to a pod in + // KB_CLUSTER_POD_NAME_LIST (e.g., "hostName1,hostName2"). + // - KB_CLUSTER_POD_HOST_IP_LIST: Comma-separated list of host IP addresses, each corresponding to a pod in + // KB_CLUSTER_POD_NAME_LIST (e.g., "hostIp1,hostIp2"). + // + // - KB_CLUSTER_COMPONENT_POD_NAME_LIST: Comma-separated list of all pod names within the component + // (e.g., "pod1,pod2"). + // - KB_CLUSTER_COMPONENT_POD_IP_LIST: Comma-separated list of pod IP addresses, + // matching the order of pods in KB_CLUSTER_COMPONENT_POD_NAME_LIST (e.g., "podIp1,podIp2"). + // - KB_CLUSTER_COMPONENT_POD_HOST_NAME_LIST: Comma-separated list of host names for each pod, + // matching the order of pods in KB_CLUSTER_COMPONENT_POD_NAME_LIST (e.g., "hostName1,hostName2"). + // - KB_CLUSTER_COMPONENT_POD_HOST_IP_LIST: Comma-separated list of host IP addresses for each pod, + // matching the order of pods in KB_CLUSTER_COMPONENT_POD_NAME_LIST (e.g., "hostIp1,hostIp2"). + // + // - KB_CLUSTER_COMPONENT_LIST: Comma-separated list of all cluster components (e.g., "comp1,comp2"). + // - KB_CLUSTER_COMPONENT_DELETING_LIST: Comma-separated list of components that are currently being deleted + // (e.g., "comp1,comp2"). + // - KB_CLUSTER_COMPONENT_UNDELETED_LIST: Comma-separated list of components that are not being deleted + // (e.g., "comp1,comp2"). + // + // - KB_CLUSTER_COMPONENT_IS_SCALING_IN: Indicates whether the component is currently scaling in. + // If this variable is present and set to "true", it denotes that the component is undergoing a scale-in operation. + // During scale-in, data rebalancing is necessary to maintain cluster integrity. + // Contrast this with a cluster deletion scenario where data rebalancing is not required as the entire cluster + // is being cleaned up. + // // Note: This field is immutable once it has been set. // // +optional - PreTerminate *Action `json:"preTerminate,omitempty"` + PreTerminate *LifecycleActionHandler `json:"preTerminate,omitempty"` // Defines the procedure which is invoked regularly to assess the role of replicas. // - // This action is periodically triggered at the specified interval to determine the role of each replica. + // This action is periodically triggered by Lorry at the specified interval to determine the role of each replica. // Upon successful execution, the action's output designates the role of the replica, // which should match one of the predefined role names within `componentDefinition.spec.roles`. // The output is then compared with the previous successful execution result. @@ -961,9 +1095,12 @@ type ComponentLifecycleActions struct { // It ensures replicas are correctly labeled with their respective roles. // Without this, services that rely on roleSelectors might improperly direct traffic to wrong replicas. // - // The container executing this action has access to following variables: + // The container executing this action has access to following environment variables: // // - KB_POD_FQDN: The FQDN of the Pod whose role is being assessed. + // - KB_SERVICE_PORT: The port used by the database service. + // - KB_SERVICE_USER: The username with the necessary permissions to interact with the database service. + // - KB_SERVICE_PASSWORD: The corresponding password for KB_SERVICE_USER to authenticate with the database service. // // Expected output of this action: // - On Success: The determined role of the replica, which must align with one of the roles specified @@ -973,22 +1110,30 @@ type ComponentLifecycleActions struct { // Note: This field is immutable once it has been set. // // +optional - RoleProbe *Probe `json:"roleProbe,omitempty"` + RoleProbe *RoleProbe `json:"roleProbe,omitempty"` // Defines the procedure for a controlled transition of leadership from the current leader to a new replica. // This approach aims to minimize downtime and maintain availability in systems with a leader-follower topology, // during events such as planned maintenance or when performing stop, shutdown, restart, or upgrade operations // involving the current leader node. // - // The container executing this action has access to following variables: + // The container executing this action has access to following environment variables: // // - KB_SWITCHOVER_CANDIDATE_NAME: The name of the pod for the new leader candidate, which may not be specified (empty). // - KB_SWITCHOVER_CANDIDATE_FQDN: The FQDN of the new leader candidate's pod, which may not be specified (empty). + // - KB_LEADER_POD_IP: The IP address of the current leader's pod prior to the switchover. + // - KB_LEADER_POD_NAME: The name of the current leader's pod prior to the switchover. + // - KB_LEADER_POD_FQDN: The FQDN of the current leader's pod prior to the switchover. + // + // The environment variables with the following prefixes are deprecated and will be removed in future releases: + // + // - KB_REPLICATION_PRIMARY_POD_ + // - KB_CONSENSUS_LEADER_POD_ // // Note: This field is immutable once it has been set. // // +optional - Switchover *Action `json:"switchover,omitempty"` + Switchover *ComponentSwitchover `json:"switchover,omitempty"` // Defines the procedure to add a new replica to the replication group. // @@ -998,10 +1143,15 @@ type ComponentLifecycleActions struct { // implementation, or automatically by the database kernel or a sidecar utility like Patroni that implements // a consensus algorithm. // - // The container executing this action has access to following variables: + // The container executing this action has access to following environment variables: // - // - KB_JOIN_MEMBER_POD_FQDN: The pod FQDN of the replica being added to the group. - // - KB_JOIN_MEMBER_POD_NAME: The pod name of the replica being added to the group. + // - KB_SERVICE_PORT: The port used by the database service. + // - KB_SERVICE_USER: The username with the necessary permissions to interact with the database service. + // - KB_SERVICE_PASSWORD: The corresponding password for KB_SERVICE_USER to authenticate with the database service. + // - KB_PRIMARY_POD_FQDN: The FQDN of the primary Pod within the replication group. + // - KB_MEMBER_ADDRESSES: A comma-separated list of Pod addresses for all replicas in the group. + // - KB_NEW_MEMBER_POD_NAME: The pod name of the replica being added to the group. + // - KB_NEW_MEMBER_POD_IP: The IP address of the replica being added to the group. // // Expected action output: // - On Failure: An error message detailing the reason for any failure encountered @@ -1014,14 +1164,17 @@ type ComponentLifecycleActions struct { // - bash // - -c // - | - // CLIENT="mysql -u $SERVICE_USER -p$SERVICE_PASSWORD -P $SERVICE_PORT -h $SERVICE_HOST -e" - // $CLIENT "ALTER SYSTEM ADD SERVER '$KB_POD_FQDN:$SERVICE_PORT' ZONE 'zone1'" + // ADDRESS=$(KB_MEMBER_ADDRESSES%%,*) + // HOST=$(echo $ADDRESS | cut -d ':' -f 1) + // PORT=$(echo $ADDRESS | cut -d ':' -f 2) + // CLIENT="mysql -u $KB_SERVICE_USER -p$KB_SERVICE_PASSWORD -P $PORT -h $HOST -e" + // $CLIENT "ALTER SYSTEM ADD SERVER '$KB_NEW_MEMBER_POD_IP:$KB_SERVICE_PORT' ZONE 'zone1'" // ``` // // Note: This field is immutable once it has been set. // // +optional - MemberJoin *Action `json:"memberJoin,omitempty"` + MemberJoin *LifecycleActionHandler `json:"memberJoin,omitempty"` // Defines the procedure to remove a replica from the replication group. // @@ -1032,10 +1185,15 @@ type ComponentLifecycleActions struct { // The process typically includes updating configurations and informing other group members about the removal. // Data migration is generally not part of this action and should be handled separately if needed. // - // The container executing this action has access to following variables: + // The container executing this action has access to following environment variables: // - // - KB_LEAVE_MEMBER_POD_FQDN: The pod name of the replica being removed from the group. + // - KB_SERVICE_PORT: The port used by the database service. + // - KB_SERVICE_USER: The username with the necessary permissions to interact with the database service. + // - KB_SERVICE_PASSWORD: The corresponding password for KB_SERVICE_USER to authenticate with the database service. + // - KB_PRIMARY_POD_FQDN: The FQDN of the primary Pod within the replication group. + // - KB_MEMBER_ADDRESSES: A comma-separated list of Pod addresses for all replicas in the group. // - KB_LEAVE_MEMBER_POD_NAME: The pod name of the replica being removed from the group. + // - KB_LEAVE_MEMBER_POD_IP: The IP address of the replica being removed from the group. // // Expected action output: // - On Failure: An error message, if applicable, indicating why the action failed. @@ -1047,14 +1205,17 @@ type ComponentLifecycleActions struct { // - bash // - -c // - | - // CLIENT="mysql -u $SERVICE_USER -p$SERVICE_PASSWORD -P $SERVICE_PORT -h $SERVICE_HOST -e" - // $CLIENT "ALTER SYSTEM DELETE SERVER '$KB_POD_FQDN:$SERVICE_PORT' ZONE 'zone1'" + // ADDRESS=$(KB_MEMBER_ADDRESSES%%,*) + // HOST=$(echo $ADDRESS | cut -d ':' -f 1) + // PORT=$(echo $ADDRESS | cut -d ':' -f 2) + // CLIENT="mysql -u $KB_SERVICE_USER -p$KB_SERVICE_PASSWORD -P $PORT -h $HOST -e" + // $CLIENT "ALTER SYSTEM DELETE SERVER '$KB_LEAVE_MEMBER_POD_IP:$KB_SERVICE_PORT' ZONE 'zone1'" // ``` // // Note: This field is immutable once it has been set. // // +optional - MemberLeave *Action `json:"memberLeave,omitempty"` + MemberLeave *LifecycleActionHandler `json:"memberLeave,omitempty"` // Defines the procedure to switch a replica into the read-only state. // @@ -1064,6 +1225,9 @@ type ComponentLifecycleActions struct { // The container executing this action has access to following environment variables: // // - KB_POD_FQDN: The FQDN of the replica pod whose role is being checked. + // - KB_SERVICE_PORT: The port used by the database service. + // - KB_SERVICE_USER: The username with the necessary permissions to interact with the database service. + // - KB_SERVICE_PASSWORD: The corresponding password for KB_SERVICE_USER to authenticate with the database service. // // Expected action output: // - On Failure: An error message, if applicable, indicating why the action failed. @@ -1071,7 +1235,7 @@ type ComponentLifecycleActions struct { // Note: This field is immutable once it has been set. // // +optional - Readonly *Action `json:"readonly,omitempty"` + Readonly *LifecycleActionHandler `json:"readonly,omitempty"` // Defines the procedure to transition a replica from the read-only state back to the read-write state. // @@ -1083,6 +1247,9 @@ type ComponentLifecycleActions struct { // The container executing this action has access to following environment variables: // // - KB_POD_FQDN: The FQDN of the replica pod whose role is being checked. + // - KB_SERVICE_PORT: The port used by the database service. + // - KB_SERVICE_USER: The username with the necessary permissions to interact with the database service. + // - KB_SERVICE_PASSWORD: The corresponding password for KB_SERVICE_USER to authenticate with the database service. // // Expected action output: // - On Failure: An error message, if applicable, indicating why the action failed. @@ -1090,7 +1257,7 @@ type ComponentLifecycleActions struct { // Note: This field is immutable once it has been set. // // +optional - Readwrite *Action `json:"readwrite,omitempty"` + Readwrite *LifecycleActionHandler `json:"readwrite,omitempty"` // Defines the procedure for exporting the data from a replica. // @@ -1109,7 +1276,7 @@ type ComponentLifecycleActions struct { // Note: This field is immutable once it has been set. // // +optional - DataDump *Action `json:"dataDump,omitempty"` + DataDump *LifecycleActionHandler `json:"dataDump,omitempty"` // Defines the procedure for importing data into a replica. // @@ -1127,7 +1294,7 @@ type ComponentLifecycleActions struct { // Note: This field is immutable once it has been set. // // +optional - DataLoad *Action `json:"dataLoad,omitempty"` + DataLoad *LifecycleActionHandler `json:"dataLoad,omitempty"` // Defines the procedure that update a replica with new configuration. // @@ -1136,7 +1303,7 @@ type ComponentLifecycleActions struct { // This Action is reserved for future versions. // // +optional - Reconfigure *Action `json:"reconfigure,omitempty"` + Reconfigure *LifecycleActionHandler `json:"reconfigure,omitempty"` // Defines the procedure to generate a new database account. // @@ -1144,14 +1311,145 @@ type ComponentLifecycleActions struct { // This action is designed to create system accounts that are utilized for replication, monitoring, backup, // and other administrative tasks. // - // The container executing this action has access to following variables: + // Note: This field is immutable once it has been set. // - // - KB_ACCOUNT_NAME: The name of the system account to be created. - // - KB_ACCOUNT_PASSWORD: The password for the system account. // TODO: how to pass the password securely? - // - KB_ACCOUNT_STATEMENT: The statement used to create the system account. + // +optional + AccountProvision *LifecycleActionHandler `json:"accountProvision,omitempty"` +} + +// LifecycleActionHandler describes the implementation of a specific lifecycle action. +// +// Each action is deemed successful if it returns an exit code of 0 for command executions, +// or an HTTP 200 status for HTTP(s) actions. +// Any other exit code or HTTP status is considered an indication of failure. +type LifecycleActionHandler struct { + // Specifies the name of the predefined action handler to be invoked for lifecycle actions. // - // Note: This field is immutable once it has been set. + // Lorry, as a sidecar agent co-located with the database container in the same Pod, + // includes a suite of built-in action implementations that are tailored to different database engines. + // These are known as "builtin" handlers, includes: `mysql`, `redis`, `mongodb`, `etcd`, + // `postgresql`, `official-postgresql`, `apecloud-postgresql`, `wesql`, `oceanbase`, `polardbx`. + // + // If the `builtinHandler` field is specified, it instructs Lorry to utilize its internal built-in action handler + // to execute the specified lifecycle actions. + // + // The `builtinHandler` field is of type `BuiltinActionHandlerType`, + // which represents the name of the built-in handler. + // The `builtinHandler` specified within the same `ComponentLifecycleActions` should be consistent across all + // actions. + // This means that if you specify a built-in handler for one action, you should use the same handler + // for all other actions throughout the entire `ComponentLifecycleActions` collection. + // + // If you need to define lifecycle actions for database engines not covered by the existing built-in support, + // or when the pre-existing built-in handlers do not meet your specific needs, + // you can use the `customHandler` field to define your own action implementation. + // + // Deprecation Notice: + // + // - In the future, the `builtinHandler` field will be deprecated in favor of using the `customHandler` field + // for configuring all lifecycle actions. + // - Instead of using a name to indicate the built-in action implementations in Lorry, + // the recommended approach will be to explicitly invoke the desired action implementation through + // a gRPC interface exposed by the sidecar agent. + // - Developers will have the flexibility to either use the built-in action implementations provided by Lorry + // or develop their own sidecar agent to implement custom actions and expose them via gRPC interfaces. + // - This change will allow for greater customization and extensibility of lifecycle actions, + // as developers can create their own "builtin" implementations tailored to their specific requirements. + // + // +optional + BuiltinHandler *BuiltinActionHandlerType `json:"builtinHandler,omitempty"` + + // Specifies a user-defined hook or procedure that is called to perform the specific lifecycle action. + // It offers a flexible and expandable approach for customizing the behavior of a Component by leveraging + // tailored actions. + // + // An Action can be implemented as either an ExecAction or an HTTPAction, with future versions planning + // to support GRPCAction, + // thereby accommodating unique logic for different database systems within the Action's framework. + // + // In future iterations, all built-in handlers are expected to transition to GRPCAction. + // This change means that Lorry or other sidecar agents will expose the implementation of actions + // through a GRPC interface for external invocation. + // Then the controller will interact with these actions via GRPCAction calls. + // + // +optional + CustomHandler *Action `json:"customHandler,omitempty"` +} + +// BuiltinActionHandlerType defines build-in action handlers provided by Lorry, including: +// +// - `mysql` +// - `wesql` +// - `oceanbase` +// - `redis` +// - `mongodb` +// - `etcd` +// - `postgresql` +// - `official-postgresql` +// - `apecloud-postgresql` +// - `polardbx` +// - `custom` +// - `unknown` +type BuiltinActionHandlerType string + +const ( + MySQLBuiltinActionHandler BuiltinActionHandlerType = "mysql" + WeSQLBuiltinActionHandler BuiltinActionHandlerType = "wesql" + OceanbaseBuiltinActionHandler BuiltinActionHandlerType = "oceanbase" + RedisBuiltinActionHandler BuiltinActionHandlerType = "redis" + MongoDBBuiltinActionHandler BuiltinActionHandlerType = "mongodb" + ETCDBuiltinActionHandler BuiltinActionHandlerType = "etcd" + PostgresqlBuiltinActionHandler BuiltinActionHandlerType = "postgresql" + OfficialPostgresqlBuiltinActionHandler BuiltinActionHandlerType = "official-postgresql" + ApeCloudPostgresqlBuiltinActionHandler BuiltinActionHandlerType = "apecloud-postgresql" + PolarDBXBuiltinActionHandler BuiltinActionHandlerType = "polardbx" + CustomActionHandler BuiltinActionHandlerType = "custom" + UnknownBuiltinActionHandler BuiltinActionHandlerType = "unknown" +) + +type RoleProbe struct { + LifecycleActionHandler `json:",inline"` + + // Specifies the number of seconds to wait after the container has started before the RoleProbe + // begins to detect the container's role. + // + // +optional + InitialDelaySeconds int32 `json:"initialDelaySeconds,omitempty" protobuf:"varint,2,opt,name=initialDelaySeconds"` + + // Specifies the number of seconds after which the probe times out. + // Defaults to 1 second. Minimum value is 1. + // + // +optional + TimeoutSeconds int32 `json:"timeoutSeconds,omitempty" protobuf:"varint,3,opt,name=timeoutSeconds"` + + // Specifies the frequency at which the probe is conducted. This value is expressed in seconds. + // Default to 10 seconds. Minimum value is 1. + // + // +optional + PeriodSeconds int32 `json:"periodSeconds,omitempty" protobuf:"varint,4,opt,name=periodSeconds"` +} + +type ComponentSwitchover struct { + // Represents the switchover process for a specified candidate primary or leader instance. + // Note that only Action.Exec is currently supported, while Action.HTTP is not. + // + // +optional + WithCandidate *Action `json:"withCandidate,omitempty"` + + // Represents a switchover process that does not involve a specific candidate primary or leader instance. + // As with the previous field, only Action.Exec is currently supported, not Action.HTTP. + // + // +optional + WithoutCandidate *Action `json:"withoutCandidate,omitempty"` + + // Used to define the selectors for the scriptSpecs that need to be referenced. + // If this field is set, the scripts defined under the 'scripts' field can be invoked or referenced within an Action. + // + // This field is deprecated from v0.9. + // This field is maintained for backward compatibility and its use is discouraged. + // Existing usage should be updated to the current preferred approach to avoid compatibility issues in future releases. // + // +kubebuilder:deprecatedversion:warning="This field is deprecated from KB 0.9.0" // +optional - AccountProvision *Action `json:"accountProvision,omitempty"` + ScriptSpecSelectors []ScriptSpecSelector `json:"scriptSpecSelectors,omitempty"` } diff --git a/apis/apps/v1alpha1/componentversion_conversion.go b/apis/apps/v1alpha1/componentversion_conversion.go index f5a493b1f65..031042bde38 100644 --- a/apis/apps/v1alpha1/componentversion_conversion.go +++ b/apis/apps/v1alpha1/componentversion_conversion.go @@ -20,6 +20,7 @@ along with this program. If not, see . package v1alpha1 import ( + "github.com/jinzhu/copier" "sigs.k8s.io/controller-runtime/pkg/conversion" appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" @@ -33,14 +34,10 @@ func (r *ComponentVersion) ConvertTo(dstRaw conversion.Hub) error { dst.ObjectMeta = r.ObjectMeta // spec - dst.Spec.CompatibilityRules = r.compatibilityRulesTo(r.Spec.CompatibilityRules) - dst.Spec.Releases = r.releasesTo(r.Spec.Releases) + copier.Copy(&dst.Spec, &r.Spec) // status - dst.Status.ObservedGeneration = r.Status.ObservedGeneration - dst.Status.Phase = appsv1.Phase(r.Status.Phase) - dst.Status.Message = r.Status.Message - dst.Status.ServiceVersions = r.Status.ServiceVersions + copier.Copy(&dst.Status, &r.Status) return nil } @@ -53,74 +50,10 @@ func (r *ComponentVersion) ConvertFrom(srcRaw conversion.Hub) error { r.ObjectMeta = src.ObjectMeta // spec - r.Spec.CompatibilityRules = r.compatibilityRulesFrom(src.Spec.CompatibilityRules) - r.Spec.Releases = r.releasesFrom(src.Spec.Releases) + copier.Copy(&r.Spec, &src.Spec) // status - r.Status.ObservedGeneration = src.Status.ObservedGeneration - r.Status.Phase = Phase(src.Status.Phase) - r.Status.Message = src.Status.Message - r.Status.ServiceVersions = src.Status.ServiceVersions + copier.Copy(&r.Status, &src.Status) return nil } - -func (r *ComponentVersion) compatibilityRulesTo(src []ComponentVersionCompatibilityRule) []appsv1.ComponentVersionCompatibilityRule { - if src != nil { - rules := make([]appsv1.ComponentVersionCompatibilityRule, 0) - for _, rule := range src { - rules = append(rules, appsv1.ComponentVersionCompatibilityRule{ - CompDefs: rule.CompDefs, - Releases: rule.Releases, - }) - } - return rules - } - return nil -} - -func (r *ComponentVersion) compatibilityRulesFrom(src []appsv1.ComponentVersionCompatibilityRule) []ComponentVersionCompatibilityRule { - if src != nil { - rules := make([]ComponentVersionCompatibilityRule, 0) - for _, rule := range src { - rules = append(rules, ComponentVersionCompatibilityRule{ - CompDefs: rule.CompDefs, - Releases: rule.Releases, - }) - } - return rules - } - return nil -} - -func (r *ComponentVersion) releasesTo(src []ComponentVersionRelease) []appsv1.ComponentVersionRelease { - if src != nil { - releases := make([]appsv1.ComponentVersionRelease, 0) - for _, release := range src { - releases = append(releases, appsv1.ComponentVersionRelease{ - Name: release.Name, - Changes: release.Changes, - ServiceVersion: release.ServiceVersion, - Images: release.Images, - }) - } - return releases - } - return nil -} - -func (r *ComponentVersion) releasesFrom(src []appsv1.ComponentVersionRelease) []ComponentVersionRelease { - if src != nil { - releases := make([]ComponentVersionRelease, 0) - for _, release := range src { - releases = append(releases, ComponentVersionRelease{ - Name: release.Name, - Changes: release.Changes, - ServiceVersion: release.ServiceVersion, - Images: release.Images, - }) - } - return releases - } - return nil -} diff --git a/apis/apps/v1alpha1/servicedescriptor_conversion.go b/apis/apps/v1alpha1/servicedescriptor_conversion.go index 140d69d12e2..7c99a6b1e0f 100644 --- a/apis/apps/v1alpha1/servicedescriptor_conversion.go +++ b/apis/apps/v1alpha1/servicedescriptor_conversion.go @@ -20,6 +20,7 @@ along with this program. If not, see . package v1alpha1 import ( + "github.com/jinzhu/copier" "sigs.k8s.io/controller-runtime/pkg/conversion" appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" @@ -33,24 +34,10 @@ func (r *ServiceDescriptor) ConvertTo(dstRaw conversion.Hub) error { dst.ObjectMeta = r.ObjectMeta // spec - dst.Spec.ServiceKind = r.Spec.ServiceKind - dst.Spec.ServiceVersion = r.Spec.ServiceVersion - dst.Spec.Endpoint = r.credentialVarTo(r.Spec.Endpoint) - dst.Spec.Host = r.credentialVarTo(r.Spec.Host) - dst.Spec.Port = r.credentialVarTo(r.Spec.Port) - if r.Spec.Auth == nil { - dst.Spec.Auth = nil - } else { - dst.Spec.Auth = &appsv1.ConnectionCredentialAuth{ - Username: r.credentialVarTo(r.Spec.Auth.Username), - Password: r.credentialVarTo(r.Spec.Auth.Password), - } - } + copier.Copy(&dst.Spec, &r.Spec) // status - dst.Status.ObservedGeneration = r.Status.ObservedGeneration - dst.Status.Phase = appsv1.Phase(r.Status.Phase) - dst.Status.Message = r.Status.Message + copier.Copy(&dst.Status, &r.Status) return nil } @@ -63,44 +50,10 @@ func (r *ServiceDescriptor) ConvertFrom(srcRaw conversion.Hub) error { r.ObjectMeta = src.ObjectMeta // spec - r.Spec.ServiceKind = src.Spec.ServiceKind - r.Spec.ServiceVersion = src.Spec.ServiceVersion - r.Spec.Endpoint = r.credentialVarFrom(src.Spec.Endpoint) - r.Spec.Host = r.credentialVarFrom(src.Spec.Host) - r.Spec.Port = r.credentialVarFrom(src.Spec.Port) - if r.Spec.Auth == nil { - r.Spec.Auth = nil - } else { - r.Spec.Auth = &ConnectionCredentialAuth{ - Username: r.credentialVarFrom(src.Spec.Auth.Username), - Password: r.credentialVarFrom(src.Spec.Auth.Password), - } - } + copier.Copy(&r.Spec, &src.Spec) // status - r.Status.ObservedGeneration = src.Status.ObservedGeneration - r.Status.Phase = Phase(src.Status.Phase) - r.Status.Message = src.Status.Message + copier.Copy(&r.Status, &src.Status) return nil } - -func (r *ServiceDescriptor) credentialVarTo(src *CredentialVar) *appsv1.CredentialVar { - if src != nil { - return &appsv1.CredentialVar{ - Value: src.Value, - ValueFrom: src.ValueFrom, - } - } - return nil -} - -func (r *ServiceDescriptor) credentialVarFrom(src *appsv1.CredentialVar) *CredentialVar { - if src != nil { - return &CredentialVar{ - Value: src.Value, - ValueFrom: src.ValueFrom, - } - } - return nil -} diff --git a/apis/apps/v1alpha1/type.go b/apis/apps/v1alpha1/type.go index c13515a03dd..dc74d672e0b 100644 --- a/apis/apps/v1alpha1/type.go +++ b/apis/apps/v1alpha1/type.go @@ -891,10 +891,6 @@ type VarSource struct { // Selects a defined var of a Component. // +optional ComponentVarRef *ComponentVarSelector `json:"componentVarRef,omitempty"` - - // Selects a defined var of a Cluster. - // +optional - ClusterVarRef *ClusterVarSelector `json:"clusterVarRef,omitempty"` } // VarOption defines whether a variable is required or optional. @@ -915,14 +911,6 @@ type NamedVar struct { Option *VarOption `json:"option,omitempty"` } -type RoledVar struct { - // +optional - Role string `json:"role,omitempty"` - - // +optional - Option *VarOption `json:"option,omitempty"` -} - // ContainerVars defines the vars that can be referenced from a Container. type ContainerVars struct { // The name of the container. @@ -944,11 +932,6 @@ type HostNetworkVars struct { // ServiceVars defines the vars that can be referenced from a Service. type ServiceVars struct { - // ServiceType references the type of the service. - // - // +optional - ServiceType *VarOption `json:"serviceType,omitempty"` - // +optional Host *VarOption `json:"host,omitempty"` @@ -1039,11 +1022,6 @@ type ComponentVars struct { // +optional ComponentName *VarOption `json:"componentName,omitempty"` - // Reference to the short name of the Component object. - // - // +optional - ShortName *VarOption `json:"shortName,omitempty"` - // Reference to the replicas of the component. // // +optional @@ -1053,47 +1031,13 @@ type ComponentVars struct { // and the value will be presented in the following format: name1,name2,... // // +optional - PodNames *VarOption `json:"podNames,omitempty"` + InstanceNames *VarOption `json:"instanceNames,omitempty"` // Reference to the pod FQDN list of the component. // The value will be presented in the following format: FQDN1,FQDN2,... // // +optional PodFQDNs *VarOption `json:"podFQDNs,omitempty"` - - // Reference to the pod name list of the component that have a specific role. - // The value will be presented in the following format: name1,name2,... - // - // +optional - PodNamesForRole *RoledVar `json:"podNamesForRole,omitempty"` - - // Reference to the pod FQDN list of the component that have a specific role. - // The value will be presented in the following format: FQDN1,FQDN2,... - // - // +optional - PodFQDNsForRole *RoledVar `json:"podFQDNsForRole,omitempty"` -} - -// ClusterVarSelector selects a var from a Cluster. -type ClusterVarSelector struct { - ClusterVars `json:",inline"` -} - -type ClusterVars struct { - // Reference to the namespace of the Cluster object. - // - // +optional - Namespace *VarOption `json:"namespace,omitempty"` - - // Reference to the name of the Cluster object. - // - // +optional - ClusterName *VarOption `json:"clusterName,omitempty"` - - // Reference to the UID of the Cluster object. - // - // +optional - ClusterUID *VarOption `json:"clusterUID,omitempty"` } // ClusterObjectReference defines information to let you locate the referenced object inside the same Cluster. diff --git a/apis/apps/v1alpha1/zz_generated.deepcopy.go b/apis/apps/v1alpha1/zz_generated.deepcopy.go index 38920a4fefa..ff0b4e5ba58 100644 --- a/apis/apps/v1alpha1/zz_generated.deepcopy.go +++ b/apis/apps/v1alpha1/zz_generated.deepcopy.go @@ -32,7 +32,7 @@ import ( "k8s.io/api/core/v1" rbacv1 "k8s.io/api/rbac/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - runtime "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/util/intstr" ) @@ -44,6 +44,18 @@ func (in *Action) DeepCopyInto(out *Action) { *out = new(ExecAction) (*in).DeepCopyInto(*out) } + if in.HTTP != nil { + in, out := &in.HTTP, &out.HTTP + *out = new(HTTPAction) + (*in).DeepCopyInto(*out) + } + if in.Env != nil { + in, out := &in.Env, &out.Env + *out = make([]v1.EnvVar, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } if in.RetryPolicy != nil { in, out := &in.RetryPolicy, &out.RetryPolicy *out = new(RetryPolicy) @@ -303,6 +315,21 @@ func (in *BackupRefSpec) DeepCopy() *BackupRefSpec { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClassDefRef) DeepCopyInto(out *ClassDefRef) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClassDefRef. +func (in *ClassDefRef) DeepCopy() *ClassDefRef { + if in == nil { + return nil + } + out := new(ClassDefRef) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Cluster) DeepCopyInto(out *Cluster) { *out = *in @@ -401,6 +428,141 @@ func (in *ClusterComponentConfigSource) DeepCopy() *ClusterComponentConfigSource return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterComponentDefinition) DeepCopyInto(out *ClusterComponentDefinition) { + *out = *in + if in.ConfigSpecs != nil { + in, out := &in.ConfigSpecs, &out.ConfigSpecs + *out = make([]ComponentConfigSpec, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.ScriptSpecs != nil { + in, out := &in.ScriptSpecs, &out.ScriptSpecs + *out = make([]ComponentTemplateSpec, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.Probes != nil { + in, out := &in.Probes, &out.Probes + *out = new(ClusterDefinitionProbes) + (*in).DeepCopyInto(*out) + } + if in.LogConfigs != nil { + in, out := &in.LogConfigs, &out.LogConfigs + *out = make([]LogConfig, len(*in)) + copy(*out, *in) + } + if in.PodSpec != nil { + in, out := &in.PodSpec, &out.PodSpec + *out = new(v1.PodSpec) + (*in).DeepCopyInto(*out) + } + if in.Service != nil { + in, out := &in.Service, &out.Service + *out = new(ServiceSpec) + (*in).DeepCopyInto(*out) + } + if in.StatelessSpec != nil { + in, out := &in.StatelessSpec, &out.StatelessSpec + *out = new(StatelessSetSpec) + (*in).DeepCopyInto(*out) + } + if in.StatefulSpec != nil { + in, out := &in.StatefulSpec, &out.StatefulSpec + *out = new(StatefulSetSpec) + (*in).DeepCopyInto(*out) + } + if in.ConsensusSpec != nil { + in, out := &in.ConsensusSpec, &out.ConsensusSpec + *out = new(ConsensusSetSpec) + (*in).DeepCopyInto(*out) + } + if in.ReplicationSpec != nil { + in, out := &in.ReplicationSpec, &out.ReplicationSpec + *out = new(ReplicationSetSpec) + (*in).DeepCopyInto(*out) + } + if in.RSMSpec != nil { + in, out := &in.RSMSpec, &out.RSMSpec + *out = new(RSMSpec) + (*in).DeepCopyInto(*out) + } + if in.HorizontalScalePolicy != nil { + in, out := &in.HorizontalScalePolicy, &out.HorizontalScalePolicy + *out = new(HorizontalScalePolicy) + **out = **in + } + if in.SystemAccounts != nil { + in, out := &in.SystemAccounts, &out.SystemAccounts + *out = new(SystemAccountSpec) + (*in).DeepCopyInto(*out) + } + if in.VolumeTypes != nil { + in, out := &in.VolumeTypes, &out.VolumeTypes + *out = make([]VolumeTypeSpec, len(*in)) + copy(*out, *in) + } + if in.CustomLabelSpecs != nil { + in, out := &in.CustomLabelSpecs, &out.CustomLabelSpecs + *out = make([]CustomLabelSpec, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.SwitchoverSpec != nil { + in, out := &in.SwitchoverSpec, &out.SwitchoverSpec + *out = new(SwitchoverSpec) + (*in).DeepCopyInto(*out) + } + if in.PostStartSpec != nil { + in, out := &in.PostStartSpec, &out.PostStartSpec + *out = new(PostStartAction) + (*in).DeepCopyInto(*out) + } + if in.VolumeProtectionSpec != nil { + in, out := &in.VolumeProtectionSpec, &out.VolumeProtectionSpec + *out = new(VolumeProtectionSpec) + (*in).DeepCopyInto(*out) + } + if in.ComponentDefRef != nil { + in, out := &in.ComponentDefRef, &out.ComponentDefRef + *out = make([]ComponentDefRef, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.ServiceRefDeclarations != nil { + in, out := &in.ServiceRefDeclarations, &out.ServiceRefDeclarations + *out = make([]ServiceRefDeclaration, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.Exporter != nil { + in, out := &in.Exporter, &out.Exporter + *out = new(Exporter) + **out = **in + } + if in.Monitor != nil { + in, out := &in.Monitor, &out.Monitor + *out = new(MonitorConfig) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterComponentDefinition. +func (in *ClusterComponentDefinition) DeepCopy() *ClusterComponentDefinition { + if in == nil { + return nil + } + out := new(ClusterComponentDefinition) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ClusterComponentService) DeepCopyInto(out *ClusterComponentService) { *out = *in @@ -431,6 +593,11 @@ func (in *ClusterComponentService) DeepCopy() *ClusterComponentService { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ClusterComponentSpec) DeepCopyInto(out *ClusterComponentSpec) { *out = *in + if in.ClassDefRef != nil { + in, out := &in.ClassDefRef, &out.ClassDefRef + *out = new(ClassDefRef) + **out = **in + } if in.ServiceRefs != nil { in, out := &in.ServiceRefs, &out.ServiceRefs *out = make([]ServiceRef, len(*in)) @@ -699,9 +866,98 @@ func (in *ClusterDefinitionList) DeepCopyObject() runtime.Object { return nil } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterDefinitionProbe) DeepCopyInto(out *ClusterDefinitionProbe) { + *out = *in + if in.Commands != nil { + in, out := &in.Commands, &out.Commands + *out = new(ClusterDefinitionProbeCMDs) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterDefinitionProbe. +func (in *ClusterDefinitionProbe) DeepCopy() *ClusterDefinitionProbe { + if in == nil { + return nil + } + out := new(ClusterDefinitionProbe) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterDefinitionProbeCMDs) DeepCopyInto(out *ClusterDefinitionProbeCMDs) { + *out = *in + if in.Writes != nil { + in, out := &in.Writes, &out.Writes + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.Queries != nil { + in, out := &in.Queries, &out.Queries + *out = make([]string, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterDefinitionProbeCMDs. +func (in *ClusterDefinitionProbeCMDs) DeepCopy() *ClusterDefinitionProbeCMDs { + if in == nil { + return nil + } + out := new(ClusterDefinitionProbeCMDs) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterDefinitionProbes) DeepCopyInto(out *ClusterDefinitionProbes) { + *out = *in + if in.RunningProbe != nil { + in, out := &in.RunningProbe, &out.RunningProbe + *out = new(ClusterDefinitionProbe) + (*in).DeepCopyInto(*out) + } + if in.StatusProbe != nil { + in, out := &in.StatusProbe, &out.StatusProbe + *out = new(ClusterDefinitionProbe) + (*in).DeepCopyInto(*out) + } + if in.RoleProbe != nil { + in, out := &in.RoleProbe, &out.RoleProbe + *out = new(ClusterDefinitionProbe) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterDefinitionProbes. +func (in *ClusterDefinitionProbes) DeepCopy() *ClusterDefinitionProbes { + if in == nil { + return nil + } + out := new(ClusterDefinitionProbes) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ClusterDefinitionSpec) DeepCopyInto(out *ClusterDefinitionSpec) { *out = *in + if in.ComponentDefs != nil { + in, out := &in.ComponentDefs, &out.ComponentDefs + *out = make([]ClusterComponentDefinition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.ConnectionCredential != nil { + in, out := &in.ConnectionCredential, &out.ConnectionCredential + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } if in.Topologies != nil { in, out := &in.Topologies, &out.Topologies *out = make([]ClusterTopology, len(*in)) @@ -1047,47 +1303,65 @@ func (in *ClusterTopologyOrders) DeepCopy() *ClusterTopologyOrders { } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ClusterVarSelector) DeepCopyInto(out *ClusterVarSelector) { +func (in *CmdExecutorConfig) DeepCopyInto(out *CmdExecutorConfig) { *out = *in - in.ClusterVars.DeepCopyInto(&out.ClusterVars) + in.CommandExecutorEnvItem.DeepCopyInto(&out.CommandExecutorEnvItem) + in.CommandExecutorItem.DeepCopyInto(&out.CommandExecutorItem) } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterVarSelector. -func (in *ClusterVarSelector) DeepCopy() *ClusterVarSelector { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CmdExecutorConfig. +func (in *CmdExecutorConfig) DeepCopy() *CmdExecutorConfig { if in == nil { return nil } - out := new(ClusterVarSelector) + out := new(CmdExecutorConfig) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ClusterVars) DeepCopyInto(out *ClusterVars) { +func (in *CommandExecutorEnvItem) DeepCopyInto(out *CommandExecutorEnvItem) { *out = *in - if in.Namespace != nil { - in, out := &in.Namespace, &out.Namespace - *out = new(VarOption) - **out = **in + if in.Env != nil { + in, out := &in.Env, &out.Env + *out = make([]v1.EnvVar, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } } - if in.ClusterName != nil { - in, out := &in.ClusterName, &out.ClusterName - *out = new(VarOption) - **out = **in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CommandExecutorEnvItem. +func (in *CommandExecutorEnvItem) DeepCopy() *CommandExecutorEnvItem { + if in == nil { + return nil } - if in.ClusterUID != nil { - in, out := &in.ClusterUID, &out.ClusterUID - *out = new(VarOption) - **out = **in + out := new(CommandExecutorEnvItem) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CommandExecutorItem) DeepCopyInto(out *CommandExecutorItem) { + *out = *in + if in.Command != nil { + in, out := &in.Command, &out.Command + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.Args != nil { + in, out := &in.Args, &out.Args + *out = make([]string, len(*in)) + copy(*out, *in) } } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterVars. -func (in *ClusterVars) DeepCopy() *ClusterVars { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CommandExecutorItem. +func (in *CommandExecutorItem) DeepCopy() *CommandExecutorItem { if in == nil { return nil } - out := new(ClusterVars) + out := new(CommandExecutorItem) in.DeepCopyInto(out) return out } @@ -1176,6 +1450,28 @@ func (in *ComponentConfigSpec) DeepCopy() *ComponentConfigSpec { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ComponentDefRef) DeepCopyInto(out *ComponentDefRef) { + *out = *in + if in.ComponentRefEnvs != nil { + in, out := &in.ComponentRefEnvs, &out.ComponentRefEnvs + *out = make([]ComponentRefEnv, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ComponentDefRef. +func (in *ComponentDefRef) DeepCopy() *ComponentDefRef { + if in == nil { + return nil + } + out := new(ComponentDefRef) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ComponentDefinition) DeepCopyInto(out *ComponentDefinition) { *out = *in @@ -1239,6 +1535,11 @@ func (in *ComponentDefinitionList) DeepCopyObject() runtime.Object { func (in *ComponentDefinitionSpec) DeepCopyInto(out *ComponentDefinitionSpec) { *out = *in in.Runtime.DeepCopyInto(&out.Runtime) + if in.Monitor != nil { + in, out := &in.Monitor, &out.Monitor + *out = new(MonitorConfig) + (*in).DeepCopyInto(*out) + } if in.Exporter != nil { in, out := &in.Exporter, &out.Exporter *out = new(Exporter) @@ -1335,6 +1636,11 @@ func (in *ComponentDefinitionSpec) DeepCopyInto(out *ComponentDefinitionSpec) { *out = make([]ReplicaRole, len(*in)) copy(*out, *in) } + if in.RoleArbitrator != nil { + in, out := &in.RoleArbitrator, &out.RoleArbitrator + *out = new(RoleArbitrator) + **out = **in + } if in.LifecycleActions != nil { in, out := &in.LifecycleActions, &out.LifecycleActions *out = new(ComponentLifecycleActions) @@ -1394,62 +1700,62 @@ func (in *ComponentLifecycleActions) DeepCopyInto(out *ComponentLifecycleActions *out = *in if in.PostProvision != nil { in, out := &in.PostProvision, &out.PostProvision - *out = new(Action) + *out = new(LifecycleActionHandler) (*in).DeepCopyInto(*out) } if in.PreTerminate != nil { in, out := &in.PreTerminate, &out.PreTerminate - *out = new(Action) + *out = new(LifecycleActionHandler) (*in).DeepCopyInto(*out) } if in.RoleProbe != nil { in, out := &in.RoleProbe, &out.RoleProbe - *out = new(Probe) + *out = new(RoleProbe) (*in).DeepCopyInto(*out) } if in.Switchover != nil { in, out := &in.Switchover, &out.Switchover - *out = new(Action) + *out = new(ComponentSwitchover) (*in).DeepCopyInto(*out) } if in.MemberJoin != nil { in, out := &in.MemberJoin, &out.MemberJoin - *out = new(Action) + *out = new(LifecycleActionHandler) (*in).DeepCopyInto(*out) } if in.MemberLeave != nil { in, out := &in.MemberLeave, &out.MemberLeave - *out = new(Action) + *out = new(LifecycleActionHandler) (*in).DeepCopyInto(*out) } if in.Readonly != nil { in, out := &in.Readonly, &out.Readonly - *out = new(Action) + *out = new(LifecycleActionHandler) (*in).DeepCopyInto(*out) } if in.Readwrite != nil { in, out := &in.Readwrite, &out.Readwrite - *out = new(Action) + *out = new(LifecycleActionHandler) (*in).DeepCopyInto(*out) } if in.DataDump != nil { in, out := &in.DataDump, &out.DataDump - *out = new(Action) + *out = new(LifecycleActionHandler) (*in).DeepCopyInto(*out) } if in.DataLoad != nil { in, out := &in.DataLoad, &out.DataLoad - *out = new(Action) + *out = new(LifecycleActionHandler) (*in).DeepCopyInto(*out) } if in.Reconfigure != nil { in, out := &in.Reconfigure, &out.Reconfigure - *out = new(Action) + *out = new(LifecycleActionHandler) (*in).DeepCopyInto(*out) } if in.AccountProvision != nil { in, out := &in.AccountProvision, &out.AccountProvision - *out = new(Action) + *out = new(LifecycleActionHandler) (*in).DeepCopyInto(*out) } } @@ -1532,6 +1838,26 @@ func (in *ComponentOps) DeepCopy() *ComponentOps { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ComponentRefEnv) DeepCopyInto(out *ComponentRefEnv) { + *out = *in + if in.ValueFrom != nil { + in, out := &in.ValueFrom, &out.ValueFrom + *out = new(ComponentValueFrom) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ComponentRefEnv. +func (in *ComponentRefEnv) DeepCopy() *ComponentRefEnv { + if in == nil { + return nil + } + out := new(ComponentRefEnv) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ComponentService) DeepCopyInto(out *ComponentService) { *out = *in @@ -1730,6 +2056,36 @@ func (in *ComponentStatus) DeepCopy() *ComponentStatus { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ComponentSwitchover) DeepCopyInto(out *ComponentSwitchover) { + *out = *in + if in.WithCandidate != nil { + in, out := &in.WithCandidate, &out.WithCandidate + *out = new(Action) + (*in).DeepCopyInto(*out) + } + if in.WithoutCandidate != nil { + in, out := &in.WithoutCandidate, &out.WithoutCandidate + *out = new(Action) + (*in).DeepCopyInto(*out) + } + if in.ScriptSpecSelectors != nil { + in, out := &in.ScriptSpecSelectors, &out.ScriptSpecSelectors + *out = make([]ScriptSpecSelector, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ComponentSwitchover. +func (in *ComponentSwitchover) DeepCopy() *ComponentSwitchover { + if in == nil { + return nil + } + out := new(ComponentSwitchover) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ComponentSystemAccount) DeepCopyInto(out *ComponentSystemAccount) { *out = *in @@ -1775,6 +2131,21 @@ func (in *ComponentTemplateSpec) DeepCopy() *ComponentTemplateSpec { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ComponentValueFrom) DeepCopyInto(out *ComponentValueFrom) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ComponentValueFrom. +func (in *ComponentValueFrom) DeepCopy() *ComponentValueFrom { + if in == nil { + return nil + } + out := new(ComponentValueFrom) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ComponentVarSelector) DeepCopyInto(out *ComponentVarSelector) { *out = *in @@ -1800,18 +2171,13 @@ func (in *ComponentVars) DeepCopyInto(out *ComponentVars) { *out = new(VarOption) **out = **in } - if in.ShortName != nil { - in, out := &in.ShortName, &out.ShortName - *out = new(VarOption) - **out = **in - } if in.Replicas != nil { in, out := &in.Replicas, &out.Replicas *out = new(VarOption) **out = **in } - if in.PodNames != nil { - in, out := &in.PodNames, &out.PodNames + if in.InstanceNames != nil { + in, out := &in.InstanceNames, &out.InstanceNames *out = new(VarOption) **out = **in } @@ -1820,16 +2186,6 @@ func (in *ComponentVars) DeepCopyInto(out *ComponentVars) { *out = new(VarOption) **out = **in } - if in.PodNamesForRole != nil { - in, out := &in.PodNamesForRole, &out.PodNamesForRole - *out = new(RoledVar) - (*in).DeepCopyInto(*out) - } - if in.PodFQDNsForRole != nil { - in, out := &in.PodFQDNsForRole, &out.PodFQDNsForRole - *out = new(RoledVar) - (*in).DeepCopyInto(*out) - } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ComponentVars. @@ -2469,6 +2825,55 @@ func (in *ConnectionCredentialAuth) DeepCopy() *ConnectionCredentialAuth { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ConsensusMember) DeepCopyInto(out *ConsensusMember) { + *out = *in + if in.Replicas != nil { + in, out := &in.Replicas, &out.Replicas + *out = new(int32) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ConsensusMember. +func (in *ConsensusMember) DeepCopy() *ConsensusMember { + if in == nil { + return nil + } + out := new(ConsensusMember) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ConsensusSetSpec) DeepCopyInto(out *ConsensusSetSpec) { + *out = *in + in.StatefulSetSpec.DeepCopyInto(&out.StatefulSetSpec) + in.Leader.DeepCopyInto(&out.Leader) + if in.Followers != nil { + in, out := &in.Followers, &out.Followers + *out = make([]ConsensusMember, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.Learner != nil { + in, out := &in.Learner, &out.Learner + *out = new(ConsensusMember) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ConsensusSetSpec. +func (in *ConsensusSetSpec) DeepCopy() *ConsensusSetSpec { + if in == nil { + return nil + } + out := new(ConsensusSetSpec) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ContainerVars) DeepCopyInto(out *ContainerVars) { *out = *in @@ -2551,6 +2956,28 @@ func (in *CredentialVars) DeepCopy() *CredentialVars { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CustomLabelSpec) DeepCopyInto(out *CustomLabelSpec) { + *out = *in + if in.Resources != nil { + in, out := &in.Resources, &out.Resources + *out = make([]GVKResource, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CustomLabelSpec. +func (in *CustomLabelSpec) DeepCopy() *CustomLabelSpec { + if in == nil { + return nil + } + out := new(CustomLabelSpec) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *CustomOps) DeepCopyInto(out *CustomOps) { *out = *in @@ -2678,13 +3105,6 @@ func (in *EnvVarRef) DeepCopy() *EnvVarRef { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ExecAction) DeepCopyInto(out *ExecAction) { *out = *in - if in.Env != nil { - in, out := &in.Env, &out.Env - *out = make([]v1.EnvVar, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } if in.Command != nil { in, out := &in.Command, &out.Command *out = make([]string, len(*in)) @@ -2722,6 +3142,22 @@ func (in *Exporter) DeepCopy() *Exporter { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ExporterConfig) DeepCopyInto(out *ExporterConfig) { + *out = *in + out.ScrapePort = in.ScrapePort +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExporterConfig. +func (in *ExporterConfig) DeepCopy() *ExporterConfig { + if in == nil { + return nil + } + out := new(ExporterConfig) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Expose) DeepCopyInto(out *Expose) { *out = *in @@ -2744,6 +3180,64 @@ func (in *Expose) DeepCopy() *Expose { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *GVKResource) DeepCopyInto(out *GVKResource) { + *out = *in + if in.Selector != nil { + in, out := &in.Selector, &out.Selector + *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 GVKResource. +func (in *GVKResource) DeepCopy() *GVKResource { + if in == nil { + return nil + } + out := new(GVKResource) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *HTTPAction) DeepCopyInto(out *HTTPAction) { + *out = *in + out.Port = in.Port + if in.HTTPHeaders != nil { + in, out := &in.HTTPHeaders, &out.HTTPHeaders + *out = make([]v1.HTTPHeader, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HTTPAction. +func (in *HTTPAction) DeepCopy() *HTTPAction { + if in == nil { + return nil + } + out := new(HTTPAction) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *HorizontalScalePolicy) DeepCopyInto(out *HorizontalScalePolicy) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HorizontalScalePolicy. +func (in *HorizontalScalePolicy) DeepCopy() *HorizontalScalePolicy { + if in == nil { + return nil + } + out := new(HorizontalScalePolicy) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *HorizontalScaling) DeepCopyInto(out *HorizontalScaling) { *out = *in @@ -3135,6 +3629,31 @@ func (in *LegacyRenderedTemplateSpec) DeepCopy() *LegacyRenderedTemplateSpec { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *LifecycleActionHandler) DeepCopyInto(out *LifecycleActionHandler) { + *out = *in + if in.BuiltinHandler != nil { + in, out := &in.BuiltinHandler, &out.BuiltinHandler + *out = new(BuiltinActionHandlerType) + **out = **in + } + if in.CustomHandler != nil { + in, out := &in.CustomHandler, &out.CustomHandler + *out = new(Action) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LifecycleActionHandler. +func (in *LifecycleActionHandler) DeepCopy() *LifecycleActionHandler { + if in == nil { + return nil + } + out := new(LifecycleActionHandler) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *LogConfig) DeepCopyInto(out *LogConfig) { *out = *in @@ -3155,12 +3674,32 @@ func (in *MatchExpressions) DeepCopyInto(out *MatchExpressions) { *out = *in } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MatchExpressions. -func (in *MatchExpressions) DeepCopy() *MatchExpressions { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MatchExpressions. +func (in *MatchExpressions) DeepCopy() *MatchExpressions { + if in == nil { + return nil + } + out := new(MatchExpressions) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MonitorConfig) DeepCopyInto(out *MonitorConfig) { + *out = *in + if in.Exporter != nil { + in, out := &in.Exporter, &out.Exporter + *out = new(ExporterConfig) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MonitorConfig. +func (in *MonitorConfig) DeepCopy() *MonitorConfig { if in == nil { return nil } - out := new(MatchExpressions) + out := new(MonitorConfig) in.DeepCopyInto(out) return out } @@ -3993,6 +4532,27 @@ func (in *PointInTimeRefSpec) DeepCopy() *PointInTimeRefSpec { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PostStartAction) DeepCopyInto(out *PostStartAction) { + *out = *in + in.CmdExecutorConfig.DeepCopyInto(&out.CmdExecutorConfig) + if in.ScriptSpecSelectors != nil { + in, out := &in.ScriptSpecSelectors, &out.ScriptSpecSelectors + *out = make([]ScriptSpecSelector, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PostStartAction. +func (in *PostStartAction) DeepCopy() *PostStartAction { + if in == nil { + return nil + } + out := new(PostStartAction) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *PreCheckResult) DeepCopyInto(out *PreCheckResult) { *out = *in @@ -4098,6 +4658,51 @@ func (in *ProgressStatusDetail) DeepCopy() *ProgressStatusDetail { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ProtectedVolume) DeepCopyInto(out *ProtectedVolume) { + *out = *in + if in.HighWatermark != nil { + in, out := &in.HighWatermark, &out.HighWatermark + *out = new(int) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProtectedVolume. +func (in *ProtectedVolume) DeepCopy() *ProtectedVolume { + if in == nil { + return nil + } + out := new(ProtectedVolume) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ProvisionPolicy) DeepCopyInto(out *ProvisionPolicy) { + *out = *in + if in.Statements != nil { + in, out := &in.Statements, &out.Statements + *out = new(ProvisionStatements) + **out = **in + } + if in.SecretRef != nil { + in, out := &in.SecretRef, &out.SecretRef + *out = new(ProvisionSecretRef) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProvisionPolicy. +func (in *ProvisionPolicy) DeepCopy() *ProvisionPolicy { + if in == nil { + return nil + } + out := new(ProvisionPolicy) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ProvisionSecretRef) DeepCopyInto(out *ProvisionSecretRef) { *out = *in @@ -4113,6 +4718,56 @@ func (in *ProvisionSecretRef) DeepCopy() *ProvisionSecretRef { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ProvisionStatements) DeepCopyInto(out *ProvisionStatements) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProvisionStatements. +func (in *ProvisionStatements) DeepCopy() *ProvisionStatements { + if in == nil { + return nil + } + out := new(ProvisionStatements) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RSMSpec) DeepCopyInto(out *RSMSpec) { + *out = *in + if in.Roles != nil { + in, out := &in.Roles, &out.Roles + *out = make([]workloadsv1alpha1.ReplicaRole, len(*in)) + copy(*out, *in) + } + if in.RoleProbe != nil { + in, out := &in.RoleProbe, &out.RoleProbe + *out = new(workloadsv1alpha1.RoleProbe) + (*in).DeepCopyInto(*out) + } + if in.MembershipReconfiguration != nil { + in, out := &in.MembershipReconfiguration, &out.MembershipReconfiguration + *out = new(workloadsv1alpha1.MembershipReconfiguration) + (*in).DeepCopyInto(*out) + } + if in.MemberUpdateStrategy != nil { + in, out := &in.MemberUpdateStrategy, &out.MemberUpdateStrategy + *out = new(workloadsv1alpha1.MemberUpdateStrategy) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RSMSpec. +func (in *RSMSpec) DeepCopy() *RSMSpec { + if in == nil { + return nil + } + out := new(RSMSpec) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *RebuildInstance) DeepCopyInto(out *RebuildInstance) { *out = *in @@ -4313,6 +4968,22 @@ func (in *ReplicasLimit) DeepCopy() *ReplicasLimit { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ReplicationSetSpec) DeepCopyInto(out *ReplicationSetSpec) { + *out = *in + in.StatefulSetSpec.DeepCopyInto(&out.StatefulSetSpec) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ReplicationSetSpec. +func (in *ReplicationSetSpec) DeepCopy() *ReplicationSetSpec { + if in == nil { + return nil + } + out := new(ReplicationSetSpec) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ResourceMeta) DeepCopyInto(out *ResourceMeta) { *out = *in @@ -4364,21 +5035,17 @@ func (in *RetryPolicy) DeepCopy() *RetryPolicy { } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *RoledVar) DeepCopyInto(out *RoledVar) { +func (in *RoleProbe) DeepCopyInto(out *RoleProbe) { *out = *in - if in.Option != nil { - in, out := &in.Option, &out.Option - *out = new(VarOption) - **out = **in - } + in.LifecycleActionHandler.DeepCopyInto(&out.LifecycleActionHandler) } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RoledVar. -func (in *RoledVar) DeepCopy() *RoledVar { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RoleProbe. +func (in *RoleProbe) DeepCopy() *RoleProbe { if in == nil { return nil } - out := new(RoledVar) + out := new(RoleProbe) in.DeepCopyInto(out) return out } @@ -4508,6 +5175,21 @@ func (in *SchedulingPolicy) DeepCopy() *SchedulingPolicy { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ScriptSpecSelector) DeepCopyInto(out *ScriptSpecSelector) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ScriptSpecSelector. +func (in *ScriptSpecSelector) DeepCopy() *ScriptSpecSelector { + if in == nil { + return nil + } + out := new(ScriptSpecSelector) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *SecretRef) DeepCopyInto(out *SecretRef) { *out = *in @@ -4657,6 +5339,27 @@ func (in *ServiceDescriptorStatus) DeepCopy() *ServiceDescriptorStatus { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ServicePort) DeepCopyInto(out *ServicePort) { + *out = *in + if in.AppProtocol != nil { + in, out := &in.AppProtocol, &out.AppProtocol + *out = new(string) + **out = **in + } + out.TargetPort = in.TargetPort +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServicePort. +func (in *ServicePort) DeepCopy() *ServicePort { + if in == nil { + return nil + } + out := new(ServicePort) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ServiceRef) DeepCopyInto(out *ServiceRef) { *out = *in @@ -4820,6 +5523,28 @@ func (in *ServiceRefVars) DeepCopy() *ServiceRefVars { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ServiceSpec) DeepCopyInto(out *ServiceSpec) { + *out = *in + if in.Ports != nil { + in, out := &in.Ports, &out.Ports + *out = make([]ServicePort, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceSpec. +func (in *ServiceSpec) DeepCopy() *ServiceSpec { + if in == nil { + return nil + } + out := new(ServiceSpec) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ServiceVarSelector) DeepCopyInto(out *ServiceVarSelector) { *out = *in @@ -4840,11 +5565,6 @@ func (in *ServiceVarSelector) DeepCopy() *ServiceVarSelector { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ServiceVars) DeepCopyInto(out *ServiceVars) { *out = *in - if in.ServiceType != nil { - in, out := &in.ServiceType, &out.ServiceType - *out = new(VarOption) - **out = **in - } if in.Host != nil { in, out := &in.Host, &out.Host *out = new(VarOption) @@ -4990,6 +5710,42 @@ func (in *SpecificOpsRequest) DeepCopy() *SpecificOpsRequest { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *StatefulSetSpec) DeepCopyInto(out *StatefulSetSpec) { + *out = *in + if in.LLUpdateStrategy != nil { + in, out := &in.LLUpdateStrategy, &out.LLUpdateStrategy + *out = new(appsv1.StatefulSetUpdateStrategy) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StatefulSetSpec. +func (in *StatefulSetSpec) DeepCopy() *StatefulSetSpec { + if in == nil { + return nil + } + out := new(StatefulSetSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *StatelessSetSpec) DeepCopyInto(out *StatelessSetSpec) { + *out = *in + in.UpdateStrategy.DeepCopyInto(&out.UpdateStrategy) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StatelessSetSpec. +func (in *StatelessSetSpec) DeepCopy() *StatelessSetSpec { + if in == nil { + return nil + } + out := new(StatelessSetSpec) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Switchover) DeepCopyInto(out *Switchover) { *out = *in @@ -5006,6 +5762,56 @@ func (in *Switchover) DeepCopy() *Switchover { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SwitchoverAction) DeepCopyInto(out *SwitchoverAction) { + *out = *in + if in.CmdExecutorConfig != nil { + in, out := &in.CmdExecutorConfig, &out.CmdExecutorConfig + *out = new(CmdExecutorConfig) + (*in).DeepCopyInto(*out) + } + if in.ScriptSpecSelectors != nil { + in, out := &in.ScriptSpecSelectors, &out.ScriptSpecSelectors + *out = make([]ScriptSpecSelector, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SwitchoverAction. +func (in *SwitchoverAction) DeepCopy() *SwitchoverAction { + if in == nil { + return nil + } + out := new(SwitchoverAction) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SwitchoverSpec) DeepCopyInto(out *SwitchoverSpec) { + *out = *in + if in.WithCandidate != nil { + in, out := &in.WithCandidate, &out.WithCandidate + *out = new(SwitchoverAction) + (*in).DeepCopyInto(*out) + } + if in.WithoutCandidate != nil { + in, out := &in.WithoutCandidate, &out.WithoutCandidate + *out = new(SwitchoverAction) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SwitchoverSpec. +func (in *SwitchoverSpec) DeepCopy() *SwitchoverSpec { + if in == nil { + return nil + } + out := new(SwitchoverSpec) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *SystemAccount) DeepCopyInto(out *SystemAccount) { *out = *in @@ -5027,6 +5833,50 @@ func (in *SystemAccount) DeepCopy() *SystemAccount { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SystemAccountConfig) DeepCopyInto(out *SystemAccountConfig) { + *out = *in + in.ProvisionPolicy.DeepCopyInto(&out.ProvisionPolicy) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SystemAccountConfig. +func (in *SystemAccountConfig) DeepCopy() *SystemAccountConfig { + if in == nil { + return nil + } + out := new(SystemAccountConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SystemAccountSpec) DeepCopyInto(out *SystemAccountSpec) { + *out = *in + if in.CmdExecutorConfig != nil { + in, out := &in.CmdExecutorConfig, &out.CmdExecutorConfig + *out = new(CmdExecutorConfig) + (*in).DeepCopyInto(*out) + } + out.PasswordConfig = in.PasswordConfig + if in.Accounts != nil { + in, out := &in.Accounts, &out.Accounts + *out = make([]SystemAccountConfig, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SystemAccountSpec. +func (in *SystemAccountSpec) DeepCopy() *SystemAccountSpec { + if in == nil { + return nil + } + out := new(SystemAccountSpec) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *TLSConfig) DeepCopyInto(out *TLSConfig) { *out = *in @@ -5307,11 +6157,6 @@ func (in *VarSource) DeepCopyInto(out *VarSource) { *out = new(ComponentVarSelector) (*in).DeepCopyInto(*out) } - if in.ClusterVarRef != nil { - in, out := &in.ClusterVarRef, &out.ClusterVarRef - *out = new(ClusterVarSelector) - (*in).DeepCopyInto(*out) - } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VarSource. @@ -5377,3 +6222,40 @@ func (in *VolumeExpansion) DeepCopy() *VolumeExpansion { in.DeepCopyInto(out) return out } + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VolumeProtectionSpec) DeepCopyInto(out *VolumeProtectionSpec) { + *out = *in + if in.Volumes != nil { + in, out := &in.Volumes, &out.Volumes + *out = make([]ProtectedVolume, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VolumeProtectionSpec. +func (in *VolumeProtectionSpec) DeepCopy() *VolumeProtectionSpec { + if in == nil { + return nil + } + out := new(VolumeProtectionSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VolumeTypeSpec) DeepCopyInto(out *VolumeTypeSpec) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VolumeTypeSpec. +func (in *VolumeTypeSpec) DeepCopy() *VolumeTypeSpec { + if in == nil { + return nil + } + out := new(VolumeTypeSpec) + in.DeepCopyInto(out) + return out +} diff --git a/apis/workloads/v1alpha1/instanceset_conversion.go b/apis/workloads/v1alpha1/instanceset_conversion.go index 5b7696ae75b..c4bd86ddaf4 100644 --- a/apis/workloads/v1alpha1/instanceset_conversion.go +++ b/apis/workloads/v1alpha1/instanceset_conversion.go @@ -20,15 +20,40 @@ along with this program. If not, see . package v1alpha1 import ( + "github.com/jinzhu/copier" "sigs.k8s.io/controller-runtime/pkg/conversion" + + workloadsv1 "github.com/apecloud/kubeblocks/apis/workloads/v1" ) // ConvertTo converts this InstanceSet to the Hub version (v1). func (r *InstanceSet) ConvertTo(dstRaw conversion.Hub) error { + dst := dstRaw.(*workloadsv1.InstanceSet) + + // objectMeta + dst.ObjectMeta = r.ObjectMeta + + // spec + copier.Copy(&dst.Spec, &r.Spec) + + // status + copier.Copy(&dst.Status, &r.Status) + return nil } // ConvertFrom converts from the Hub version (v1) to this version. func (r *InstanceSet) ConvertFrom(srcRaw conversion.Hub) error { + src := srcRaw.(*workloadsv1.InstanceSet) + + // objectMeta + r.ObjectMeta = src.ObjectMeta + + // spec + copier.Copy(&r.Spec, &src.Spec) + + // status + copier.Copy(&r.Status, &src.Status) + return nil } diff --git a/config/crd/bases/apps.kubeblocks.io_clusterdefinitions.yaml b/config/crd/bases/apps.kubeblocks.io_clusterdefinitions.yaml index 133edfc7b7d..7bfc5b8b7ef 100644 --- a/config/crd/bases/apps.kubeblocks.io_clusterdefinitions.yaml +++ b/config/crd/bases/apps.kubeblocks.io_clusterdefinitions.yaml @@ -255,6 +255,9876 @@ spec: spec: description: ClusterDefinitionSpec defines the desired state of ClusterDefinition. properties: + componentDefs: + description: |- + Provides the definitions for the cluster components. + + + Deprecated since v0.9. + Components should now be individually defined using ComponentDefinition and + collectively referenced via `topology.components`. + This field is maintained for backward compatibility and its use is discouraged. + Existing usage should be updated to the current preferred approach to avoid compatibility issues in future releases. + items: + description: |- + ClusterComponentDefinition defines a Component within a ClusterDefinition but is deprecated and + has been replaced by ComponentDefinition. + + + Deprecated: Use ComponentDefinition instead. This type is deprecated as of version 0.8. + properties: + characterType: + description: Defines well-known database component name, such + as mongos(mongodb), proxy(redis), mariadb(mysql). + type: string + componentDefRef: + description: |- + Used to inject values from other components into the current component. Values will be saved and updated in a + configmap and mounted to the current component. + items: + description: |- + ComponentDefRef is used to select the component and its fields to be referenced. + + + Deprecated since v0.8. + properties: + componentDefName: + description: The name of the componentDef to be selected. + type: string + componentRefEnv: + description: The values that are to be injected as environment + variables into each component. + items: + description: |- + ComponentRefEnv specifies name and value of an env. + + + Deprecated since v0.8. + properties: + name: + description: The name of the env, it must be a C + identifier. + pattern: ^[A-Za-z_][A-Za-z0-9_]*$ + type: string + value: + description: The value of the env. + type: string + valueFrom: + description: The source from which the value of + the env. + properties: + fieldPath: + description: |- + The jsonpath of the source to select when the Type is `FieldRef`. + Two objects are registered in the jsonpath: `componentDef` and `components`: + + + - `componentDef` is the component definition object specified in `componentRef.componentDefName`. + - `components` are the component list objects referring to the component definition object. + type: string + format: + default: ="$POD_FQDN" + description: |- + Defines the format of each headless service address. + Three builtin variables can be used as placeholders: `$POD_ORDINAL`, `$POD_FQDN`, `$POD_NAME` + + + - `$POD_ORDINAL` represents the ordinal of the pod. + - `$POD_FQDN` represents the fully qualified domain name of the pod. + - `$POD_NAME` represents the name of the pod. + type: string + joinWith: + default: ',' + description: The string used to join the values + of headless service addresses. + type: string + type: + allOf: + - enum: + - FieldRef + - ServiceRef + - HeadlessServiceRef + - enum: + - FieldRef + - ServiceRef + - HeadlessServiceRef + description: 'Specifies the source to select. + It can be one of three types: `FieldRef`, + `ServiceRef`, `HeadlessServiceRef`.' + type: string + required: + - type + type: object + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + failurePolicy: + allOf: + - enum: + - Ignore + - Fail + - enum: + - Ignore + - Fail + description: Defines the policy to be followed in case + of a failure in finding the component. + type: string + required: + - componentDefName + type: object + type: array + x-kubernetes-list-map-keys: + - componentDefName + x-kubernetes-list-type: map + configSpecs: + description: Defines the template of configurations. + items: + properties: + asEnvFrom: + description: |- + Specifies the containers to inject the ConfigMap parameters as environment variables. + + + This is useful when application images accept parameters through environment variables and + generate the final configuration file in the startup script based on these variables. + + + This field allows users to specify a list of container names, and KubeBlocks will inject the environment + variables converted from the ConfigMap into these designated containers. This provides a flexible way to + pass the configuration items from the ConfigMap to the container without modifying the image. + + + Deprecated: `asEnvFrom` has been deprecated since 0.9.0 and will be removed in 0.10.0. + Use `injectEnvTo` instead. + items: + type: string + type: array + x-kubernetes-list-type: set + constraintRef: + description: Specifies the name of the referenced configuration + constraints object. + maxLength: 63 + pattern: ^[a-z0-9]([a-z0-9\.\-]*[a-z0-9])?$ + type: string + defaultMode: + description: |- + The operator attempts to set default file permissions for scripts (0555) and configurations (0444). + However, certain database engines may require different file permissions. + You can specify the desired file permissions here. + + + Must be specified as an octal value between 0000 and 0777 (inclusive), + or as a decimal value between 0 and 511 (inclusive). + YAML supports both octal and decimal values for file permissions. + + + Please note that this setting only affects the permissions of the files themselves. + Directories within the specified path are not impacted by this setting. + It's important to be aware that this setting might conflict with other options + that influence the file mode, such as fsGroup. + In such cases, the resulting file mode may have additional bits set. + Refers to documents of k8s.ConfigMapVolumeSource.defaultMode for more information. + format: int32 + type: integer + injectEnvTo: + description: |- + Specifies the containers to inject the ConfigMap parameters as environment variables. + + + This is useful when application images accept parameters through environment variables and + generate the final configuration file in the startup script based on these variables. + + + This field allows users to specify a list of container names, and KubeBlocks will inject the environment + variables converted from the ConfigMap into these designated containers. This provides a flexible way to + pass the configuration items from the ConfigMap to the container without modifying the image. + items: + type: string + type: array + x-kubernetes-list-type: set + keys: + description: |- + Specifies the configuration files within the ConfigMap that support dynamic updates. + + + A configuration template (provided in the form of a ConfigMap) may contain templates for multiple + configuration files. + Each configuration file corresponds to a key in the ConfigMap. + Some of these configuration files may support dynamic modification and reloading without requiring + a pod restart. + + + If empty or omitted, all configuration files in the ConfigMap are assumed to support dynamic updates, + and ConfigConstraint applies to all keys. + items: + type: string + type: array + x-kubernetes-list-type: set + legacyRenderedConfigSpec: + description: |- + Specifies the secondary rendered config spec for pod-specific customization. + + + The template is rendered inside the pod (by the "config-manager" sidecar container) and merged with the main + template's render result to generate the final configuration file. + + + This field is intended to handle scenarios where different pods within the same Component have + varying configurations. It allows for pod-specific customization of the configuration. + + + Note: This field will be deprecated in future versions, and the functionality will be moved to + `cluster.spec.componentSpecs[*].instances[*]`. + properties: + namespace: + default: default + description: |- + Specifies the namespace of the referenced configuration template ConfigMap object. + An empty namespace is equivalent to the "default" namespace. + pattern: ^[a-z0-9]([a-z0-9\-]*[a-z0-9])?$ + type: string + policy: + default: none + description: Defines the strategy for merging externally + imported templates into component templates. + enum: + - patch + - replace + - none + type: string + templateRef: + description: Specifies the name of the referenced + configuration template ConfigMap object. + pattern: ^[a-z0-9]([a-z0-9\.\-]*[a-z0-9])?$ + type: string + required: + - templateRef + type: object + name: + description: Specifies the name of the configuration template. + maxLength: 63 + pattern: ^[a-z0-9]([a-z0-9\.\-]*[a-z0-9])?$ + type: string + namespace: + default: default + description: |- + Specifies the namespace of the referenced configuration template ConfigMap object. + An empty namespace is equivalent to the "default" namespace. + maxLength: 63 + pattern: ^[a-z0-9]([a-z0-9\-]*[a-z0-9])?$ + type: string + reRenderResourceTypes: + description: |- + Specifies whether the configuration needs to be re-rendered after v-scale or h-scale operations to reflect changes. + + + In some scenarios, the configuration may need to be updated to reflect the changes in resource allocation + or cluster topology. Examples: + + + - Redis: adjust maxmemory after v-scale operation. + - MySQL: increase max connections after v-scale operation. + - Zookeeper: update zoo.cfg with new node addresses after h-scale operation. + items: + description: RerenderResourceType defines the resource + requirements for a component. + enum: + - vscale + - hscale + - tls + type: string + type: array + x-kubernetes-list-type: set + templateRef: + description: Specifies the name of the referenced configuration + template ConfigMap object. + maxLength: 63 + pattern: ^[a-z0-9]([a-z0-9\.\-]*[a-z0-9])?$ + type: string + volumeName: + description: |- + Refers to the volume name of PodTemplate. The configuration file produced through the configuration + template will be mounted to the corresponding volume. Must be a DNS_LABEL name. + The volume name must be defined in podSpec.containers[*].volumeMounts. + maxLength: 63 + pattern: ^[a-z]([a-z0-9\-]*[a-z0-9])?$ + type: string + required: + - name + - volumeName + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + consensusSpec: + description: Defines spec for `Consensus` workloads. It's required + if the workload type is `Consensus`. + properties: + followers: + description: Members of the consensus set that have voting + rights but are not the leader. + items: + description: ConsensusMember is deprecated since v0.7. + properties: + accessMode: + default: ReadWrite + description: Specifies the services that this member + is capable of providing. + enum: + - None + - Readonly + - ReadWrite + type: string + name: + default: leader + description: Specifies the name of the consensus member. + type: string + replicas: + default: 0 + description: |- + Indicates the number of Pods that perform this role. + The default is 1 for `Leader`, 0 for `Learner`, others for `Followers`. + format: int32 + minimum: 0 + type: integer + required: + - accessMode + - name + type: object + type: array + leader: + description: Represents a single leader in the consensus + set. + properties: + accessMode: + default: ReadWrite + description: Specifies the services that this member + is capable of providing. + enum: + - None + - Readonly + - ReadWrite + type: string + name: + default: leader + description: Specifies the name of the consensus member. + type: string + replicas: + default: 0 + description: |- + Indicates the number of Pods that perform this role. + The default is 1 for `Leader`, 0 for `Learner`, others for `Followers`. + format: int32 + minimum: 0 + type: integer + required: + - accessMode + - name + type: object + learner: + description: Represents a member of the consensus set that + does not have voting rights. + properties: + accessMode: + default: ReadWrite + description: Specifies the services that this member + is capable of providing. + enum: + - None + - Readonly + - ReadWrite + type: string + name: + default: leader + description: Specifies the name of the consensus member. + type: string + replicas: + default: 0 + description: |- + Indicates the number of Pods that perform this role. + The default is 1 for `Leader`, 0 for `Learner`, others for `Followers`. + format: int32 + minimum: 0 + type: integer + required: + - accessMode + - name + type: object + llPodManagementPolicy: + description: |- + Controls the creation of pods during initial scale up, replacement of pods on nodes, and scaling down. + + + - `OrderedReady`: Creates pods in increasing order (pod-0, then pod-1, etc). The controller waits until each pod + is ready before continuing. Pods are removed in reverse order when scaling down. + - `Parallel`: Creates pods in parallel to match the desired scale without waiting. All pods are deleted at once + when scaling down. + type: string + llUpdateStrategy: + description: |- + Specifies the low-level StatefulSetUpdateStrategy to be used when updating Pods in the StatefulSet upon a + revision to the Template. + `UpdateStrategy` will be ignored if this is provided. + properties: + rollingUpdate: + description: RollingUpdate is used to communicate parameters + when Type is RollingUpdateStatefulSetStrategyType. + properties: + maxUnavailable: + anyOf: + - type: integer + - type: string + description: |- + The maximum number of pods that can be unavailable during the update. + Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). + Absolute number is calculated from percentage by rounding up. This can not be 0. + Defaults to 1. This field is alpha-level and is only honored by servers that enable the + MaxUnavailableStatefulSet feature. The field applies to all pods in the range 0 to + Replicas-1. That means if there is any unavailable pod in the range 0 to Replicas-1, it + will be counted towards MaxUnavailable. + x-kubernetes-int-or-string: true + partition: + description: |- + Partition indicates the ordinal at which the StatefulSet should be partitioned + for updates. During a rolling update, all pods from ordinal Replicas-1 to + Partition are updated. All pods from ordinal Partition-1 to 0 remain untouched. + This is helpful in being able to do a canary based deployment. The default value is 0. + format: int32 + type: integer + type: object + type: + description: |- + Type indicates the type of the StatefulSetUpdateStrategy. + Default is RollingUpdate. + type: string + type: object + updateStrategy: + default: Serial + description: |- + Specifies the strategy for updating Pods. + For workloadType=`Consensus`, the update strategy can be one of the following: + + + - `Serial`: Updates Members sequentially to minimize component downtime. + - `BestEffortParallel`: Updates Members in parallel to minimize component write downtime. Majority remains online + at all times. + - `Parallel`: Forces parallel updates. + enum: + - Serial + - BestEffortParallel + - Parallel + type: string + required: + - leader + type: object + customLabelSpecs: + description: Used for custom label tags which you want to add + to the component resources. + items: + description: CustomLabelSpec is deprecated since v0.8. + properties: + key: + description: The key of the label. + type: string + resources: + description: The resources that will be patched with the + label. + items: + description: GVKResource is deprecated since v0.8. + properties: + gvk: + description: |- + Represents the GVK of a resource, such as "v1/Pod", "apps/v1/StatefulSet", etc. + When a resource matching this is found by the selector, a custom label will be added if it doesn't already exist, + or updated if it does. + type: string + selector: + additionalProperties: + type: string + description: A label query used to filter a set + of resources. + type: object + required: + - gvk + type: object + type: array + value: + description: The value of the label. + type: string + required: + - key + - value + type: object + type: array + x-kubernetes-list-map-keys: + - key + x-kubernetes-list-type: map + description: + description: Description of the component definition. + type: string + exporter: + description: Defines the metrics exporter. + properties: + containerName: + description: Specifies the name of the built-in metrics + exporter container. + type: string + scrapePath: + description: |- + Specifies the http/https url path to scrape for metrics. + If empty, Prometheus uses the default value (e.g. `/metrics`). + type: string + scrapePort: + description: Specifies the port name to scrape for metrics. + type: string + scrapeScheme: + description: |- + Specifies the schema to use for scraping. + `http` and `https` are the expected values unless you rewrite the `__scheme__` label via relabeling. + If empty, Prometheus uses the default value `http`. + enum: + - http + - https + type: string + type: object + horizontalScalePolicy: + description: Defines the behavior of horizontal scale. + properties: + backupPolicyTemplateName: + description: Refers to the backup policy template. + type: string + type: + default: None + description: |- + Determines the data synchronization method when a component scales out. + The policy can be one of the following: {None, CloneVolume}. The default policy is `None`. + + + - `None`: This is the default policy. It creates an empty volume without data cloning. + - `CloneVolume`: This policy clones data to newly scaled pods. It first tries to use a volume snapshot. + If volume snapshot is not enabled, it will attempt to use a backup tool. If neither method works, it will report an error. + - `Snapshot`: This policy is deprecated and is an alias for CloneVolume. + enum: + - None + - CloneVolume + - Snapshot + type: string + volumeMountsName: + description: |- + Specifies the volumeMount of the container to backup. + This only works if Type is not None. If not specified, the first volumeMount will be selected. + type: string + type: object + logConfigs: + description: Specify the logging files which can be observed + and configured by cluster users. + items: + properties: + filePathPattern: + description: |- + Specifies the paths or patterns identifying where the log files are stored. + This field allows the system to locate and manage log files effectively. + + + Examples: + + + - /home/postgres/pgdata/pgroot/data/log/postgresql-* + - /data/mysql/log/mysqld-error.log + maxLength: 4096 + type: string + name: + description: |- + Specifies a descriptive label for the log type, such as 'slow' for a MySQL slow log file. + It provides a clear identification of the log's purpose and content. + maxLength: 128 + type: string + required: + - filePathPattern + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + monitor: + description: |- + Deprecated since v0.9 + monitor is monitoring config which provided by provider. + properties: + builtIn: + default: false + description: |- + builtIn is a switch to enable KubeBlocks builtIn monitoring. + If BuiltIn is set to true, monitor metrics will be scraped automatically. + If BuiltIn is set to false, the provider should set ExporterConfig and Sidecar container own. + type: boolean + exporterConfig: + description: |- + exporterConfig provided by provider, which specify necessary information to Time Series Database. + exporterConfig is valid when builtIn is false. + properties: + scrapePath: + default: /metrics + description: scrapePath is exporter url path for Time + Series Database to scrape metrics. + maxLength: 128 + type: string + scrapePort: + anyOf: + - type: integer + - type: string + description: scrapePort is exporter port for Time Series + Database to scrape metrics. + x-kubernetes-int-or-string: true + required: + - scrapePort + type: object + type: object + name: + description: |- + This name could be used as default name of `cluster.spec.componentSpecs.name`, and needs to conform with same + validation rules as `cluster.spec.componentSpecs.name`, currently complying with IANA Service Naming rule. + This name will apply to cluster objects as the value of label "apps.kubeblocks.io/component-name". + maxLength: 22 + pattern: ^[a-z]([a-z0-9\-]*[a-z0-9])?$ + type: string + podSpec: + description: Defines the pod spec template of component. + properties: + activeDeadlineSeconds: + description: |- + Optional duration in seconds the pod may be active on the node relative to + StartTime before the system will actively try to mark it failed and kill associated containers. + Value must be a positive integer. + format: int64 + type: integer + affinity: + description: If specified, the pod's scheduling constraints + properties: + nodeAffinity: + description: Describes node affinity scheduling rules + for the pod. + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node matches the corresponding matchExpressions; the + node(s) with the highest sum are the most preferred. + items: + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). + properties: + preference: + description: A node selector term, associated + with the corresponding weight. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that + the selector applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that + the selector applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + weight: + description: Weight associated with matching + the corresponding nodeSelectorTerm, in the + range 1-100. + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. + properties: + nodeSelectorTerms: + description: Required. A list of node selector + terms. The terms are ORed. + items: + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that + the selector applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that + the selector applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + type: array + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + description: Describes pod affinity scheduling rules + (e.g. co-locate this pod in the same node, zone, etc. + as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched + WeightedPodAffinityTerm fields are added per-node + to find the most preferred node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, + associated with the corresponding weight. + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a + list of label selector requirements. + The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. + Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a + list of label selector requirements. + The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: |- + weight associated with matching the corresponding podAffinityTerm, + in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. + items: + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. + Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + description: Describes pod anti-affinity scheduling + rules (e.g. avoid putting this pod in the same node, + zone, etc. as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the anti-affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched + WeightedPodAffinityTerm fields are added per-node + to find the most preferred node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, + associated with the corresponding weight. + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a + list of label selector requirements. + The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. + Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a + list of label selector requirements. + The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: |- + weight associated with matching the corresponding podAffinityTerm, + in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the anti-affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the anti-affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. + items: + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. + Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + automountServiceAccountToken: + description: AutomountServiceAccountToken indicates whether + a service account token should be automatically mounted. + type: boolean + containers: + description: |- + List of containers belonging to the pod. + Containers cannot currently be added or removed. + There must be at least one container in a Pod. + Cannot be updated. + items: + description: A single application container that you want + to run within a pod. + properties: + args: + description: |- + Arguments to the entrypoint. + The container image's CMD is used if this is not provided. + Variable references $(VAR_NAME) are expanded using the container's environment. If a variable + cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will + produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless + of whether the variable exists or not. Cannot be updated. + More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell + items: + type: string + type: array + command: + description: |- + Entrypoint array. Not executed within a shell. + The container image's ENTRYPOINT is used if this is not provided. + Variable references $(VAR_NAME) are expanded using the container's environment. If a variable + cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will + produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless + of whether the variable exists or not. Cannot be updated. + More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell + items: + type: string + type: array + env: + description: |- + List of environment variables to set in the container. + Cannot be updated. + items: + description: EnvVar represents an environment variable + present in a Container. + properties: + name: + description: Name of the environment variable. + Must be a C_IDENTIFIER. + type: string + value: + description: |- + Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in the container and + any service environment variables. If a variable cannot be resolved, + the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless of whether the variable + exists or not. + Defaults to "". + type: string + valueFrom: + description: Source for the environment variable's + value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the + FieldPath is written in terms of, + defaults to "v1". + type: string + fieldPath: + description: Path of the field to select + in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required + for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format + of the exposed resources, defaults + to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to + select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in + the pod's namespace + properties: + key: + description: The key of the secret to + select from. Must be a valid secret + key. + type: string + 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 + optional: + description: Specify whether the Secret + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + envFrom: + description: |- + List of sources to populate environment variables in the container. + The keys defined within a source must be a C_IDENTIFIER. All invalid keys + will be reported as an event when the container is starting. When a key exists in multiple + sources, the value associated with the last source will take precedence. + Values defined by an Env with a duplicate key will take precedence. + Cannot be updated. + items: + description: EnvFromSource represents the source + of a set of ConfigMaps + properties: + configMapRef: + description: The ConfigMap to select from + 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 + optional: + description: Specify whether the ConfigMap + must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + description: An optional identifier to prepend + to each key in the ConfigMap. Must be a C_IDENTIFIER. + type: string + secretRef: + description: The Secret to select from + 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 + optional: + description: Specify whether the Secret + must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + image: + description: |- + Container image name. + More info: https://kubernetes.io/docs/concepts/containers/images + This field is optional to allow higher level config management to default or override + container images in workload controllers like Deployments and StatefulSets. + type: string + imagePullPolicy: + description: |- + Image pull policy. + One of Always, Never, IfNotPresent. + Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/containers/images#updating-images + type: string + lifecycle: + description: |- + Actions that the management system should take in response to container lifecycle events. + Cannot be updated. + properties: + postStart: + description: |- + PostStart is called immediately after a container is created. If the handler fails, + the container is terminated and restarted according to its restart policy. + Other management of the container blocks until the hook completes. + More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks + properties: + exec: + description: Exec specifies the action to + take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in + the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a + custom header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP + server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + sleep: + description: Sleep represents the duration + that the container should sleep before being + terminated. + properties: + seconds: + description: Seconds is the number of + seconds to sleep. + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + description: |- + Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept + for the backward compatibility. There are no validation of this field and + lifecycle hooks will fail in runtime when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + description: |- + PreStop is called immediately before a container is terminated due to an + API request or management event such as liveness/startup probe failure, + preemption, resource contention, etc. The handler is not called if the + container crashes or exits. The Pod's termination grace period countdown begins before the + PreStop hook is executed. Regardless of the outcome of the handler, the + container will eventually terminate within the Pod's termination grace + period (unless delayed by finalizers). Other management of the container blocks until the hook completes + or until the termination grace period is reached. + More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks + properties: + exec: + description: Exec specifies the action to + take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in + the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a + custom header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP + server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + sleep: + description: Sleep represents the duration + that the container should sleep before being + terminated. + properties: + seconds: + description: Seconds is the number of + seconds to sleep. + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + description: |- + Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept + for the backward compatibility. There are no validation of this field and + lifecycle hooks will fail in runtime when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + description: |- + Periodic probe of container liveness. + Container will be restarted if the probe fails. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving + a GRPC port. + properties: + port: + description: Port number of the gRPC service. + Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the + request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + name: + description: |- + Name of the container specified as a DNS_LABEL. + Each container in a pod must have a unique name (DNS_LABEL). + Cannot be updated. + type: string + ports: + description: |- + List of ports to expose from the container. Not specifying a port here + DOES NOT prevent that port from being exposed. Any port which is + listening on the default "0.0.0.0" address inside a container will be + accessible from the network. + Modifying this array with strategic merge patch may corrupt the data. + For more information See https://github.com/kubernetes/kubernetes/issues/108255. + Cannot be updated. + items: + description: ContainerPort represents a network + port in a single container. + properties: + containerPort: + description: |- + Number of port to expose on the pod's IP address. + This must be a valid port number, 0 < x < 65536. + format: int32 + type: integer + hostIP: + description: What host IP to bind the external + port to. + type: string + hostPort: + description: |- + Number of port to expose on the host. + If specified, this must be a valid port number, 0 < x < 65536. + If HostNetwork is specified, this must match ContainerPort. + Most containers do not need this. + format: int32 + type: integer + name: + description: |- + If specified, this must be an IANA_SVC_NAME and unique within the pod. Each + named port in a pod must have a unique name. Name for the port that can be + referred to by services. + type: string + protocol: + default: TCP + description: |- + Protocol for port. Must be UDP, TCP, or SCTP. + Defaults to "TCP". + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + description: |- + Periodic probe of container service readiness. + Container will be removed from service endpoints if the probe fails. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving + a GRPC port. + properties: + port: + description: Port number of the gRPC service. + Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the + request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + resizePolicy: + description: Resources resize policy for the container. + items: + description: ContainerResizePolicy represents resource + resize policy for the container. + properties: + resourceName: + description: |- + Name of the resource to which this resource resize policy applies. + Supported values: cpu, memory. + type: string + restartPolicy: + description: |- + Restart policy to apply when specified resource is resized. + If not specified, it defaults to NotRequired. + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + description: |- + Compute Resources required by this container. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + properties: + claims: + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + + + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + + + This field is immutable. It can only be set for containers. + items: + description: ResourceClaim references one entry + in PodSpec.ResourceClaims. + properties: + name: + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + restartPolicy: + description: |- + RestartPolicy defines the restart behavior of individual containers in a pod. + This field may only be set for init containers, and the only allowed value is "Always". + For non-init containers or when this field is not specified, + the restart behavior is defined by the Pod's restart policy and the container type. + Setting the RestartPolicy as "Always" for the init container will have the following effect: + this init container will be continually restarted on + exit until all regular containers have terminated. Once all regular + containers have completed, all init containers with restartPolicy "Always" + will be shut down. This lifecycle differs from normal init containers and + is often referred to as a "sidecar" container. Although this init + container still starts in the init container sequence, it does not wait + for the container to complete before proceeding to the next init + container. Instead, the next init container starts immediately after this + init container is started, or after any startupProbe has successfully + completed. + type: string + securityContext: + description: |- + SecurityContext defines the security options the container should be run with. + If set, the fields of SecurityContext override the equivalent fields of PodSecurityContext. + More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ + properties: + allowPrivilegeEscalation: + description: |- + AllowPrivilegeEscalation controls whether a process can gain more + privileges than its parent process. This bool directly controls if + the no_new_privs flag will be set on the container process. + AllowPrivilegeEscalation is true always when the container is: + 1) run as Privileged + 2) has CAP_SYS_ADMIN + Note that this field cannot be set when spec.os.name is windows. + type: boolean + capabilities: + description: |- + The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the container runtime. + Note that this field cannot be set when spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX + capabilities type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX + capabilities type + type: string + type: array + type: object + privileged: + description: |- + Run container in privileged mode. + Processes in privileged containers are essentially equivalent to root on the host. + Defaults to false. + Note that this field cannot be set when spec.os.name is windows. + type: boolean + procMount: + description: |- + procMount denotes the type of proc mount to use for the containers. + The default is DefaultProcMount which uses the container runtime defaults for + readonly paths and masked paths. + This requires the ProcMountType feature flag to be enabled. + Note that this field cannot be set when spec.os.name is windows. + type: string + readOnlyRootFilesystem: + description: |- + Whether this container has a read-only root filesystem. + Default is false. + Note that this field cannot be set when spec.os.name is windows. + type: boolean + runAsGroup: + description: |- + The GID to run the entrypoint of the container process. + Uses runtime default if unset. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: |- + Indicates that the container must run as a non-root user. + If true, the Kubelet will validate the image at runtime to ensure that it + does not run as UID 0 (root) and fail to start the container if it does. + If unset or false, no such validation will be performed. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: |- + The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: |- + The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random SELinux context for each + container. May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label + that applies to the container. + type: string + role: + description: Role is a SELinux role label + that applies to the container. + type: string + type: + description: Type is a SELinux type label + that applies to the container. + type: string + user: + description: User is a SELinux user label + that applies to the container. + type: string + type: object + seccompProfile: + description: |- + The seccomp options to use by this container. If seccomp options are + provided at both the pod & container level, the container options + override the pod options. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile defined in a file on the node should be used. + The profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be set for any other type. + type: string + type: + description: |- + type indicates which kind of seccomp profile will be applied. + Valid options are: + + + Localhost - a profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile should be used. + Unconfined - no profile should be applied. + type: string + required: + - type + type: object + windowsOptions: + description: |- + The Windows specific settings applied to all containers. + If unspecified, the options from the PodSecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: |- + GMSACredentialSpec is where the GMSA admission webhook + (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the + GMSA credential spec named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the + name of the GMSA credential spec to use. + type: string + hostProcess: + description: |- + HostProcess determines if a container should be run as a 'Host Process' container. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: |- + The UserName in Windows to run the entrypoint of the container process. + Defaults to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: string + type: object + type: object + startupProbe: + description: |- + StartupProbe indicates that the Pod has successfully initialized. + If specified, no other probes are executed until this completes successfully. + If this probe fails, the Pod will be restarted, just as if the livenessProbe failed. + This can be used to provide different probe parameters at the beginning of a Pod's lifecycle, + when it might take a long time to load data or warm a cache, than during steady-state operation. + This cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving + a GRPC port. + properties: + port: + description: Port number of the gRPC service. + Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the + request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + stdin: + description: |- + Whether this container should allocate a buffer for stdin in the container runtime. If this + is not set, reads from stdin in the container will always result in EOF. + Default is false. + type: boolean + stdinOnce: + description: |- + Whether the container runtime should close the stdin channel after it has been opened by + a single attach. When stdin is true the stdin stream will remain open across multiple attach + sessions. If stdinOnce is set to true, stdin is opened on container start, is empty until the + first client attaches to stdin, and then remains open and accepts data until the client disconnects, + at which time stdin is closed and remains closed until the container is restarted. If this + flag is false, a container processes that reads from stdin will never receive an EOF. + Default is false + type: boolean + terminationMessagePath: + description: |- + Optional: Path at which the file to which the container's termination message + will be written is mounted into the container's filesystem. + Message written is intended to be brief final status, such as an assertion failure message. + Will be truncated by the node if greater than 4096 bytes. The total message length across + all containers will be limited to 12kb. + Defaults to /dev/termination-log. + Cannot be updated. + type: string + terminationMessagePolicy: + description: |- + Indicate how the termination message should be populated. File will use the contents of + terminationMessagePath to populate the container status message on both success and failure. + FallbackToLogsOnError will use the last chunk of container log output if the termination + message file is empty and the container exited with an error. + The log output is limited to 2048 bytes or 80 lines, whichever is smaller. + Defaults to File. + Cannot be updated. + type: string + tty: + description: |- + Whether this container should allocate a TTY for itself, also requires 'stdin' to be true. + Default is false. + type: boolean + volumeDevices: + description: volumeDevices is the list of block devices + to be used by the container. + items: + description: volumeDevice describes a mapping of + a raw block device within a container. + properties: + devicePath: + description: devicePath is the path inside of + the container that the device will be mapped + to. + type: string + name: + description: name must match the name of a persistentVolumeClaim + in the pod + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + description: |- + Pod volumes to mount into the container's filesystem. + Cannot be updated. + items: + description: VolumeMount describes a mounting of + a Volume within a container. + properties: + mountPath: + description: |- + Path within the container at which the volume should be mounted. Must + not contain ':'. + type: string + mountPropagation: + description: |- + mountPropagation determines how mounts are propagated from the host + to container and the other way around. + When not set, MountPropagationNone is used. + This field is beta in 1.10. + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: |- + Mounted read-only if true, read-write otherwise (false or unspecified). + Defaults to false. + type: boolean + subPath: + description: |- + Path within the volume from which the container's volume should be mounted. + Defaults to "" (volume's root). + type: string + subPathExpr: + description: |- + Expanded path within the volume from which the container's volume should be mounted. + Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment. + Defaults to "" (volume's root). + SubPathExpr and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + description: |- + Container's working directory. + If not specified, the container runtime's default will be used, which + might be configured in the container image. + Cannot be updated. + type: string + required: + - name + type: object + type: array + dnsConfig: + description: |- + Specifies the DNS parameters of a pod. + Parameters specified here will be merged to the generated DNS + configuration based on DNSPolicy. + properties: + nameservers: + description: |- + A list of DNS name server IP addresses. + This will be appended to the base nameservers generated from DNSPolicy. + Duplicated nameservers will be removed. + items: + type: string + type: array + options: + description: |- + A list of DNS resolver options. + This will be merged with the base options generated from DNSPolicy. + Duplicated entries will be removed. Resolution options given in Options + will override those that appear in the base DNSPolicy. + items: + description: PodDNSConfigOption defines DNS resolver + options of a pod. + properties: + name: + description: Required. + type: string + value: + type: string + type: object + type: array + searches: + description: |- + A list of DNS search domains for host-name lookup. + This will be appended to the base search paths generated from DNSPolicy. + Duplicated search paths will be removed. + items: + type: string + type: array + type: object + dnsPolicy: + description: |- + Set DNS policy for the pod. + Defaults to "ClusterFirst". + Valid values are 'ClusterFirstWithHostNet', 'ClusterFirst', 'Default' or 'None'. + DNS parameters given in DNSConfig will be merged with the policy selected with DNSPolicy. + To have DNS options set along with hostNetwork, you have to specify DNS policy + explicitly to 'ClusterFirstWithHostNet'. + type: string + enableServiceLinks: + description: |- + EnableServiceLinks indicates whether information about services should be injected into pod's + environment variables, matching the syntax of Docker links. + Optional: Defaults to true. + type: boolean + ephemeralContainers: + description: |- + List of ephemeral containers run in this pod. Ephemeral containers may be run in an existing + pod to perform user-initiated actions such as debugging. This list cannot be specified when + creating a pod, and it cannot be modified by updating the pod spec. In order to add an + ephemeral container to an existing pod, use the pod's ephemeralcontainers subresource. + items: + description: |- + An EphemeralContainer is a temporary container that you may add to an existing Pod for + user-initiated activities such as debugging. Ephemeral containers have no resource or + scheduling guarantees, and they will not be restarted when they exit or when a Pod is + removed or restarted. The kubelet may evict a Pod if an ephemeral container causes the + Pod to exceed its resource allocation. + + + To add an ephemeral container, use the ephemeralcontainers subresource of an existing + Pod. Ephemeral containers may not be removed or restarted. + properties: + args: + description: |- + Arguments to the entrypoint. + The image's CMD is used if this is not provided. + Variable references $(VAR_NAME) are expanded using the container's environment. If a variable + cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will + produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless + of whether the variable exists or not. Cannot be updated. + More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell + items: + type: string + type: array + command: + description: |- + Entrypoint array. Not executed within a shell. + The image's ENTRYPOINT is used if this is not provided. + Variable references $(VAR_NAME) are expanded using the container's environment. If a variable + cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will + produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless + of whether the variable exists or not. Cannot be updated. + More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell + items: + type: string + type: array + env: + description: |- + List of environment variables to set in the container. + Cannot be updated. + items: + description: EnvVar represents an environment variable + present in a Container. + properties: + name: + description: Name of the environment variable. + Must be a C_IDENTIFIER. + type: string + value: + description: |- + Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in the container and + any service environment variables. If a variable cannot be resolved, + the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless of whether the variable + exists or not. + Defaults to "". + type: string + valueFrom: + description: Source for the environment variable's + value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the + FieldPath is written in terms of, + defaults to "v1". + type: string + fieldPath: + description: Path of the field to select + in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required + for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format + of the exposed resources, defaults + to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to + select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in + the pod's namespace + properties: + key: + description: The key of the secret to + select from. Must be a valid secret + key. + type: string + 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 + optional: + description: Specify whether the Secret + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + envFrom: + description: |- + List of sources to populate environment variables in the container. + The keys defined within a source must be a C_IDENTIFIER. All invalid keys + will be reported as an event when the container is starting. When a key exists in multiple + sources, the value associated with the last source will take precedence. + Values defined by an Env with a duplicate key will take precedence. + Cannot be updated. + items: + description: EnvFromSource represents the source + of a set of ConfigMaps + properties: + configMapRef: + description: The ConfigMap to select from + 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 + optional: + description: Specify whether the ConfigMap + must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + description: An optional identifier to prepend + to each key in the ConfigMap. Must be a C_IDENTIFIER. + type: string + secretRef: + description: The Secret to select from + 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 + optional: + description: Specify whether the Secret + must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + image: + description: |- + Container image name. + More info: https://kubernetes.io/docs/concepts/containers/images + type: string + imagePullPolicy: + description: |- + Image pull policy. + One of Always, Never, IfNotPresent. + Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/containers/images#updating-images + type: string + lifecycle: + description: Lifecycle is not allowed for ephemeral + containers. + properties: + postStart: + description: |- + PostStart is called immediately after a container is created. If the handler fails, + the container is terminated and restarted according to its restart policy. + Other management of the container blocks until the hook completes. + More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks + properties: + exec: + description: Exec specifies the action to + take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in + the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a + custom header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP + server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + sleep: + description: Sleep represents the duration + that the container should sleep before being + terminated. + properties: + seconds: + description: Seconds is the number of + seconds to sleep. + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + description: |- + Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept + for the backward compatibility. There are no validation of this field and + lifecycle hooks will fail in runtime when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + description: |- + PreStop is called immediately before a container is terminated due to an + API request or management event such as liveness/startup probe failure, + preemption, resource contention, etc. The handler is not called if the + container crashes or exits. The Pod's termination grace period countdown begins before the + PreStop hook is executed. Regardless of the outcome of the handler, the + container will eventually terminate within the Pod's termination grace + period (unless delayed by finalizers). Other management of the container blocks until the hook completes + or until the termination grace period is reached. + More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks + properties: + exec: + description: Exec specifies the action to + take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in + the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a + custom header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP + server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + sleep: + description: Sleep represents the duration + that the container should sleep before being + terminated. + properties: + seconds: + description: Seconds is the number of + seconds to sleep. + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + description: |- + Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept + for the backward compatibility. There are no validation of this field and + lifecycle hooks will fail in runtime when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + description: Probes are not allowed for ephemeral + containers. + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving + a GRPC port. + properties: + port: + description: Port number of the gRPC service. + Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the + request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + name: + description: |- + Name of the ephemeral container specified as a DNS_LABEL. + This name must be unique among all containers, init containers and ephemeral containers. + type: string + ports: + description: Ports are not allowed for ephemeral containers. + items: + description: ContainerPort represents a network + port in a single container. + properties: + containerPort: + description: |- + Number of port to expose on the pod's IP address. + This must be a valid port number, 0 < x < 65536. + format: int32 + type: integer + hostIP: + description: What host IP to bind the external + port to. + type: string + hostPort: + description: |- + Number of port to expose on the host. + If specified, this must be a valid port number, 0 < x < 65536. + If HostNetwork is specified, this must match ContainerPort. + Most containers do not need this. + format: int32 + type: integer + name: + description: |- + If specified, this must be an IANA_SVC_NAME and unique within the pod. Each + named port in a pod must have a unique name. Name for the port that can be + referred to by services. + type: string + protocol: + default: TCP + description: |- + Protocol for port. Must be UDP, TCP, or SCTP. + Defaults to "TCP". + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + description: Probes are not allowed for ephemeral + containers. + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving + a GRPC port. + properties: + port: + description: Port number of the gRPC service. + Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the + request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + resizePolicy: + description: Resources resize policy for the container. + items: + description: ContainerResizePolicy represents resource + resize policy for the container. + properties: + resourceName: + description: |- + Name of the resource to which this resource resize policy applies. + Supported values: cpu, memory. + type: string + restartPolicy: + description: |- + Restart policy to apply when specified resource is resized. + If not specified, it defaults to NotRequired. + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + description: |- + Resources are not allowed for ephemeral containers. Ephemeral containers use spare resources + already allocated to the pod. + properties: + claims: + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + + + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + + + This field is immutable. It can only be set for containers. + items: + description: ResourceClaim references one entry + in PodSpec.ResourceClaims. + properties: + name: + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + restartPolicy: + description: |- + Restart policy for the container to manage the restart behavior of each + container within a pod. + This may only be set for init containers. You cannot set this field on + ephemeral containers. + type: string + securityContext: + description: |- + Optional: SecurityContext defines the security options the ephemeral container should be run with. + If set, the fields of SecurityContext override the equivalent fields of PodSecurityContext. + properties: + allowPrivilegeEscalation: + description: |- + AllowPrivilegeEscalation controls whether a process can gain more + privileges than its parent process. This bool directly controls if + the no_new_privs flag will be set on the container process. + AllowPrivilegeEscalation is true always when the container is: + 1) run as Privileged + 2) has CAP_SYS_ADMIN + Note that this field cannot be set when spec.os.name is windows. + type: boolean + capabilities: + description: |- + The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the container runtime. + Note that this field cannot be set when spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX + capabilities type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX + capabilities type + type: string + type: array + type: object + privileged: + description: |- + Run container in privileged mode. + Processes in privileged containers are essentially equivalent to root on the host. + Defaults to false. + Note that this field cannot be set when spec.os.name is windows. + type: boolean + procMount: + description: |- + procMount denotes the type of proc mount to use for the containers. + The default is DefaultProcMount which uses the container runtime defaults for + readonly paths and masked paths. + This requires the ProcMountType feature flag to be enabled. + Note that this field cannot be set when spec.os.name is windows. + type: string + readOnlyRootFilesystem: + description: |- + Whether this container has a read-only root filesystem. + Default is false. + Note that this field cannot be set when spec.os.name is windows. + type: boolean + runAsGroup: + description: |- + The GID to run the entrypoint of the container process. + Uses runtime default if unset. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: |- + Indicates that the container must run as a non-root user. + If true, the Kubelet will validate the image at runtime to ensure that it + does not run as UID 0 (root) and fail to start the container if it does. + If unset or false, no such validation will be performed. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: |- + The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: |- + The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random SELinux context for each + container. May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label + that applies to the container. + type: string + role: + description: Role is a SELinux role label + that applies to the container. + type: string + type: + description: Type is a SELinux type label + that applies to the container. + type: string + user: + description: User is a SELinux user label + that applies to the container. + type: string + type: object + seccompProfile: + description: |- + The seccomp options to use by this container. If seccomp options are + provided at both the pod & container level, the container options + override the pod options. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile defined in a file on the node should be used. + The profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be set for any other type. + type: string + type: + description: |- + type indicates which kind of seccomp profile will be applied. + Valid options are: + + + Localhost - a profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile should be used. + Unconfined - no profile should be applied. + type: string + required: + - type + type: object + windowsOptions: + description: |- + The Windows specific settings applied to all containers. + If unspecified, the options from the PodSecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: |- + GMSACredentialSpec is where the GMSA admission webhook + (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the + GMSA credential spec named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the + name of the GMSA credential spec to use. + type: string + hostProcess: + description: |- + HostProcess determines if a container should be run as a 'Host Process' container. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: |- + The UserName in Windows to run the entrypoint of the container process. + Defaults to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: string + type: object + type: object + startupProbe: + description: Probes are not allowed for ephemeral + containers. + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving + a GRPC port. + properties: + port: + description: Port number of the gRPC service. + Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the + request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + stdin: + description: |- + Whether this container should allocate a buffer for stdin in the container runtime. If this + is not set, reads from stdin in the container will always result in EOF. + Default is false. + type: boolean + stdinOnce: + description: |- + Whether the container runtime should close the stdin channel after it has been opened by + a single attach. When stdin is true the stdin stream will remain open across multiple attach + sessions. If stdinOnce is set to true, stdin is opened on container start, is empty until the + first client attaches to stdin, and then remains open and accepts data until the client disconnects, + at which time stdin is closed and remains closed until the container is restarted. If this + flag is false, a container processes that reads from stdin will never receive an EOF. + Default is false + type: boolean + targetContainerName: + description: |- + If set, the name of the container from PodSpec that this ephemeral container targets. + The ephemeral container will be run in the namespaces (IPC, PID, etc) of this container. + If not set then the ephemeral container uses the namespaces configured in the Pod spec. + + + The container runtime must implement support for this feature. If the runtime does not + support namespace targeting then the result of setting this field is undefined. + type: string + terminationMessagePath: + description: |- + Optional: Path at which the file to which the container's termination message + will be written is mounted into the container's filesystem. + Message written is intended to be brief final status, such as an assertion failure message. + Will be truncated by the node if greater than 4096 bytes. The total message length across + all containers will be limited to 12kb. + Defaults to /dev/termination-log. + Cannot be updated. + type: string + terminationMessagePolicy: + description: |- + Indicate how the termination message should be populated. File will use the contents of + terminationMessagePath to populate the container status message on both success and failure. + FallbackToLogsOnError will use the last chunk of container log output if the termination + message file is empty and the container exited with an error. + The log output is limited to 2048 bytes or 80 lines, whichever is smaller. + Defaults to File. + Cannot be updated. + type: string + tty: + description: |- + Whether this container should allocate a TTY for itself, also requires 'stdin' to be true. + Default is false. + type: boolean + volumeDevices: + description: volumeDevices is the list of block devices + to be used by the container. + items: + description: volumeDevice describes a mapping of + a raw block device within a container. + properties: + devicePath: + description: devicePath is the path inside of + the container that the device will be mapped + to. + type: string + name: + description: name must match the name of a persistentVolumeClaim + in the pod + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + description: |- + Pod volumes to mount into the container's filesystem. Subpath mounts are not allowed for ephemeral containers. + Cannot be updated. + items: + description: VolumeMount describes a mounting of + a Volume within a container. + properties: + mountPath: + description: |- + Path within the container at which the volume should be mounted. Must + not contain ':'. + type: string + mountPropagation: + description: |- + mountPropagation determines how mounts are propagated from the host + to container and the other way around. + When not set, MountPropagationNone is used. + This field is beta in 1.10. + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: |- + Mounted read-only if true, read-write otherwise (false or unspecified). + Defaults to false. + type: boolean + subPath: + description: |- + Path within the volume from which the container's volume should be mounted. + Defaults to "" (volume's root). + type: string + subPathExpr: + description: |- + Expanded path within the volume from which the container's volume should be mounted. + Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment. + Defaults to "" (volume's root). + SubPathExpr and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + description: |- + Container's working directory. + If not specified, the container runtime's default will be used, which + might be configured in the container image. + Cannot be updated. + type: string + required: + - name + type: object + type: array + hostAliases: + description: |- + HostAliases is an optional list of hosts and IPs that will be injected into the pod's hosts + file if specified. This is only valid for non-hostNetwork pods. + items: + description: |- + HostAlias holds the mapping between IP and hostnames that will be injected as an entry in the + pod's hosts file. + properties: + hostnames: + description: Hostnames for the above IP address. + items: + type: string + type: array + ip: + description: IP address of the host file entry. + type: string + type: object + type: array + hostIPC: + description: |- + Use the host's ipc namespace. + Optional: Default to false. + type: boolean + hostNetwork: + description: |- + Host networking requested for this pod. Use the host's network namespace. + If this option is set, the ports that will be used must be specified. + Default to false. + type: boolean + hostPID: + description: |- + Use the host's pid namespace. + Optional: Default to false. + type: boolean + hostUsers: + description: |- + Use the host's user namespace. + Optional: Default to true. + If set to true or not present, the pod will be run in the host user namespace, useful + for when the pod needs a feature only available to the host user namespace, such as + loading a kernel module with CAP_SYS_MODULE. + When set to false, a new userns is created for the pod. Setting false is useful for + mitigating container breakout vulnerabilities even allowing users to run their + containers as root without actually having root privileges on the host. + This field is alpha-level and is only honored by servers that enable the UserNamespacesSupport feature. + type: boolean + hostname: + description: |- + Specifies the hostname of the Pod + If not specified, the pod's hostname will be set to a system-defined value. + type: string + imagePullSecrets: + description: |- + ImagePullSecrets is an optional list of references to secrets in the same namespace to use for pulling any of the images used by this PodSpec. + If specified, these secrets will be passed to individual puller implementations for them to use. + More info: https://kubernetes.io/docs/concepts/containers/images#specifying-imagepullsecrets-on-a-pod + items: + 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? + type: string + type: object + x-kubernetes-map-type: atomic + type: array + initContainers: + description: |- + List of initialization containers belonging to the pod. + Init containers are executed in order prior to containers being started. If any + init container fails, the pod is considered to have failed and is handled according + to its restartPolicy. The name for an init container or normal container must be + unique among all containers. + Init containers may not have Lifecycle actions, Readiness probes, Liveness probes, or Startup probes. + The resourceRequirements of an init container are taken into account during scheduling + by finding the highest request/limit for each resource type, and then using the max of + of that value or the sum of the normal containers. Limits are applied to init containers + in a similar fashion. + Init containers cannot currently be added or removed. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/init-containers/ + items: + description: A single application container that you want + to run within a pod. + properties: + args: + description: |- + Arguments to the entrypoint. + The container image's CMD is used if this is not provided. + Variable references $(VAR_NAME) are expanded using the container's environment. If a variable + cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will + produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless + of whether the variable exists or not. Cannot be updated. + More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell + items: + type: string + type: array + command: + description: |- + Entrypoint array. Not executed within a shell. + The container image's ENTRYPOINT is used if this is not provided. + Variable references $(VAR_NAME) are expanded using the container's environment. If a variable + cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will + produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless + of whether the variable exists or not. Cannot be updated. + More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell + items: + type: string + type: array + env: + description: |- + List of environment variables to set in the container. + Cannot be updated. + items: + description: EnvVar represents an environment variable + present in a Container. + properties: + name: + description: Name of the environment variable. + Must be a C_IDENTIFIER. + type: string + value: + description: |- + Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in the container and + any service environment variables. If a variable cannot be resolved, + the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless of whether the variable + exists or not. + Defaults to "". + type: string + valueFrom: + description: Source for the environment variable's + value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the + FieldPath is written in terms of, + defaults to "v1". + type: string + fieldPath: + description: Path of the field to select + in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required + for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format + of the exposed resources, defaults + to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to + select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in + the pod's namespace + properties: + key: + description: The key of the secret to + select from. Must be a valid secret + key. + type: string + 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 + optional: + description: Specify whether the Secret + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + envFrom: + description: |- + List of sources to populate environment variables in the container. + The keys defined within a source must be a C_IDENTIFIER. All invalid keys + will be reported as an event when the container is starting. When a key exists in multiple + sources, the value associated with the last source will take precedence. + Values defined by an Env with a duplicate key will take precedence. + Cannot be updated. + items: + description: EnvFromSource represents the source + of a set of ConfigMaps + properties: + configMapRef: + description: The ConfigMap to select from + 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 + optional: + description: Specify whether the ConfigMap + must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + description: An optional identifier to prepend + to each key in the ConfigMap. Must be a C_IDENTIFIER. + type: string + secretRef: + description: The Secret to select from + 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 + optional: + description: Specify whether the Secret + must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + image: + description: |- + Container image name. + More info: https://kubernetes.io/docs/concepts/containers/images + This field is optional to allow higher level config management to default or override + container images in workload controllers like Deployments and StatefulSets. + type: string + imagePullPolicy: + description: |- + Image pull policy. + One of Always, Never, IfNotPresent. + Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/containers/images#updating-images + type: string + lifecycle: + description: |- + Actions that the management system should take in response to container lifecycle events. + Cannot be updated. + properties: + postStart: + description: |- + PostStart is called immediately after a container is created. If the handler fails, + the container is terminated and restarted according to its restart policy. + Other management of the container blocks until the hook completes. + More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks + properties: + exec: + description: Exec specifies the action to + take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in + the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a + custom header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP + server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + sleep: + description: Sleep represents the duration + that the container should sleep before being + terminated. + properties: + seconds: + description: Seconds is the number of + seconds to sleep. + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + description: |- + Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept + for the backward compatibility. There are no validation of this field and + lifecycle hooks will fail in runtime when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + description: |- + PreStop is called immediately before a container is terminated due to an + API request or management event such as liveness/startup probe failure, + preemption, resource contention, etc. The handler is not called if the + container crashes or exits. The Pod's termination grace period countdown begins before the + PreStop hook is executed. Regardless of the outcome of the handler, the + container will eventually terminate within the Pod's termination grace + period (unless delayed by finalizers). Other management of the container blocks until the hook completes + or until the termination grace period is reached. + More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks + properties: + exec: + description: Exec specifies the action to + take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in + the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a + custom header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP + server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + sleep: + description: Sleep represents the duration + that the container should sleep before being + terminated. + properties: + seconds: + description: Seconds is the number of + seconds to sleep. + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + description: |- + Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept + for the backward compatibility. There are no validation of this field and + lifecycle hooks will fail in runtime when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + description: |- + Periodic probe of container liveness. + Container will be restarted if the probe fails. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving + a GRPC port. + properties: + port: + description: Port number of the gRPC service. + Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the + request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + name: + description: |- + Name of the container specified as a DNS_LABEL. + Each container in a pod must have a unique name (DNS_LABEL). + Cannot be updated. + type: string + ports: + description: |- + List of ports to expose from the container. Not specifying a port here + DOES NOT prevent that port from being exposed. Any port which is + listening on the default "0.0.0.0" address inside a container will be + accessible from the network. + Modifying this array with strategic merge patch may corrupt the data. + For more information See https://github.com/kubernetes/kubernetes/issues/108255. + Cannot be updated. + items: + description: ContainerPort represents a network + port in a single container. + properties: + containerPort: + description: |- + Number of port to expose on the pod's IP address. + This must be a valid port number, 0 < x < 65536. + format: int32 + type: integer + hostIP: + description: What host IP to bind the external + port to. + type: string + hostPort: + description: |- + Number of port to expose on the host. + If specified, this must be a valid port number, 0 < x < 65536. + If HostNetwork is specified, this must match ContainerPort. + Most containers do not need this. + format: int32 + type: integer + name: + description: |- + If specified, this must be an IANA_SVC_NAME and unique within the pod. Each + named port in a pod must have a unique name. Name for the port that can be + referred to by services. + type: string + protocol: + default: TCP + description: |- + Protocol for port. Must be UDP, TCP, or SCTP. + Defaults to "TCP". + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + description: |- + Periodic probe of container service readiness. + Container will be removed from service endpoints if the probe fails. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving + a GRPC port. + properties: + port: + description: Port number of the gRPC service. + Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the + request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + resizePolicy: + description: Resources resize policy for the container. + items: + description: ContainerResizePolicy represents resource + resize policy for the container. + properties: + resourceName: + description: |- + Name of the resource to which this resource resize policy applies. + Supported values: cpu, memory. + type: string + restartPolicy: + description: |- + Restart policy to apply when specified resource is resized. + If not specified, it defaults to NotRequired. + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + description: |- + Compute Resources required by this container. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + properties: + claims: + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + + + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + + + This field is immutable. It can only be set for containers. + items: + description: ResourceClaim references one entry + in PodSpec.ResourceClaims. + properties: + name: + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + restartPolicy: + description: |- + RestartPolicy defines the restart behavior of individual containers in a pod. + This field may only be set for init containers, and the only allowed value is "Always". + For non-init containers or when this field is not specified, + the restart behavior is defined by the Pod's restart policy and the container type. + Setting the RestartPolicy as "Always" for the init container will have the following effect: + this init container will be continually restarted on + exit until all regular containers have terminated. Once all regular + containers have completed, all init containers with restartPolicy "Always" + will be shut down. This lifecycle differs from normal init containers and + is often referred to as a "sidecar" container. Although this init + container still starts in the init container sequence, it does not wait + for the container to complete before proceeding to the next init + container. Instead, the next init container starts immediately after this + init container is started, or after any startupProbe has successfully + completed. + type: string + securityContext: + description: |- + SecurityContext defines the security options the container should be run with. + If set, the fields of SecurityContext override the equivalent fields of PodSecurityContext. + More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ + properties: + allowPrivilegeEscalation: + description: |- + AllowPrivilegeEscalation controls whether a process can gain more + privileges than its parent process. This bool directly controls if + the no_new_privs flag will be set on the container process. + AllowPrivilegeEscalation is true always when the container is: + 1) run as Privileged + 2) has CAP_SYS_ADMIN + Note that this field cannot be set when spec.os.name is windows. + type: boolean + capabilities: + description: |- + The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the container runtime. + Note that this field cannot be set when spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX + capabilities type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX + capabilities type + type: string + type: array + type: object + privileged: + description: |- + Run container in privileged mode. + Processes in privileged containers are essentially equivalent to root on the host. + Defaults to false. + Note that this field cannot be set when spec.os.name is windows. + type: boolean + procMount: + description: |- + procMount denotes the type of proc mount to use for the containers. + The default is DefaultProcMount which uses the container runtime defaults for + readonly paths and masked paths. + This requires the ProcMountType feature flag to be enabled. + Note that this field cannot be set when spec.os.name is windows. + type: string + readOnlyRootFilesystem: + description: |- + Whether this container has a read-only root filesystem. + Default is false. + Note that this field cannot be set when spec.os.name is windows. + type: boolean + runAsGroup: + description: |- + The GID to run the entrypoint of the container process. + Uses runtime default if unset. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: |- + Indicates that the container must run as a non-root user. + If true, the Kubelet will validate the image at runtime to ensure that it + does not run as UID 0 (root) and fail to start the container if it does. + If unset or false, no such validation will be performed. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: |- + The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: |- + The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random SELinux context for each + container. May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label + that applies to the container. + type: string + role: + description: Role is a SELinux role label + that applies to the container. + type: string + type: + description: Type is a SELinux type label + that applies to the container. + type: string + user: + description: User is a SELinux user label + that applies to the container. + type: string + type: object + seccompProfile: + description: |- + The seccomp options to use by this container. If seccomp options are + provided at both the pod & container level, the container options + override the pod options. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile defined in a file on the node should be used. + The profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be set for any other type. + type: string + type: + description: |- + type indicates which kind of seccomp profile will be applied. + Valid options are: + + + Localhost - a profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile should be used. + Unconfined - no profile should be applied. + type: string + required: + - type + type: object + windowsOptions: + description: |- + The Windows specific settings applied to all containers. + If unspecified, the options from the PodSecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: |- + GMSACredentialSpec is where the GMSA admission webhook + (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the + GMSA credential spec named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the + name of the GMSA credential spec to use. + type: string + hostProcess: + description: |- + HostProcess determines if a container should be run as a 'Host Process' container. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: |- + The UserName in Windows to run the entrypoint of the container process. + Defaults to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: string + type: object + type: object + startupProbe: + description: |- + StartupProbe indicates that the Pod has successfully initialized. + If specified, no other probes are executed until this completes successfully. + If this probe fails, the Pod will be restarted, just as if the livenessProbe failed. + This can be used to provide different probe parameters at the beginning of a Pod's lifecycle, + when it might take a long time to load data or warm a cache, than during steady-state operation. + This cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving + a GRPC port. + properties: + port: + description: Port number of the gRPC service. + Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the + request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + stdin: + description: |- + Whether this container should allocate a buffer for stdin in the container runtime. If this + is not set, reads from stdin in the container will always result in EOF. + Default is false. + type: boolean + stdinOnce: + description: |- + Whether the container runtime should close the stdin channel after it has been opened by + a single attach. When stdin is true the stdin stream will remain open across multiple attach + sessions. If stdinOnce is set to true, stdin is opened on container start, is empty until the + first client attaches to stdin, and then remains open and accepts data until the client disconnects, + at which time stdin is closed and remains closed until the container is restarted. If this + flag is false, a container processes that reads from stdin will never receive an EOF. + Default is false + type: boolean + terminationMessagePath: + description: |- + Optional: Path at which the file to which the container's termination message + will be written is mounted into the container's filesystem. + Message written is intended to be brief final status, such as an assertion failure message. + Will be truncated by the node if greater than 4096 bytes. The total message length across + all containers will be limited to 12kb. + Defaults to /dev/termination-log. + Cannot be updated. + type: string + terminationMessagePolicy: + description: |- + Indicate how the termination message should be populated. File will use the contents of + terminationMessagePath to populate the container status message on both success and failure. + FallbackToLogsOnError will use the last chunk of container log output if the termination + message file is empty and the container exited with an error. + The log output is limited to 2048 bytes or 80 lines, whichever is smaller. + Defaults to File. + Cannot be updated. + type: string + tty: + description: |- + Whether this container should allocate a TTY for itself, also requires 'stdin' to be true. + Default is false. + type: boolean + volumeDevices: + description: volumeDevices is the list of block devices + to be used by the container. + items: + description: volumeDevice describes a mapping of + a raw block device within a container. + properties: + devicePath: + description: devicePath is the path inside of + the container that the device will be mapped + to. + type: string + name: + description: name must match the name of a persistentVolumeClaim + in the pod + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + description: |- + Pod volumes to mount into the container's filesystem. + Cannot be updated. + items: + description: VolumeMount describes a mounting of + a Volume within a container. + properties: + mountPath: + description: |- + Path within the container at which the volume should be mounted. Must + not contain ':'. + type: string + mountPropagation: + description: |- + mountPropagation determines how mounts are propagated from the host + to container and the other way around. + When not set, MountPropagationNone is used. + This field is beta in 1.10. + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: |- + Mounted read-only if true, read-write otherwise (false or unspecified). + Defaults to false. + type: boolean + subPath: + description: |- + Path within the volume from which the container's volume should be mounted. + Defaults to "" (volume's root). + type: string + subPathExpr: + description: |- + Expanded path within the volume from which the container's volume should be mounted. + Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment. + Defaults to "" (volume's root). + SubPathExpr and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + description: |- + Container's working directory. + If not specified, the container runtime's default will be used, which + might be configured in the container image. + Cannot be updated. + type: string + required: + - name + type: object + type: array + nodeName: + description: |- + NodeName is a request to schedule this pod onto a specific node. If it is non-empty, + the scheduler simply schedules this pod onto that node, assuming that it fits resource + requirements. + type: string + nodeSelector: + additionalProperties: + type: string + description: |- + NodeSelector is a selector which must be true for the pod to fit on a node. + Selector which must match a node's labels for the pod to be scheduled on that node. + More info: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ + type: object + x-kubernetes-map-type: atomic + os: + description: |- + Specifies the OS of the containers in the pod. + Some pod and container fields are restricted if this is set. + + + If the OS field is set to linux, the following fields must be unset: + -securityContext.windowsOptions + + + If the OS field is set to windows, following fields must be unset: + - spec.hostPID + - spec.hostIPC + - spec.hostUsers + - spec.securityContext.seLinuxOptions + - spec.securityContext.seccompProfile + - spec.securityContext.fsGroup + - spec.securityContext.fsGroupChangePolicy + - spec.securityContext.sysctls + - spec.shareProcessNamespace + - spec.securityContext.runAsUser + - spec.securityContext.runAsGroup + - spec.securityContext.supplementalGroups + - spec.containers[*].securityContext.seLinuxOptions + - spec.containers[*].securityContext.seccompProfile + - spec.containers[*].securityContext.capabilities + - spec.containers[*].securityContext.readOnlyRootFilesystem + - spec.containers[*].securityContext.privileged + - spec.containers[*].securityContext.allowPrivilegeEscalation + - spec.containers[*].securityContext.procMount + - spec.containers[*].securityContext.runAsUser + - spec.containers[*].securityContext.runAsGroup + properties: + name: + description: |- + Name is the name of the operating system. The currently supported values are linux and windows. + Additional value may be defined in future and can be one of: + https://github.com/opencontainers/runtime-spec/blob/master/config.md#platform-specific-configuration + Clients should expect to handle additional values and treat unrecognized values in this field as os: null + type: string + required: + - name + type: object + overhead: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Overhead represents the resource overhead associated with running a pod for a given RuntimeClass. + This field will be autopopulated at admission time by the RuntimeClass admission controller. If + the RuntimeClass admission controller is enabled, overhead must not be set in Pod create requests. + The RuntimeClass admission controller will reject Pod create requests which have the overhead already + set. If RuntimeClass is configured and selected in the PodSpec, Overhead will be set to the value + defined in the corresponding RuntimeClass, otherwise it will remain unset and treated as zero. + More info: https://git.k8s.io/enhancements/keps/sig-node/688-pod-overhead/README.md + type: object + preemptionPolicy: + description: |- + PreemptionPolicy is the Policy for preempting pods with lower priority. + One of Never, PreemptLowerPriority. + Defaults to PreemptLowerPriority if unset. + type: string + priority: + description: |- + The priority value. Various system components use this field to find the + priority of the pod. When Priority Admission Controller is enabled, it + prevents users from setting this field. The admission controller populates + this field from PriorityClassName. + The higher the value, the higher the priority. + format: int32 + type: integer + priorityClassName: + description: |- + If specified, indicates the pod's priority. "system-node-critical" and + "system-cluster-critical" are two special keywords which indicate the + highest priorities with the former being the highest priority. Any other + name must be defined by creating a PriorityClass object with that name. + If not specified, the pod priority will be default or zero if there is no + default. + type: string + readinessGates: + description: |- + If specified, all readiness gates will be evaluated for pod readiness. + A pod is ready when all its containers are ready AND + all conditions specified in the readiness gates have status equal to "True" + More info: https://git.k8s.io/enhancements/keps/sig-network/580-pod-readiness-gates + items: + description: PodReadinessGate contains the reference to + a pod condition + properties: + conditionType: + description: ConditionType refers to a condition in + the pod's condition list with matching type. + type: string + required: + - conditionType + type: object + type: array + resourceClaims: + description: |- + ResourceClaims defines which ResourceClaims must be allocated + and reserved before the Pod is allowed to start. The resources + will be made available to those containers which consume them + by name. + + + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + + + This field is immutable. + items: + description: |- + PodResourceClaim references exactly one ResourceClaim through a ClaimSource. + It adds a name to it that uniquely identifies the ResourceClaim inside the Pod. + Containers that need access to the ResourceClaim reference it with this name. + properties: + name: + description: |- + Name uniquely identifies this resource claim inside the pod. + This must be a DNS_LABEL. + type: string + source: + description: Source describes where to find the ResourceClaim. + properties: + resourceClaimName: + description: |- + ResourceClaimName is the name of a ResourceClaim object in the same + namespace as this pod. + type: string + resourceClaimTemplateName: + description: |- + ResourceClaimTemplateName is the name of a ResourceClaimTemplate + object in the same namespace as this pod. + + + The template will be used to create a new ResourceClaim, which will + be bound to this pod. When this pod is deleted, the ResourceClaim + will also be deleted. The pod name and resource name, along with a + generated component, will be used to form a unique name for the + ResourceClaim, which will be recorded in pod.status.resourceClaimStatuses. + + + This field is immutable and no changes will be made to the + corresponding ResourceClaim by the control plane after creating the + ResourceClaim. + type: string + type: object + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + restartPolicy: + description: |- + Restart policy for all containers within the pod. + One of Always, OnFailure, Never. In some contexts, only a subset of those values may be permitted. + Default to Always. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#restart-policy + type: string + runtimeClassName: + description: |- + RuntimeClassName refers to a RuntimeClass object in the node.k8s.io group, which should be used + to run this pod. If no RuntimeClass resource matches the named class, the pod will not be run. + If unset or empty, the "legacy" RuntimeClass will be used, which is an implicit class with an + empty definition that uses the default runtime handler. + More info: https://git.k8s.io/enhancements/keps/sig-node/585-runtime-class + type: string + schedulerName: + description: |- + If specified, the pod will be dispatched by specified scheduler. + If not specified, the pod will be dispatched by default scheduler. + type: string + schedulingGates: + description: |- + SchedulingGates is an opaque list of values that if specified will block scheduling the pod. + If schedulingGates is not empty, the pod will stay in the SchedulingGated state and the + scheduler will not attempt to schedule the pod. + + + SchedulingGates can only be set at pod creation time, and be removed only afterwards. + + + This is a beta feature enabled by the PodSchedulingReadiness feature gate. + items: + description: PodSchedulingGate is associated to a Pod + to guard its scheduling. + properties: + name: + description: |- + Name of the scheduling gate. + Each scheduling gate must have a unique name field. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + securityContext: + description: |- + SecurityContext holds pod-level security attributes and common container settings. + Optional: Defaults to empty. See type description for default values of each field. + properties: + fsGroup: + description: |- + A special supplemental group that applies to all containers in a pod. + Some volume types allow the Kubelet to change the ownership of that volume + to be owned by the pod: + + + 1. The owning GID will be the FSGroup + 2. The setgid bit is set (new files created in the volume will be owned by FSGroup) + 3. The permission bits are OR'd with rw-rw---- + + + If unset, the Kubelet will not modify the ownership and permissions of any volume. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + fsGroupChangePolicy: + description: |- + fsGroupChangePolicy defines behavior of changing ownership and permission of the volume + before being exposed inside Pod. This field will only apply to + volume types which support fsGroup based ownership(and permissions). + It will have no effect on ephemeral volume types such as: secret, configmaps + and emptydir. + Valid values are "OnRootMismatch" and "Always". If not specified, "Always" is used. + Note that this field cannot be set when spec.os.name is windows. + type: string + runAsGroup: + description: |- + The GID to run the entrypoint of the container process. + Uses runtime default if unset. + May also be set in SecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence + for that container. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: |- + Indicates that the container must run as a non-root user. + If true, the Kubelet will validate the image at runtime to ensure that it + does not run as UID 0 (root) and fail to start the container if it does. + If unset or false, no such validation will be performed. + May also be set in SecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: |- + The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in SecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence + for that container. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: |- + The SELinux context to be applied to all containers. + If unspecified, the container runtime will allocate a random SELinux context for each + container. May also be set in SecurityContext. If set in + both SecurityContext and PodSecurityContext, the value specified in SecurityContext + takes precedence for that container. + Note that this field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies + to the container. + type: string + role: + description: Role is a SELinux role label that applies + to the container. + type: string + type: + description: Type is a SELinux type label that applies + to the container. + type: string + user: + description: User is a SELinux user label that applies + to the container. + type: string + type: object + seccompProfile: + description: |- + The seccomp options to use by the containers in this pod. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile defined in a file on the node should be used. + The profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be set for any other type. + type: string + type: + description: |- + type indicates which kind of seccomp profile will be applied. + Valid options are: + + + Localhost - a profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile should be used. + Unconfined - no profile should be applied. + type: string + required: + - type + type: object + supplementalGroups: + description: |- + A list of groups applied to the first process run in each container, in addition + to the container's primary GID, the fsGroup (if specified), and group memberships + defined in the container image for the uid of the container process. If unspecified, + no additional groups are added to any container. Note that group memberships + defined in the container image for the uid of the container process are still effective, + even if they are not included in this list. + Note that this field cannot be set when spec.os.name is windows. + items: + format: int64 + type: integer + type: array + sysctls: + description: |- + Sysctls hold a list of namespaced sysctls used for the pod. Pods with unsupported + sysctls (by the container runtime) might fail to launch. + Note that this field cannot be set when spec.os.name is windows. + items: + description: Sysctl defines a kernel parameter to + be set + properties: + name: + description: Name of a property to set + type: string + value: + description: Value of a property to set + type: string + required: + - name + - value + type: object + type: array + windowsOptions: + description: |- + The Windows specific settings applied to all containers. + If unspecified, the options within a container's SecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: |- + GMSACredentialSpec is where the GMSA admission webhook + (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the + GMSA credential spec named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name + of the GMSA credential spec to use. + type: string + hostProcess: + description: |- + HostProcess determines if a container should be run as a 'Host Process' container. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: |- + The UserName in Windows to run the entrypoint of the container process. + Defaults to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: string + type: object + type: object + serviceAccount: + description: |- + DeprecatedServiceAccount is a depreciated alias for ServiceAccountName. + Deprecated: Use serviceAccountName instead. + type: string + serviceAccountName: + description: |- + ServiceAccountName is the name of the ServiceAccount to use to run this pod. + More info: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/ + type: string + setHostnameAsFQDN: + description: |- + If true the pod's hostname will be configured as the pod's FQDN, rather than the leaf name (the default). + In Linux containers, this means setting the FQDN in the hostname field of the kernel (the nodename field of struct utsname). + In Windows containers, this means setting the registry value of hostname for the registry key HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters to FQDN. + If a pod does not have FQDN, this has no effect. + Default to false. + type: boolean + shareProcessNamespace: + description: |- + Share a single process namespace between all of the containers in a pod. + When this is set containers will be able to view and signal processes from other containers + in the same pod, and the first process in each container will not be assigned PID 1. + HostPID and ShareProcessNamespace cannot both be set. + Optional: Default to false. + type: boolean + subdomain: + description: |- + If specified, the fully qualified Pod hostname will be "...svc.". + If not specified, the pod will not have a domainname at all. + type: string + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully. May be decreased in delete request. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + If this value is nil, the default grace period will be used instead. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + Defaults to 30 seconds. + format: int64 + type: integer + tolerations: + description: If specified, the pod's tolerations. + items: + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . + properties: + effect: + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. + type: string + operator: + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. + type: string + tolerationSeconds: + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. + format: int64 + type: integer + value: + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. + type: string + type: object + type: array + topologySpreadConstraints: + description: |- + TopologySpreadConstraints describes how a group of pods ought to spread across topology + domains. Scheduler will schedule pods in a way which abides by the constraints. + All topologySpreadConstraints are ANDed. + items: + description: TopologySpreadConstraint specifies how to + spread matching pods among the given topology. + properties: + labelSelector: + description: |- + LabelSelector is used to find matching pods. + Pods that match this label selector are counted to determine the number of pods + in their corresponding topology domain. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select the pods over which + spreading will be calculated. The keys are used to lookup values from the + incoming pod labels, those key-value labels are ANDed with labelSelector + to select the group of existing pods over which spreading will be calculated + for the incoming pod. The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + MatchLabelKeys cannot be set when LabelSelector isn't set. + Keys that don't exist in the incoming pod labels will + be ignored. A null or empty list means only match against labelSelector. + + + This is a beta field and requires the MatchLabelKeysInPodTopologySpread feature gate to be enabled (enabled by default). + items: + type: string + type: array + x-kubernetes-list-type: atomic + maxSkew: + description: |- + MaxSkew describes the degree to which pods may be unevenly distributed. + When `whenUnsatisfiable=DoNotSchedule`, it is the maximum permitted difference + between the number of matching pods in the target topology and the global minimum. + The global minimum is the minimum number of matching pods in an eligible domain + or zero if the number of eligible domains is less than MinDomains. + For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same + labelSelector spread as 2/2/1: + In this case, the global minimum is 1. + | zone1 | zone2 | zone3 | + | P P | P P | P | + - if MaxSkew is 1, incoming pod can only be scheduled to zone3 to become 2/2/2; + scheduling it onto zone1(zone2) would make the ActualSkew(3-1) on zone1(zone2) + violate MaxSkew(1). + - if MaxSkew is 2, incoming pod can be scheduled onto any zone. + When `whenUnsatisfiable=ScheduleAnyway`, it is used to give higher precedence + to topologies that satisfy it. + It's a required field. Default value is 1 and 0 is not allowed. + format: int32 + type: integer + minDomains: + description: |- + MinDomains indicates a minimum number of eligible domains. + When the number of eligible domains with matching topology keys is less than minDomains, + Pod Topology Spread treats "global minimum" as 0, and then the calculation of Skew is performed. + And when the number of eligible domains with matching topology keys equals or greater than minDomains, + this value has no effect on scheduling. + As a result, when the number of eligible domains is less than minDomains, + scheduler won't schedule more than maxSkew Pods to those domains. + If value is nil, the constraint behaves as if MinDomains is equal to 1. + Valid values are integers greater than 0. + When value is not nil, WhenUnsatisfiable must be DoNotSchedule. + + + For example, in a 3-zone cluster, MaxSkew is set to 2, MinDomains is set to 5 and pods with the same + labelSelector spread as 2/2/2: + | zone1 | zone2 | zone3 | + | P P | P P | P P | + The number of domains is less than 5(MinDomains), so "global minimum" is treated as 0. + In this situation, new pod with the same labelSelector cannot be scheduled, + because computed skew will be 3(3 - 0) if new Pod is scheduled to any of the three zones, + it will violate MaxSkew. + + + This is a beta field and requires the MinDomainsInPodTopologySpread feature gate to be enabled (enabled by default). + format: int32 + type: integer + nodeAffinityPolicy: + description: |- + NodeAffinityPolicy indicates how we will treat Pod's nodeAffinity/nodeSelector + when calculating pod topology spread skew. Options are: + - Honor: only nodes matching nodeAffinity/nodeSelector are included in the calculations. + - Ignore: nodeAffinity/nodeSelector are ignored. All nodes are included in the calculations. + + + If this value is nil, the behavior is equivalent to the Honor policy. + This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag. + type: string + nodeTaintsPolicy: + description: |- + NodeTaintsPolicy indicates how we will treat node taints when calculating + pod topology spread skew. Options are: + - Honor: nodes without taints, along with tainted nodes for which the incoming pod + has a toleration, are included. + - Ignore: node taints are ignored. All nodes are included. + + + If this value is nil, the behavior is equivalent to the Ignore policy. + This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag. + type: string + topologyKey: + description: |- + TopologyKey is the key of node labels. Nodes that have a label with this key + and identical values are considered to be in the same topology. + We consider each as a "bucket", and try to put balanced number + of pods into each bucket. + We define a domain as a particular instance of a topology. + Also, we define an eligible domain as a domain whose nodes meet the requirements of + nodeAffinityPolicy and nodeTaintsPolicy. + e.g. If TopologyKey is "kubernetes.io/hostname", each Node is a domain of that topology. + And, if TopologyKey is "topology.kubernetes.io/zone", each zone is a domain of that topology. + It's a required field. + type: string + whenUnsatisfiable: + description: |- + WhenUnsatisfiable indicates how to deal with a pod if it doesn't satisfy + the spread constraint. + - DoNotSchedule (default) tells the scheduler not to schedule it. + - ScheduleAnyway tells the scheduler to schedule the pod in any location, + but giving higher precedence to topologies that would help reduce the + skew. + A constraint is considered "Unsatisfiable" for an incoming pod + if and only if every possible node assignment for that pod would violate + "MaxSkew" on some topology. + For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same + labelSelector spread as 3/1/1: + | zone1 | zone2 | zone3 | + | P P P | P | P | + If WhenUnsatisfiable is set to DoNotSchedule, incoming pod can only be scheduled + to zone2(zone3) to become 3/2/1(3/1/2) as ActualSkew(2-1) on zone2(zone3) satisfies + MaxSkew(1). In other words, the cluster can still be imbalanced, but scheduler + won't make it *more* imbalanced. + It's a required field. + type: string + required: + - maxSkew + - topologyKey + - whenUnsatisfiable + type: object + type: array + x-kubernetes-list-map-keys: + - topologyKey + - whenUnsatisfiable + x-kubernetes-list-type: map + volumes: + description: |- + List of volumes that can be mounted by containers belonging to the pod. + More info: https://kubernetes.io/docs/concepts/storage/volumes + items: + description: Volume represents a named volume in a pod + that may be accessed by any container in the pod. + properties: + awsElasticBlockStore: + description: |- + awsElasticBlockStore represents an AWS Disk resource that is attached to a + kubelet's host machine and then exposed to the pod. + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + properties: + fsType: + description: |- + fsType is the filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + partition: + description: |- + partition is the partition in the volume that you want to mount. + If omitted, the default is to mount by volume name. + Examples: For volume /dev/sda1, you specify the partition as "1". + Similarly, the volume partition for /dev/sda is "0" (or you can leave the property empty). + format: int32 + type: integer + readOnly: + description: |- + readOnly value true will force the readOnly setting in VolumeMounts. + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + type: boolean + volumeID: + description: |- + volumeID is unique ID of the persistent disk resource in AWS (Amazon EBS volume). + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + type: string + required: + - volumeID + type: object + azureDisk: + description: azureDisk represents an Azure Data Disk + mount on the host and bind mount to the pod. + properties: + cachingMode: + description: 'cachingMode is the Host Caching + mode: None, Read Only, Read Write.' + type: string + diskName: + description: diskName is the Name of the data + disk in the blob storage + type: string + diskURI: + description: diskURI is the URI of data disk in + the blob storage + type: string + fsType: + description: |- + fsType is Filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + kind: + description: 'kind expected values are Shared: + multiple blob disks per storage account Dedicated: + single blob disk per storage account Managed: + azure managed data disk (only in managed availability + set). defaults to shared' + type: string + readOnly: + description: |- + readOnly Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + description: azureFile represents an Azure File Service + mount on the host and bind mount to the pod. + properties: + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretName: + description: secretName is the name of secret + that contains Azure Storage Account Name and + Key + type: string + shareName: + description: shareName is the azure share Name + type: string + required: + - secretName + - shareName + type: object + cephfs: + description: cephFS represents a Ceph FS mount on + the host that shares a pod's lifetime + properties: + monitors: + description: |- + monitors is Required: Monitors is a collection of Ceph monitors + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + items: + type: string + type: array + path: + description: 'path is Optional: Used as the mounted + root, rather than the full Ceph tree, default + is /' + type: string + readOnly: + description: |- + readOnly is Optional: Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + type: boolean + secretFile: + description: |- + secretFile is Optional: SecretFile is the path to key ring for User, default is /etc/ceph/user.secret + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + type: string + secretRef: + description: |- + secretRef is Optional: SecretRef is reference to the authentication secret for User, default is empty. + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + 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 + user: + description: |- + user is optional: User is the rados user name, default is admin + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + type: string + required: + - monitors + type: object + cinder: + description: |- + cinder represents a cinder volume attached and mounted on kubelets host machine. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + type: string + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + type: boolean + secretRef: + description: |- + secretRef is optional: points to a secret object containing parameters used to connect + to OpenStack. + 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 + volumeID: + description: |- + volumeID used to identify the volume in cinder. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + type: string + required: + - volumeID + type: object + configMap: + description: configMap represents a configMap that + should populate this volume + properties: + defaultMode: + description: |- + defaultMode is optional: mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + items: + description: |- + items if unspecified, each key-value pair in the Data field of the referenced + ConfigMap will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the ConfigMap, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within + a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + 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 + optional: + description: optional specify whether the ConfigMap + or its keys must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + csi: + description: csi (Container Storage Interface) represents + ephemeral storage that is handled by certain external + CSI drivers (Beta feature). + properties: + driver: + description: |- + driver is the name of the CSI driver that handles this volume. + Consult with your admin for the correct name as registered in the cluster. + type: string + fsType: + description: |- + fsType to mount. Ex. "ext4", "xfs", "ntfs". + If not provided, the empty value is passed to the associated CSI driver + which will determine the default filesystem to apply. + type: string + nodePublishSecretRef: + description: |- + nodePublishSecretRef is a reference to the secret object containing + sensitive information to pass to the CSI driver to complete the CSI + NodePublishVolume and NodeUnpublishVolume calls. + This field is optional, and may be empty if no secret is required. If the + secret object contains more than one secret, all secret references are passed. + 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 + readOnly: + description: |- + readOnly specifies a read-only configuration for the volume. + Defaults to false (read/write). + type: boolean + volumeAttributes: + additionalProperties: + type: string + description: |- + volumeAttributes stores driver-specific properties that are passed to the CSI + driver. Consult your driver's documentation for supported values. + type: object + required: + - driver + type: object + downwardAPI: + description: downwardAPI represents downward API about + the pod that should populate this volume + properties: + defaultMode: + description: |- + Optional: mode bits to use on created files by default. Must be a + Optional: mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + items: + description: Items is a list of downward API volume + file + items: + description: DownwardAPIVolumeFile represents + information to create the file containing + the pod field + properties: + fieldRef: + description: 'Required: Selects a field + of the pod: only annotations, labels, + name and namespace are supported.' + properties: + apiVersion: + description: Version of the schema the + FieldPath is written in terms of, + defaults to "v1". + type: string + fieldPath: + description: Path of the field to select + in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + description: |- + Optional: mode bits used to set permissions on this file, must be an octal value + between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: 'Required: Path is the relative + path name of the file to be created. Must + not be absolute or contain the ''..'' + path. Must be utf-8 encoded. The first + item of the relative path must not start + with ''..''' + type: string + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported. + properties: + containerName: + description: 'Container name: required + for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format + of the exposed resources, defaults + to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to + select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + type: object + emptyDir: + description: |- + emptyDir represents a temporary directory that shares a pod's lifetime. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir + properties: + medium: + description: |- + medium represents what type of storage medium should back this directory. + The default is "" which means to use the node's default medium. + Must be an empty string (default) or Memory. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + description: |- + sizeLimit is the total amount of local storage required for this EmptyDir volume. + The size limit is also applicable for memory medium. + The maximum usage on memory medium EmptyDir would be the minimum value between + the SizeLimit specified here and the sum of memory limits of all containers in a pod. + The default is nil which means that the limit is undefined. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + description: |- + ephemeral represents a volume that is handled by a cluster storage driver. + The volume's lifecycle is tied to the pod that defines it - it will be created before the pod starts, + and deleted when the pod is removed. + + + Use this if: + a) the volume is only needed while the pod runs, + b) features of normal volumes like restoring from snapshot or capacity + tracking are needed, + c) the storage driver is specified through a storage class, and + d) the storage driver supports dynamic volume provisioning through + a PersistentVolumeClaim (see EphemeralVolumeSource for more + information on the connection between this volume type + and PersistentVolumeClaim). + + + Use PersistentVolumeClaim or one of the vendor-specific + APIs for volumes that persist for longer than the lifecycle + of an individual pod. + + + Use CSI for light-weight local ephemeral volumes if the CSI driver is meant to + be used that way - see the documentation of the driver for + more information. + + + A pod can use both types of ephemeral volumes and + persistent volumes at the same time. + properties: + volumeClaimTemplate: + description: |- + Will be used to create a stand-alone PVC to provision the volume. + The pod in which this EphemeralVolumeSource is embedded will be the + owner of the PVC, i.e. the PVC will be deleted together with the + pod. The name of the PVC will be `-` where + `` is the name from the `PodSpec.Volumes` array + entry. Pod validation will reject the pod if the concatenated name + is not valid for a PVC (for example, too long). + + + An existing PVC with that name that is not owned by the pod + will *not* be used for the pod to avoid using an unrelated + volume by mistake. Starting the pod is then blocked until + the unrelated PVC is removed. If such a pre-created PVC is + meant to be used by the pod, the PVC has to updated with an + owner reference to the pod once the pod exists. Normally + this should not be necessary, but it may be useful when + manually reconstructing a broken cluster. + + + This field is read-only and no changes will be made by Kubernetes + to the PVC after it has been created. + + + Required, must not be nil. + properties: + metadata: + description: |- + May contain labels and annotations that will be copied into the PVC + when creating it. No other fields are allowed and will be rejected during + validation. + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + description: |- + The specification for the PersistentVolumeClaim. The entire content is + copied unchanged into the PVC that gets created from this + template. The same fields as in a PersistentVolumeClaim + are also valid here. + properties: + accessModes: + description: |- + accessModes contains the desired access modes the volume should have. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1 + items: + type: string + type: array + dataSource: + description: |- + dataSource field can be used to specify either: + * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) + * An existing PVC (PersistentVolumeClaim) + If the provisioner or an external controller can support the specified data source, + it will create a new volume based on the contents of the specified data source. + When the AnyVolumeDataSource feature gate is enabled, dataSource contents will be copied to dataSourceRef, + and dataSourceRef contents will be copied to dataSource when dataSourceRef.namespace is not specified. + If the namespace is specified, then dataSourceRef will not be copied to dataSource. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource + being referenced + type: string + name: + description: Name is the name of resource + being referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + description: |- + dataSourceRef specifies the object from which to populate the volume with data, if a non-empty + volume is desired. This may be any object from a non-empty API group (non + core object) or a PersistentVolumeClaim object. + When this field is specified, volume binding will only succeed if the type of + the specified object matches some installed volume populator or dynamic + provisioner. + This field will replace the functionality of the dataSource field and as such + if both fields are non-empty, they must have the same value. For backwards + compatibility, when namespace isn't specified in dataSourceRef, + both fields (dataSource and dataSourceRef) will be set to the same + value automatically if one of them is empty and the other is non-empty. + When namespace is specified in dataSourceRef, + dataSource isn't set to the same value and must be empty. + There are three important differences between dataSource and dataSourceRef: + * While dataSource only allows two specific types of objects, dataSourceRef + allows any non-core object, as well as PersistentVolumeClaim objects. + * While dataSource ignores disallowed values (dropping them), dataSourceRef + preserves all values, and generates an error if a disallowed value is + specified. + * While dataSource only allows local objects, dataSourceRef allows objects + in any namespaces. + (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled. + (Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource + being referenced + type: string + name: + description: Name is the name of resource + being referenced + type: string + namespace: + description: |- + Namespace is the namespace of resource being referenced + Note that when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details. + (Alpha) This field requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + type: string + required: + - kind + - name + type: object + resources: + description: |- + resources represents the minimum resources the volume should have. + If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements + that are lower than previous value but must still be higher than capacity recorded in the + status field of the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + selector: + description: selector is a label query + over volumes to consider for binding. + properties: + matchExpressions: + description: matchExpressions is a + list of label selector requirements. + The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + description: |- + storageClassName is the name of the StorageClass required by the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1 + type: string + volumeAttributesClassName: + description: |- + volumeAttributesClassName may be used to set the VolumeAttributesClass used by this claim. + If specified, the CSI driver will create or update the volume with the attributes defined + in the corresponding VolumeAttributesClass. This has a different purpose than storageClassName, + it can be changed after the claim is created. An empty string value means that no VolumeAttributesClass + will be applied to the claim but it's not allowed to reset this field to empty string once it is set. + If unspecified and the PersistentVolumeClaim is unbound, the default VolumeAttributesClass + will be set by the persistentvolume controller if it exists. + If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be + set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource + exists. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#volumeattributesclass + (Alpha) Using this field requires the VolumeAttributesClass feature gate to be enabled. + type: string + volumeMode: + description: |- + volumeMode defines what type of volume is required by the claim. + Value of Filesystem is implied when not included in claim spec. + type: string + volumeName: + description: volumeName is the binding + reference to the PersistentVolume backing + this claim. + type: string + type: object + required: + - spec + type: object + type: object + fc: + description: fc represents a Fibre Channel resource + that is attached to a kubelet's host machine and + then exposed to the pod. + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + lun: + description: 'lun is Optional: FC target lun number' + format: int32 + type: integer + readOnly: + description: |- + readOnly is Optional: Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + targetWWNs: + description: 'targetWWNs is Optional: FC target + worldwide names (WWNs)' + items: + type: string + type: array + wwids: + description: |- + wwids Optional: FC volume world wide identifiers (wwids) + Either wwids or combination of targetWWNs and lun must be set, but not both simultaneously. + items: + type: string + type: array + type: object + flexVolume: + description: |- + flexVolume represents a generic volume resource that is + provisioned/attached using an exec based plugin. + properties: + driver: + description: driver is the name of the driver + to use for this volume. + type: string + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". The default filesystem depends on FlexVolume script. + type: string + options: + additionalProperties: + type: string + description: 'options is Optional: this field + holds extra command options if any.' + type: object + readOnly: + description: |- + readOnly is Optional: defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: |- + secretRef is Optional: secretRef is reference to the secret object containing + sensitive information to pass to the plugin scripts. This may be + empty if no secret object is specified. If the secret object + contains more than one secret, all secrets are passed to the plugin + scripts. + 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 + required: + - driver + type: object + flocker: + description: flocker represents a Flocker volume attached + to a kubelet's host machine. This depends on the + Flocker control service being running + properties: + datasetName: + description: |- + datasetName is Name of the dataset stored as metadata -> name on the dataset for Flocker + should be considered as deprecated + type: string + datasetUUID: + description: datasetUUID is the UUID of the dataset. + This is unique identifier of a Flocker dataset + type: string + type: object + gcePersistentDisk: + description: |- + gcePersistentDisk represents a GCE Disk resource that is attached to a + kubelet's host machine and then exposed to the pod. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + properties: + fsType: + description: |- + fsType is filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + partition: + description: |- + partition is the partition in the volume that you want to mount. + If omitted, the default is to mount by volume name. + Examples: For volume /dev/sda1, you specify the partition as "1". + Similarly, the volume partition for /dev/sda is "0" (or you can leave the property empty). + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + format: int32 + type: integer + pdName: + description: |- + pdName is unique name of the PD resource in GCE. Used to identify the disk in GCE. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + type: string + readOnly: + description: |- + readOnly here will force the ReadOnly setting in VolumeMounts. + Defaults to false. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + type: boolean + required: + - pdName + type: object + gitRepo: + description: |- + gitRepo represents a git repository at a particular revision. + DEPRECATED: GitRepo is deprecated. To provision a container with a git repo, mount an + EmptyDir into an InitContainer that clones the repo using git, then mount the EmptyDir + into the Pod's container. + properties: + directory: + description: |- + directory is the target directory name. + Must not contain or start with '..'. If '.' is supplied, the volume directory will be the + git repository. Otherwise, if specified, the volume will contain the git repository in + the subdirectory with the given name. + type: string + repository: + description: repository is the URL + type: string + revision: + description: revision is the commit hash for the + specified revision. + type: string + required: + - repository + type: object + glusterfs: + description: |- + glusterfs represents a Glusterfs mount on the host that shares a pod's lifetime. + More info: https://examples.k8s.io/volumes/glusterfs/README.md + properties: + endpoints: + description: |- + endpoints is the endpoint name that details Glusterfs topology. + More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod + type: string + path: + description: |- + path is the Glusterfs volume path. + More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod + type: string + readOnly: + description: |- + readOnly here will force the Glusterfs volume to be mounted with read-only permissions. + Defaults to false. + More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod + type: boolean + required: + - endpoints + - path + type: object + hostPath: + description: |- + hostPath represents a pre-existing file or directory on the host + machine that is directly exposed to the container. This is generally + used for system agents or other privileged things that are allowed + to see the host machine. Most containers will NOT need this. + More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + --- + TODO(jonesdl) We need to restrict who can use host directory mounts and who can/can not + mount host directories as read/write. + properties: + path: + description: |- + path of the directory on the host. + If the path is a symlink, it will follow the link to the real path. + More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + type: string + type: + description: |- + type for HostPath Volume + Defaults to "" + More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + type: string + required: + - path + type: object + iscsi: + description: |- + iscsi represents an ISCSI Disk resource that is attached to a + kubelet's host machine and then exposed to the pod. + More info: https://examples.k8s.io/volumes/iscsi/README.md + properties: + chapAuthDiscovery: + description: chapAuthDiscovery defines whether + support iSCSI Discovery CHAP authentication + type: boolean + chapAuthSession: + description: chapAuthSession defines whether support + iSCSI Session CHAP authentication + type: boolean + fsType: + description: |- + fsType is the filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#iscsi + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + initiatorName: + description: |- + initiatorName is the custom iSCSI Initiator Name. + If initiatorName is specified with iscsiInterface simultaneously, new iSCSI interface + : will be created for the connection. + type: string + iqn: + description: iqn is the target iSCSI Qualified + Name. + type: string + iscsiInterface: + description: |- + iscsiInterface is the interface Name that uses an iSCSI transport. + Defaults to 'default' (tcp). + type: string + lun: + description: lun represents iSCSI Target Lun number. + format: int32 + type: integer + portals: + description: |- + portals is the iSCSI Target Portal List. The portal is either an IP or ip_addr:port if the port + is other than default (typically TCP ports 860 and 3260). + items: + type: string + type: array + readOnly: + description: |- + readOnly here will force the ReadOnly setting in VolumeMounts. + Defaults to false. + type: boolean + secretRef: + description: secretRef is the CHAP Secret for + iSCSI target and initiator authentication + 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 + targetPortal: + description: |- + targetPortal is iSCSI Target Portal. The Portal is either an IP or ip_addr:port if the port + is other than default (typically TCP ports 860 and 3260). + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + description: |- + name of the volume. + Must be a DNS_LABEL and unique within the pod. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + nfs: + description: |- + nfs represents an NFS mount on the host that shares a pod's lifetime + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + properties: + path: + description: |- + path that is exported by the NFS server. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + type: string + readOnly: + description: |- + readOnly here will force the NFS export to be mounted with read-only permissions. + Defaults to false. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + type: boolean + server: + description: |- + server is the hostname or IP address of the NFS server. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + description: |- + persistentVolumeClaimVolumeSource represents a reference to a + PersistentVolumeClaim in the same namespace. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims + properties: + claimName: + description: |- + claimName is the name of a PersistentVolumeClaim in the same namespace as the pod using this volume. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims + type: string + readOnly: + description: |- + readOnly Will force the ReadOnly setting in VolumeMounts. + Default false. + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + description: photonPersistentDisk represents a PhotonController + persistent disk attached and mounted on kubelets + host machine + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + pdID: + description: pdID is the ID that identifies Photon + Controller persistent disk + type: string + required: + - pdID + type: object + portworxVolume: + description: portworxVolume represents a portworx + volume attached and mounted on kubelets host machine + properties: + fsType: + description: |- + fSType represents the filesystem type to mount + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs". Implicitly inferred to be "ext4" if unspecified. + type: string + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + volumeID: + description: volumeID uniquely identifies a Portworx + volume + type: string + required: + - volumeID + type: object + projected: + description: projected items for all in one resources + secrets, configmaps, and downward API + properties: + defaultMode: + description: |- + defaultMode are the mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + sources: + description: sources is the list of volume projections + items: + description: Projection that may be projected + along with other supported volume types + properties: + clusterTrustBundle: + description: |- + ClusterTrustBundle allows a pod to access the `.spec.trustBundle` field + of ClusterTrustBundle objects in an auto-updating file. + + + Alpha, gated by the ClusterTrustBundleProjection feature gate. + + + ClusterTrustBundle objects can either be selected by name, or by the + combination of signer name and a label selector. + + + Kubelet performs aggressive normalization of the PEM contents written + into the pod filesystem. Esoteric PEM features such as inter-block + comments and block headers are stripped. Certificates are deduplicated. + The ordering of certificates within the file is arbitrary, and Kubelet + may change the order over time. + properties: + labelSelector: + description: |- + Select all ClusterTrustBundles that match this label selector. Only has + effect if signerName is set. Mutually-exclusive with name. If unset, + interpreted as "match nothing". If set but empty, interpreted as "match + everything". + properties: + matchExpressions: + description: matchExpressions is + a list of label selector requirements. + The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + name: + description: |- + Select a single ClusterTrustBundle by object name. Mutually-exclusive + with signerName and labelSelector. + type: string + optional: + description: |- + If true, don't block pod startup if the referenced ClusterTrustBundle(s) + aren't available. If using name, then the named ClusterTrustBundle is + allowed not to exist. If using signerName, then the combination of + signerName and labelSelector is allowed to match zero + ClusterTrustBundles. + type: boolean + path: + description: Relative path from the + volume root to write the bundle. + type: string + signerName: + description: |- + Select all ClusterTrustBundles that match this signer name. + Mutually-exclusive with name. The contents of all selected + ClusterTrustBundles will be unified and deduplicated. + type: string + required: + - path + type: object + configMap: + description: configMap information about + the configMap data to project + properties: + items: + description: |- + items if unspecified, each key-value pair in the Data field of the referenced + ConfigMap will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the ConfigMap, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to + a path within a volume. + properties: + key: + description: key is the key to + project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + 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 + optional: + description: optional specify whether + the ConfigMap or its keys must be + defined + type: boolean + type: object + x-kubernetes-map-type: atomic + downwardAPI: + description: downwardAPI information about + the downwardAPI data to project + properties: + items: + description: Items is a list of DownwardAPIVolume + file + items: + description: DownwardAPIVolumeFile + represents information to create + the file containing the pod field + properties: + fieldRef: + description: 'Required: Selects + a field of the pod: only annotations, + labels, name and namespace are + supported.' + properties: + apiVersion: + description: Version of the + schema the FieldPath is + written in terms of, defaults + to "v1". + type: string + fieldPath: + description: Path of the field + to select in the specified + API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + description: |- + Optional: mode bits used to set permissions on this file, must be an octal value + between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: 'Required: Path is the + relative path name of the file + to be created. Must not be absolute + or contain the ''..'' path. + Must be utf-8 encoded. The first + item of the relative path must + not start with ''..''' + type: string + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported. + properties: + containerName: + description: 'Container name: + required for volumes, optional + for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the + output format of the exposed + resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource + to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + type: object + secret: + description: secret information about the + secret data to project + properties: + items: + description: |- + items if unspecified, each key-value pair in the Data field of the referenced + Secret will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the Secret, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to + a path within a volume. + properties: + key: + description: key is the key to + project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + 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 + optional: + description: optional field specify + whether the Secret or its key must + be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + serviceAccountToken: + description: serviceAccountToken is information + about the serviceAccountToken data to + project + properties: + audience: + description: |- + audience is the intended audience of the token. A recipient of a token + must identify itself with an identifier specified in the audience of the + token, and otherwise should reject the token. The audience defaults to the + identifier of the apiserver. + type: string + expirationSeconds: + description: |- + expirationSeconds is the requested duration of validity of the service + account token. As the token approaches expiration, the kubelet volume + plugin will proactively rotate the service account token. The kubelet will + start trying to rotate the token if the token is older than 80 percent of + its time to live or if the token is older than 24 hours.Defaults to 1 hour + and must be at least 10 minutes. + format: int64 + type: integer + path: + description: |- + path is the path relative to the mount point of the file to project the + token into. + type: string + required: + - path + type: object + type: object + type: array + type: object + quobyte: + description: quobyte represents a Quobyte mount on + the host that shares a pod's lifetime + properties: + group: + description: |- + group to map volume access to + Default is no group + type: string + readOnly: + description: |- + readOnly here will force the Quobyte volume to be mounted with read-only permissions. + Defaults to false. + type: boolean + registry: + description: |- + registry represents a single or multiple Quobyte Registry services + specified as a string as host:port pair (multiple entries are separated with commas) + which acts as the central registry for volumes + type: string + tenant: + description: |- + tenant owning the given Quobyte volume in the Backend + Used with dynamically provisioned Quobyte volumes, value is set by the plugin + type: string + user: + description: |- + user to map volume access to + Defaults to serivceaccount user + type: string + volume: + description: volume is a string that references + an already created Quobyte volume by name. + type: string + required: + - registry + - volume + type: object + rbd: + description: |- + rbd represents a Rados Block Device mount on the host that shares a pod's lifetime. + More info: https://examples.k8s.io/volumes/rbd/README.md + properties: + fsType: + description: |- + fsType is the filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#rbd + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + image: + description: |- + image is the rados image name. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + keyring: + description: |- + keyring is the path to key ring for RBDUser. + Default is /etc/ceph/keyring. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + monitors: + description: |- + monitors is a collection of Ceph monitors. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + items: + type: string + type: array + pool: + description: |- + pool is the rados pool name. + Default is rbd. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + readOnly: + description: |- + readOnly here will force the ReadOnly setting in VolumeMounts. + Defaults to false. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: boolean + secretRef: + description: |- + secretRef is name of the authentication secret for RBDUser. If provided + overrides keyring. + Default is nil. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + 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 + user: + description: |- + user is the rados user name. + Default is admin. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + required: + - image + - monitors + type: object + scaleIO: + description: scaleIO represents a ScaleIO persistent + volume attached and mounted on Kubernetes nodes. + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". + Default is "xfs". + type: string + gateway: + description: gateway is the host address of the + ScaleIO API Gateway. + type: string + protectionDomain: + description: protectionDomain is the name of the + ScaleIO Protection Domain for the configured + storage. + type: string + readOnly: + description: |- + readOnly Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: |- + secretRef references to the secret for ScaleIO user and other + sensitive information. If this is not provided, Login operation will fail. + 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 + sslEnabled: + description: sslEnabled Flag enable/disable SSL + communication with Gateway, default false + type: boolean + storageMode: + description: |- + storageMode indicates whether the storage for a volume should be ThickProvisioned or ThinProvisioned. + Default is ThinProvisioned. + type: string + storagePool: + description: storagePool is the ScaleIO Storage + Pool associated with the protection domain. + type: string + system: + description: system is the name of the storage + system as configured in ScaleIO. + type: string + volumeName: + description: |- + volumeName is the name of a volume already created in the ScaleIO system + that is associated with this volume source. + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + description: |- + secret represents a secret that should populate this volume. + More info: https://kubernetes.io/docs/concepts/storage/volumes#secret + properties: + defaultMode: + description: |- + defaultMode is Optional: mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values + for mode bits. Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + items: + description: |- + items If unspecified, each key-value pair in the Data field of the referenced + Secret will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the Secret, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within + a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + optional: + description: optional field specify whether the + Secret or its keys must be defined + type: boolean + secretName: + description: |- + secretName is the name of the secret in the pod's namespace to use. + More info: https://kubernetes.io/docs/concepts/storage/volumes#secret + type: string + type: object + storageos: + description: storageOS represents a StorageOS volume + attached and mounted on Kubernetes nodes. + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: |- + secretRef specifies the secret to use for obtaining the StorageOS API + credentials. If not specified, default values will be attempted. + 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 + volumeName: + description: |- + volumeName is the human-readable name of the StorageOS volume. Volume + names are only unique within a namespace. + type: string + volumeNamespace: + description: |- + volumeNamespace specifies the scope of the volume within StorageOS. If no + namespace is specified then the Pod's namespace will be used. This allows the + Kubernetes name scoping to be mirrored within StorageOS for tighter integration. + Set VolumeName to any name to override the default behaviour. + Set to "default" if you are not using namespaces within StorageOS. + Namespaces that do not pre-exist within StorageOS will be created. + type: string + type: object + vsphereVolume: + description: vsphereVolume represents a vSphere volume + attached and mounted on kubelets host machine + properties: + fsType: + description: |- + fsType is filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + storagePolicyID: + description: storagePolicyID is the storage Policy + Based Management (SPBM) profile ID associated + with the StoragePolicyName. + type: string + storagePolicyName: + description: storagePolicyName is the storage + Policy Based Management (SPBM) profile name. + type: string + volumePath: + description: volumePath is the path that identifies + vSphere volume vmdk + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + required: + - containers + type: object + x-kubernetes-preserve-unknown-fields: true + postStartSpec: + description: |- + Defines the command to be executed when the component is ready, and the command will only be executed once after + the component becomes ready. + properties: + cmdExecutorConfig: + description: Specifies the post-start command to be executed. + properties: + args: + description: Additional parameters used in the execution + of the command. + items: + type: string + type: array + command: + description: The command to be executed. + items: + type: string + minItems: 1 + type: array + env: + description: A list of environment variables that will + be injected into the command execution context. + items: + description: EnvVar represents an environment variable + present in a Container. + properties: + name: + description: Name of the environment variable. + Must be a C_IDENTIFIER. + type: string + value: + description: |- + Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in the container and + any service environment variables. If a variable cannot be resolved, + the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless of whether the variable + exists or not. + Defaults to "". + type: string + valueFrom: + description: Source for the environment variable's + value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the + FieldPath is written in terms of, defaults + to "v1". + type: string + fieldPath: + description: Path of the field to select + in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required + for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format + of the exposed resources, defaults to + "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in + the pod's namespace + properties: + key: + description: The key of the secret to + select from. Must be a valid secret + key. + type: string + 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 + optional: + description: Specify whether the Secret + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + x-kubernetes-preserve-unknown-fields: true + image: + description: Specifies the image used to execute the + command. + type: string + required: + - command + - image + type: object + scriptSpecSelectors: + description: |- + Used to select the script that need to be referenced. + When defined, the scripts defined in scriptSpecs can be referenced within the CmdExecutorConfig. + items: + properties: + name: + description: Represents the name of the ScriptSpec + referent. + maxLength: 63 + pattern: ^[a-z0-9]([a-z0-9\.\-]*[a-z0-9])?$ + type: string + required: + - name + type: object + type: array + required: + - cmdExecutorConfig + type: object + probes: + description: Settings for health checks. + properties: + roleProbe: + description: Specifies the probe used for checking the role + of the component. + properties: + commands: + description: Commands used to execute for probe. + properties: + queries: + description: Defines read checks that are executed + on the probe sidecar. + items: + type: string + type: array + writes: + description: Defines write checks that are executed + on the probe sidecar. + items: + type: string + type: array + type: object + failureThreshold: + default: 3 + description: Minimum consecutive failures for the probe + to be considered failed after having succeeded. + format: int32 + minimum: 2 + type: integer + periodSeconds: + default: 1 + description: How often (in seconds) to perform the probe. + format: int32 + minimum: 1 + type: integer + timeoutSeconds: + default: 1 + description: Number of seconds after which the probe + times out. Defaults to 1 second. + format: int32 + minimum: 1 + type: integer + type: object + roleProbeTimeoutAfterPodsReady: + description: |- + Defines the timeout (in seconds) for the role probe after all pods of the component are ready. + The system will check if the application is available in the pod. + If pods exceed the InitializationTimeoutSeconds time without a role label, this component will enter the + Failed/Abnormal phase. + + + Note that this configuration will only take effect if the component supports RoleProbe + and will not affect the life cycle of the pod. default values are 60 seconds. + format: int32 + minimum: 30 + type: integer + runningProbe: + description: Specifies the probe used for checking the running + status of the component. + properties: + commands: + description: Commands used to execute for probe. + properties: + queries: + description: Defines read checks that are executed + on the probe sidecar. + items: + type: string + type: array + writes: + description: Defines write checks that are executed + on the probe sidecar. + items: + type: string + type: array + type: object + failureThreshold: + default: 3 + description: Minimum consecutive failures for the probe + to be considered failed after having succeeded. + format: int32 + minimum: 2 + type: integer + periodSeconds: + default: 1 + description: How often (in seconds) to perform the probe. + format: int32 + minimum: 1 + type: integer + timeoutSeconds: + default: 1 + description: Number of seconds after which the probe + times out. Defaults to 1 second. + format: int32 + minimum: 1 + type: integer + type: object + statusProbe: + description: Specifies the probe used for checking the status + of the component. + properties: + commands: + description: Commands used to execute for probe. + properties: + queries: + description: Defines read checks that are executed + on the probe sidecar. + items: + type: string + type: array + writes: + description: Defines write checks that are executed + on the probe sidecar. + items: + type: string + type: array + type: object + failureThreshold: + default: 3 + description: Minimum consecutive failures for the probe + to be considered failed after having succeeded. + format: int32 + minimum: 2 + type: integer + periodSeconds: + default: 1 + description: How often (in seconds) to perform the probe. + format: int32 + minimum: 1 + type: integer + timeoutSeconds: + default: 1 + description: Number of seconds after which the probe + times out. Defaults to 1 second. + format: int32 + minimum: 1 + type: integer + type: object + type: object + replicationSpec: + description: Defines spec for `Replication` workloads. + properties: + llPodManagementPolicy: + description: |- + Controls the creation of pods during initial scale up, replacement of pods on nodes, and scaling down. + + + - `OrderedReady`: Creates pods in increasing order (pod-0, then pod-1, etc). The controller waits until each pod + is ready before continuing. Pods are removed in reverse order when scaling down. + - `Parallel`: Creates pods in parallel to match the desired scale without waiting. All pods are deleted at once + when scaling down. + type: string + llUpdateStrategy: + description: |- + Specifies the low-level StatefulSetUpdateStrategy to be used when updating Pods in the StatefulSet upon a + revision to the Template. + `UpdateStrategy` will be ignored if this is provided. + properties: + rollingUpdate: + description: RollingUpdate is used to communicate parameters + when Type is RollingUpdateStatefulSetStrategyType. + properties: + maxUnavailable: + anyOf: + - type: integer + - type: string + description: |- + The maximum number of pods that can be unavailable during the update. + Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). + Absolute number is calculated from percentage by rounding up. This can not be 0. + Defaults to 1. This field is alpha-level and is only honored by servers that enable the + MaxUnavailableStatefulSet feature. The field applies to all pods in the range 0 to + Replicas-1. That means if there is any unavailable pod in the range 0 to Replicas-1, it + will be counted towards MaxUnavailable. + x-kubernetes-int-or-string: true + partition: + description: |- + Partition indicates the ordinal at which the StatefulSet should be partitioned + for updates. During a rolling update, all pods from ordinal Replicas-1 to + Partition are updated. All pods from ordinal Partition-1 to 0 remain untouched. + This is helpful in being able to do a canary based deployment. The default value is 0. + format: int32 + type: integer + type: object + type: + description: |- + Type indicates the type of the StatefulSetUpdateStrategy. + Default is RollingUpdate. + type: string + type: object + updateStrategy: + default: Serial + description: |- + Specifies the strategy for updating Pods. + For workloadType=`Consensus`, the update strategy can be one of the following: + + + - `Serial`: Updates Members sequentially to minimize component downtime. + - `BestEffortParallel`: Updates Members in parallel to minimize component write downtime. Majority remains online + at all times. + - `Parallel`: Forces parallel updates. + enum: + - Serial + - BestEffortParallel + - Parallel + type: string + type: object + rsmSpec: + description: |- + Defines workload spec of this component. + From KB 0.7.0, RSM(InstanceSetSpec) will be the underlying CR which powers all kinds of workload in KB. + RSM is an enhanced stateful workload extension dedicated for heavy-state workloads like databases. + properties: + memberUpdateStrategy: + description: |- + Describes the strategy for updating Members (Pods). + + + - `Serial`: Updates Members sequentially to ensure minimum component downtime. + - `BestEffortParallel`: Updates Members in parallel to ensure minimum component write downtime. + - `Parallel`: Forces parallel updates. + enum: + - Serial + - BestEffortParallel + - Parallel + type: string + membershipReconfiguration: + description: Indicates the actions required for dynamic + membership reconfiguration. + properties: + logSyncAction: + description: |- + Defines the action to trigger the new member to start log syncing. + If the Image is not configured, the Image from the previous non-nil action will be used. + properties: + args: + description: Additional parameters used to perform + specific statements. This field is optional. + items: + type: string + type: array + command: + description: A set of instructions that will be + executed within the Container to retrieve or process + role information. This field is required. + items: + type: string + type: array + image: + description: Refers to the utility image that contains + the command which can be utilized to retrieve + or process role information. + type: string + required: + - command + type: object + memberJoinAction: + description: |- + Defines the action to add a member. + If the Image is not configured, the Image from the previous non-nil action will be used. + properties: + args: + description: Additional parameters used to perform + specific statements. This field is optional. + items: + type: string + type: array + command: + description: A set of instructions that will be + executed within the Container to retrieve or process + role information. This field is required. + items: + type: string + type: array + image: + description: Refers to the utility image that contains + the command which can be utilized to retrieve + or process role information. + type: string + required: + - command + type: object + memberLeaveAction: + description: |- + Defines the action to remove a member. + If the Image is not configured, the Image from the previous non-nil action will be used. + properties: + args: + description: Additional parameters used to perform + specific statements. This field is optional. + items: + type: string + type: array + command: + description: A set of instructions that will be + executed within the Container to retrieve or process + role information. This field is required. + items: + type: string + type: array + image: + description: Refers to the utility image that contains + the command which can be utilized to retrieve + or process role information. + type: string + required: + - command + type: object + promoteAction: + description: |- + Defines the action to inform the cluster that the new member can join voting now. + If the Image is not configured, the Image from the previous non-nil action will be used. + properties: + args: + description: Additional parameters used to perform + specific statements. This field is optional. + items: + type: string + type: array + command: + description: A set of instructions that will be + executed within the Container to retrieve or process + role information. This field is required. + items: + type: string + type: array + image: + description: Refers to the utility image that contains + the command which can be utilized to retrieve + or process role information. + type: string + required: + - command + type: object + switchoverAction: + description: |- + Specifies the environment variables that can be used in all following Actions: + - KB_ITS_USERNAME: Represents the username part of the credential + - KB_ITS_PASSWORD: Represents the password part of the credential + - KB_ITS_LEADER_HOST: Represents the leader host + - KB_ITS_TARGET_HOST: Represents the target host + - KB_ITS_SERVICE_PORT: Represents the service port + + + Defines the action to perform a switchover. + If the Image is not configured, the latest [BusyBox](https://busybox.net/) image will be used. + properties: + args: + description: Additional parameters used to perform + specific statements. This field is optional. + items: + type: string + type: array + command: + description: A set of instructions that will be + executed within the Container to retrieve or process + role information. This field is required. + items: + type: string + type: array + image: + description: Refers to the utility image that contains + the command which can be utilized to retrieve + or process role information. + type: string + required: + - command + type: object + type: object + roleProbe: + description: Defines the method used to probe a role. + properties: + customHandler: + description: |- + Defines a custom method for role probing. + Actions defined here are executed in series. + Upon completion of all actions, the final output should be a single string representing the role name defined in spec.Roles. + The latest [BusyBox](https://busybox.net/) image will be used if Image is not configured. + Environment variables can be used in Command: + - v_KB_ITS_LAST_STDOUT: stdout from the last action, watch for 'v_' prefix + - KB_ITS_USERNAME: username part of the credential + - KB_ITS_PASSWORD: password part of the credential + items: + properties: + args: + description: Additional parameters used to perform + specific statements. This field is optional. + items: + type: string + type: array + command: + description: A set of instructions that will be + executed within the Container to retrieve or + process role information. This field is required. + items: + type: string + type: array + image: + description: Refers to the utility image that + contains the command which can be utilized to + retrieve or process role information. + type: string + required: + - command + type: object + type: array + failureThreshold: + default: 3 + description: Specifies the minimum number of consecutive + failures for the probe to be considered failed after + having succeeded. + format: int32 + minimum: 1 + type: integer + initialDelaySeconds: + default: 0 + description: Specifies the number of seconds to wait + after the container has started before initiating + role probing. + format: int32 + minimum: 0 + type: integer + periodSeconds: + default: 2 + description: Specifies the frequency (in seconds) of + probe execution. + format: int32 + minimum: 1 + type: integer + roleUpdateMechanism: + default: ReadinessProbeEventUpdate + description: Specifies the method for updating the pod + role label. + enum: + - ReadinessProbeEventUpdate + - DirectAPIServerEventUpdate + type: string + successThreshold: + default: 1 + description: Specifies the minimum number of consecutive + successes for the probe to be considered successful + after having failed. + format: int32 + minimum: 1 + type: integer + timeoutSeconds: + default: 1 + description: Specifies the number of seconds after which + the probe times out. + format: int32 + minimum: 1 + type: integer + type: object + roles: + description: Specifies a list of roles defined within the + system. + items: + properties: + accessMode: + default: ReadWrite + description: Specifies the service capabilities of + this member. + enum: + - None + - Readonly + - ReadWrite + type: string + canVote: + default: true + description: Indicates if this member has voting rights. + type: boolean + isLeader: + default: false + description: Determines if this member is the leader. + type: boolean + name: + default: leader + description: Defines the role name of the replica. + type: string + required: + - accessMode + - name + type: object + type: array + type: object + scriptSpecs: + description: Defines the template of scripts. + items: + properties: + defaultMode: + description: |- + The operator attempts to set default file permissions for scripts (0555) and configurations (0444). + However, certain database engines may require different file permissions. + You can specify the desired file permissions here. + + + Must be specified as an octal value between 0000 and 0777 (inclusive), + or as a decimal value between 0 and 511 (inclusive). + YAML supports both octal and decimal values for file permissions. + + + Please note that this setting only affects the permissions of the files themselves. + Directories within the specified path are not impacted by this setting. + It's important to be aware that this setting might conflict with other options + that influence the file mode, such as fsGroup. + In such cases, the resulting file mode may have additional bits set. + Refers to documents of k8s.ConfigMapVolumeSource.defaultMode for more information. + format: int32 + type: integer + name: + description: Specifies the name of the configuration template. + maxLength: 63 + pattern: ^[a-z0-9]([a-z0-9\.\-]*[a-z0-9])?$ + type: string + namespace: + default: default + description: |- + Specifies the namespace of the referenced configuration template ConfigMap object. + An empty namespace is equivalent to the "default" namespace. + maxLength: 63 + pattern: ^[a-z0-9]([a-z0-9\-]*[a-z0-9])?$ + type: string + templateRef: + description: Specifies the name of the referenced configuration + template ConfigMap object. + maxLength: 63 + pattern: ^[a-z0-9]([a-z0-9\.\-]*[a-z0-9])?$ + type: string + volumeName: + description: |- + Refers to the volume name of PodTemplate. The configuration file produced through the configuration + template will be mounted to the corresponding volume. Must be a DNS_LABEL name. + The volume name must be defined in podSpec.containers[*].volumeMounts. + maxLength: 63 + pattern: ^[a-z]([a-z0-9\-]*[a-z0-9])?$ + type: string + required: + - name + - volumeName + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + service: + description: Defines the service spec. + properties: + ports: + description: |- + The list of ports that are exposed by this service. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + items: + description: ServicePort is deprecated since v0.8. + properties: + appProtocol: + description: |- + The application protocol for this port. + This field follows standard Kubernetes label syntax. + Un-prefixed names are reserved for IANA standard service names (as per + RFC-6335 and https://www.iana.org/assignments/service-names). + Non-standard protocols should use prefixed names such as + mycompany.com/my-custom-protocol. + type: string + name: + description: |- + The name of this port within the service. This must be a DNS_LABEL. + All ports within a ServiceSpec must have unique names. When considering + the endpoints for a Service, this must match the 'name' field in the + EndpointPort. + type: string + port: + description: The port that will be exposed by this + service. + format: int32 + type: integer + protocol: + default: TCP + description: |- + The IP protocol for this port. Supports "TCP", "UDP", and "SCTP". + Default is TCP. + enum: + - TCP + - UDP + - SCTP + type: string + targetPort: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the pods targeted by the service. + + + Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + + + - If this is a string, it will be looked up as a named port in the target Pod's container ports. + - If this is not specified, the value of the `port` field is used (an identity map). + + + This field is ignored for services with clusterIP=None, and should be + omitted or set equal to the `port` field. + + + More info: https://kubernetes.io/docs/concepts/services-networking/service/#defining-a-service + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-map-keys: + - port + - protocol + x-kubernetes-list-type: map + type: object + serviceRefDeclarations: + description: Used to declare the service reference of the current + component. + items: + description: |- + ServiceRefDeclaration represents a reference to a service that can be either provided by a KubeBlocks Cluster + or an external service. + It acts as a placeholder for the actual service reference, which is determined later when a Cluster is created. + + + The purpose of ServiceRefDeclaration is to declare a service dependency without specifying the concrete details + of the service. + It allows for flexibility and abstraction in defining service references within a Component. + By using ServiceRefDeclaration, you can define service dependencies in a declarative manner, enabling loose coupling + and easier management of service references across different components and clusters. + + + Upon Cluster creation, the ServiceRefDeclaration is bound to an actual service through the ServiceRef field, + effectively resolving and connecting to the specified service. + properties: + name: + description: Specifies the name of the ServiceRefDeclaration. + type: string + optional: + description: |- + Specifies whether the service reference can be optional. + + + For an optional service-ref, the component can still be created even if the service-ref is not provided. + type: boolean + serviceRefDeclarationSpecs: + description: |- + Defines a list of constraints and requirements for services that can be bound to this ServiceRefDeclaration + upon Cluster creation. + Each ServiceRefDeclarationSpec defines a ServiceKind and ServiceVersion, + outlining the acceptable service types and versions that are compatible. + + + This flexibility allows a ServiceRefDeclaration to be fulfilled by any one of the provided specs. + For example, if it requires an OLTP database, specs for both MySQL and PostgreSQL are listed, + either MySQL or PostgreSQL services can be used when binding. + items: + properties: + serviceKind: + description: |- + Specifies the type or nature of the service. This should be a well-known application cluster type, such as + {mysql, redis, mongodb}. + The field is case-insensitive and supports abbreviations for some well-known databases. + For instance, both `zk` and `zookeeper` are considered as a ZooKeeper cluster, while `pg`, `postgres`, `postgresql` + are all recognized as a PostgreSQL cluster. + type: string + serviceVersion: + description: |- + Defines the service version of the service reference. This is a regular expression that matches a version number pattern. + For instance, `^8.0.8$`, `8.0.\d{1,2}$`, `^[v\-]*?(\d{1,2}\.){0,3}\d{1,2}$` are all valid patterns. + type: string + required: + - serviceKind + - serviceVersion + type: object + type: array + required: + - name + - serviceRefDeclarationSpecs + type: object + type: array + statefulSpec: + description: Defines spec for `Stateful` workloads. + properties: + llPodManagementPolicy: + description: |- + Controls the creation of pods during initial scale up, replacement of pods on nodes, and scaling down. + + + - `OrderedReady`: Creates pods in increasing order (pod-0, then pod-1, etc). The controller waits until each pod + is ready before continuing. Pods are removed in reverse order when scaling down. + - `Parallel`: Creates pods in parallel to match the desired scale without waiting. All pods are deleted at once + when scaling down. + type: string + llUpdateStrategy: + description: |- + Specifies the low-level StatefulSetUpdateStrategy to be used when updating Pods in the StatefulSet upon a + revision to the Template. + `UpdateStrategy` will be ignored if this is provided. + properties: + rollingUpdate: + description: RollingUpdate is used to communicate parameters + when Type is RollingUpdateStatefulSetStrategyType. + properties: + maxUnavailable: + anyOf: + - type: integer + - type: string + description: |- + The maximum number of pods that can be unavailable during the update. + Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). + Absolute number is calculated from percentage by rounding up. This can not be 0. + Defaults to 1. This field is alpha-level and is only honored by servers that enable the + MaxUnavailableStatefulSet feature. The field applies to all pods in the range 0 to + Replicas-1. That means if there is any unavailable pod in the range 0 to Replicas-1, it + will be counted towards MaxUnavailable. + x-kubernetes-int-or-string: true + partition: + description: |- + Partition indicates the ordinal at which the StatefulSet should be partitioned + for updates. During a rolling update, all pods from ordinal Replicas-1 to + Partition are updated. All pods from ordinal Partition-1 to 0 remain untouched. + This is helpful in being able to do a canary based deployment. The default value is 0. + format: int32 + type: integer + type: object + type: + description: |- + Type indicates the type of the StatefulSetUpdateStrategy. + Default is RollingUpdate. + type: string + type: object + updateStrategy: + default: Serial + description: |- + Specifies the strategy for updating Pods. + For workloadType=`Consensus`, the update strategy can be one of the following: + + + - `Serial`: Updates Members sequentially to minimize component downtime. + - `BestEffortParallel`: Updates Members in parallel to minimize component write downtime. Majority remains online + at all times. + - `Parallel`: Forces parallel updates. + enum: + - Serial + - BestEffortParallel + - Parallel + type: string + type: object + statelessSpec: + description: Defines spec for `Stateless` workloads. + properties: + updateStrategy: + description: Specifies the deployment strategy that will + be used to replace existing pods with new ones. + properties: + rollingUpdate: + description: |- + Rolling update config params. Present only if DeploymentStrategyType = + RollingUpdate. + --- + TODO: Update this to follow our convention for oneOf, whatever we decide it + to be. + properties: + maxSurge: + anyOf: + - type: integer + - type: string + description: |- + The maximum number of pods that can be scheduled above the desired number of + pods. + Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). + This can not be 0 if MaxUnavailable is 0. + Absolute number is calculated from percentage by rounding up. + Defaults to 25%. + Example: when this is set to 30%, the new ReplicaSet can be scaled up immediately when + the rolling update starts, such that the total number of old and new pods do not exceed + 130% of desired pods. Once old pods have been killed, + new ReplicaSet can be scaled up further, ensuring that total number of pods running + at any time during the update is at most 130% of desired pods. + x-kubernetes-int-or-string: true + maxUnavailable: + anyOf: + - type: integer + - type: string + description: |- + The maximum number of pods that can be unavailable during the update. + Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). + Absolute number is calculated from percentage by rounding down. + This can not be 0 if MaxSurge is 0. + Defaults to 25%. + Example: when this is set to 30%, the old ReplicaSet can be scaled down to 70% of desired pods + immediately when the rolling update starts. Once new pods are ready, old ReplicaSet + can be scaled down further, followed by scaling up the new ReplicaSet, ensuring + that the total number of pods available at all times during the update is at + least 70% of desired pods. + x-kubernetes-int-or-string: true + type: object + type: + description: Type of deployment. Can be "Recreate" or + "RollingUpdate". Default is RollingUpdate. + type: string + type: object + type: object + switchoverSpec: + description: |- + Defines command to do switchover. + In particular, when workloadType=Replication, the command defined in switchoverSpec will only be executed under + the condition of cluster.componentSpecs[x].SwitchPolicy.type=Noop. + properties: + withCandidate: + description: Represents the action of switching over to + a specified candidate primary or leader instance. + properties: + cmdExecutorConfig: + description: Specifies the switchover command. + properties: + args: + description: Additional parameters used in the execution + of the command. + items: + type: string + type: array + command: + description: The command to be executed. + items: + type: string + minItems: 1 + type: array + env: + description: A list of environment variables that + will be injected into the command execution context. + items: + description: EnvVar represents an environment + variable present in a Container. + properties: + name: + description: Name of the environment variable. + Must be a C_IDENTIFIER. + type: string + value: + description: |- + Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in the container and + any service environment variables. If a variable cannot be resolved, + the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless of whether the variable + exists or not. + Defaults to "". + type: string + valueFrom: + description: Source for the environment variable's + value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema + the FieldPath is written in terms + of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to + select in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required + for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output + format of the exposed resources, + defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to + select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret + in the pod's namespace + properties: + key: + description: The key of the secret + to select from. Must be a valid + secret key. + type: string + 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 + optional: + description: Specify whether the Secret + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + x-kubernetes-preserve-unknown-fields: true + image: + description: Specifies the image used to execute + the command. + type: string + required: + - command + - image + type: object + scriptSpecSelectors: + description: |- + Used to select the script that need to be referenced. + When defined, the scripts defined in scriptSpecs can be referenced within the SwitchoverAction.CmdExecutorConfig. + items: + properties: + name: + description: Represents the name of the ScriptSpec + referent. + maxLength: 63 + pattern: ^[a-z0-9]([a-z0-9\.\-]*[a-z0-9])?$ + type: string + required: + - name + type: object + type: array + required: + - cmdExecutorConfig + type: object + withoutCandidate: + description: Represents the action of switching over without + specifying a candidate primary or leader instance. + properties: + cmdExecutorConfig: + description: Specifies the switchover command. + properties: + args: + description: Additional parameters used in the execution + of the command. + items: + type: string + type: array + command: + description: The command to be executed. + items: + type: string + minItems: 1 + type: array + env: + description: A list of environment variables that + will be injected into the command execution context. + items: + description: EnvVar represents an environment + variable present in a Container. + properties: + name: + description: Name of the environment variable. + Must be a C_IDENTIFIER. + type: string + value: + description: |- + Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in the container and + any service environment variables. If a variable cannot be resolved, + the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless of whether the variable + exists or not. + Defaults to "". + type: string + valueFrom: + description: Source for the environment variable's + value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema + the FieldPath is written in terms + of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to + select in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required + for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output + format of the exposed resources, + defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to + select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret + in the pod's namespace + properties: + key: + description: The key of the secret + to select from. Must be a valid + secret key. + type: string + 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 + optional: + description: Specify whether the Secret + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + x-kubernetes-preserve-unknown-fields: true + image: + description: Specifies the image used to execute + the command. + type: string + required: + - command + - image + type: object + scriptSpecSelectors: + description: |- + Used to select the script that need to be referenced. + When defined, the scripts defined in scriptSpecs can be referenced within the SwitchoverAction.CmdExecutorConfig. + items: + properties: + name: + description: Represents the name of the ScriptSpec + referent. + maxLength: 63 + pattern: ^[a-z0-9]([a-z0-9\.\-]*[a-z0-9])?$ + type: string + required: + - name + type: object + type: array + required: + - cmdExecutorConfig + type: object + type: object + systemAccounts: + description: Defines system accounts needed to manage the component, + and the statement to create them. + properties: + accounts: + description: Defines the configuration settings for system + accounts. + items: + description: |- + SystemAccountConfig specifies how to create and delete system accounts. + + + Deprecated since v0.9. + properties: + name: + description: The unique identifier of a system account. + enum: + - kbadmin + - kbdataprotection + - kbprobe + - kbmonitoring + - kbreplicator + type: string + provisionPolicy: + description: Outlines the strategy for creating the + account. + properties: + scope: + default: AnyPods + description: Defines the scope within which the + account is provisioned. + type: string + secretRef: + description: The external secret to refer. + properties: + name: + description: The unique identifier of the + secret. + type: string + namespace: + description: The namespace where the secret + is located. + type: string + required: + - name + - namespace + type: object + statements: + description: The statement to provision an account. + properties: + creation: + description: Specifies the statement required + to create a new account with the necessary + privileges. + type: string + deletion: + description: |- + Defines the statement required to delete an existing account. + Typically used in conjunction with the creation statement to delete an account before recreating it. + For example, one might use a `drop user if exists` statement followed by a `create user` statement to ensure a fresh account. + + + Deprecated: This field is deprecated and the update statement should be used instead. + type: string + update: + description: Defines the statement required + to update the password of an existing account. + type: string + required: + - creation + type: object + type: + description: Specifies the method to provision + an account. + enum: + - CreateByStmt + - ReferToExisting + type: string + required: + - scope + - type + type: object + required: + - name + - provisionPolicy + type: object + minItems: 1 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + cmdExecutorConfig: + description: Configures how to obtain the client SDK and + execute statements. + properties: + args: + description: Additional parameters used in the execution + of the command. + items: + type: string + type: array + command: + description: The command to be executed. + items: + type: string + minItems: 1 + type: array + env: + description: A list of environment variables that will + be injected into the command execution context. + items: + description: EnvVar represents an environment variable + present in a Container. + properties: + name: + description: Name of the environment variable. + Must be a C_IDENTIFIER. + type: string + value: + description: |- + Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in the container and + any service environment variables. If a variable cannot be resolved, + the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless of whether the variable + exists or not. + Defaults to "". + type: string + valueFrom: + description: Source for the environment variable's + value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the + FieldPath is written in terms of, defaults + to "v1". + type: string + fieldPath: + description: Path of the field to select + in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required + for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format + of the exposed resources, defaults to + "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in + the pod's namespace + properties: + key: + description: The key of the secret to + select from. Must be a valid secret + key. + type: string + 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 + optional: + description: Specify whether the Secret + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + x-kubernetes-preserve-unknown-fields: true + image: + description: Specifies the image used to execute the + command. + type: string + required: + - command + - image + type: object + passwordConfig: + description: Defines the pattern used to generate passwords + for system accounts. + properties: + length: + default: 16 + description: The length of the password. + format: int32 + maximum: 32 + minimum: 8 + type: integer + letterCase: + default: MixedCases + description: The case of the letters in the password. + enum: + - LowerCases + - UpperCases + - MixedCases + type: string + numDigits: + default: 4 + description: The number of digits in the password. + format: int32 + maximum: 8 + minimum: 0 + type: integer + numSymbols: + default: 0 + description: The number of symbols in the password. + format: int32 + maximum: 8 + minimum: 0 + type: integer + seed: + description: |- + Seed to generate the account's password. + Cannot be updated. + type: string + type: object + required: + - accounts + - cmdExecutorConfig + - passwordConfig + type: object + volumeProtectionSpec: + description: Defines settings to do volume protect. + properties: + highWatermark: + default: 90 + description: |- + The high watermark threshold for volume space usage. + If there is any specified volumes who's space usage is over the threshold, the pre-defined "LOCK" action + will be triggered to degrade the service to protect volume from space exhaustion, such as to set the instance + as read-only. And after that, if all volumes' space usage drops under the threshold later, the pre-defined + "UNLOCK" action will be performed to recover the service normally. + maximum: 100 + minimum: 0 + type: integer + volumes: + description: The Volumes to be protected. + items: + properties: + highWatermark: + description: |- + Defines the high watermark threshold for the volume, it will override the component level threshold. + If the value is invalid, it will be ignored and the component level threshold will be used. + maximum: 100 + minimum: 0 + type: integer + name: + description: The Name of the volume to protect. + type: string + type: object + type: array + type: object + volumeTypes: + description: |- + Used to describe the purpose of the volumes mapping the name of the VolumeMounts in the PodSpec.Container field, + such as data volume, log volume, etc. When backing up the volume, the volume can be correctly backed up according + to the volumeType. + + + For example: + + + - `name: data, type: data` means that the volume named `data` is used to store `data`. + - `name: binlog, type: log` means that the volume named `binlog` is used to store `log`. + + + NOTE: When volumeTypes is not defined, the backup function will not be supported, even if a persistent volume has + been specified. + items: + description: VolumeTypeSpec is deprecated since v0.9, replaced + with ComponentVolume. + properties: + name: + description: Corresponds to the name of the VolumeMounts + field in PodSpec.Container. + pattern: ^[a-z0-9]([a-z0-9\.\-]*[a-z0-9])?$ + type: string + type: + description: Type of data the volume will persistent. + enum: + - data + - log + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + workloadType: + description: |- + Defines the type of the workload. + + + - `Stateless` describes stateless applications. + - `Stateful` describes common stateful applications. + - `Consensus` describes applications based on consensus protocols, such as raft and paxos. + - `Replication` describes applications based on the primary-secondary data replication protocol. + enum: + - Stateless + - Stateful + - Consensus + - Replication + type: string + required: + - name + - workloadType + type: object + x-kubernetes-validations: + - message: componentDefs.consensusSpec(deprecated) or componentDefs.rsmSpec(recommended) + is required when componentDefs.workloadType is Consensus, and + forbidden otherwise + rule: 'has(self.workloadType) && self.workloadType == ''Consensus'' + ? (has(self.consensusSpec) || has(self.rsmSpec)) : !has(self.consensusSpec)' + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + connectionCredential: + additionalProperties: + type: string + description: |- + Connection credential template used for creating a connection credential secret for cluster objects. + + + Built-in objects are: + + + - `$(RANDOM_PASSWD)` random 8 characters. + - `$(STRONG_RANDOM_PASSWD)` random 16 characters, with mixed cases, digits and symbols. + - `$(UUID)` generate a random UUID v4 string. + - `$(UUID_B64)` generate a random UUID v4 BASE64 encoded string. + - `$(UUID_STR_B64)` generate a random UUID v4 string then BASE64 encoded. + - `$(UUID_HEX)` generate a random UUID v4 HEX representation. + - `$(HEADLESS_SVC_FQDN)` headless service FQDN placeholder, value pattern is `$(CLUSTER_NAME)-$(1ST_COMP_NAME)-headless.$(NAMESPACE).svc`, + where 1ST_COMP_NAME is the 1st component that provide `ClusterDefinition.spec.componentDefs[].service` attribute; + - `$(SVC_FQDN)` service FQDN placeholder, value pattern is `$(CLUSTER_NAME)-$(1ST_COMP_NAME).$(NAMESPACE).svc`, + where 1ST_COMP_NAME is the 1st component that provide `ClusterDefinition.spec.componentDefs[].service` attribute; + - `$(SVC_PORT_{PORT-NAME})` is ServicePort's port value with specified port name, i.e, a servicePort JSON struct: + `{"name": "mysql", "targetPort": "mysqlContainerPort", "port": 3306}`, and `$(SVC_PORT_mysql)` in the + connection credential value is 3306. + + + Deprecated since v0.9. + This field is maintained for backward compatibility and its use is discouraged. + Existing usage should be updated to the current preferred approach to avoid compatibility issues in future releases. + type: object topologies: description: Topologies defines all possible topologies within the cluster. @@ -362,6 +10232,17 @@ spec: maxItems: 128 minItems: 1 type: array + type: + description: |- + Specifies the well-known database type, such as mysql, redis, or mongodb. + + + Deprecated since v0.9. + This field is maintained for backward compatibility and its use is discouraged. + Existing usage should be updated to the current preferred approach to avoid compatibility issues in future releases. + maxLength: 24 + pattern: ^[a-z0-9]([a-z0-9\-]*[a-z0-9])?$ + type: string type: object status: description: ClusterDefinitionStatus defines the observed state of ClusterDefinition diff --git a/config/crd/bases/apps.kubeblocks.io_clusters.yaml b/config/crd/bases/apps.kubeblocks.io_clusters.yaml index 8eb9ec1959a..476972cd760 100644 --- a/config/crd/bases/apps.kubeblocks.io_clusters.yaml +++ b/config/crd/bases/apps.kubeblocks.io_clusters.yaml @@ -16991,6 +16991,27 @@ spec: description: Specifies Annotations to override or add for underlying Pods. type: object + classDefRef: + description: |- + References the class defined in ComponentClassDefinition. + + + Deprecated since v0.9. + This field is maintained for backward compatibility and its use is discouraged. + Existing usage should be updated to the current preferred approach to avoid compatibility issues in future releases. + properties: + class: + description: Defines the name of the class that is defined + in the ComponentClassDefinition. + type: string + name: + description: Specifies the name of the ComponentClassDefinition. + maxLength: 63 + pattern: ^[a-z0-9]([a-z0-9\.\-]*[a-z0-9])?$ + type: string + required: + - class + type: object componentDef: description: |- References the name of a ComponentDefinition object. @@ -26111,6 +26132,27 @@ spec: description: Specifies Annotations to override or add for underlying Pods. type: object + classDefRef: + description: |- + References the class defined in ComponentClassDefinition. + + + Deprecated since v0.9. + This field is maintained for backward compatibility and its use is discouraged. + Existing usage should be updated to the current preferred approach to avoid compatibility issues in future releases. + properties: + class: + description: Defines the name of the class that is defined + in the ComponentClassDefinition. + type: string + name: + description: Specifies the name of the ComponentClassDefinition. + maxLength: 63 + pattern: ^[a-z0-9]([a-z0-9\.\-]*[a-z0-9])?$ + type: string + required: + - class + type: object componentDef: description: |- References the name of a ComponentDefinition object. diff --git a/config/crd/bases/apps.kubeblocks.io_componentdefinitions.yaml b/config/crd/bases/apps.kubeblocks.io_componentdefinitions.yaml index 4360700ec17..58591693ee5 100644 --- a/config/crd/bases/apps.kubeblocks.io_componentdefinitions.yaml +++ b/config/crd/bases/apps.kubeblocks.io_componentdefinitions.yaml @@ -13527,57 +13527,80 @@ spec: and other administrative tasks. - The container executing this action has access to following variables: + Note: This field is immutable once it has been set. + properties: + builtinHandler: + description: |- + Specifies the name of the predefined action handler to be invoked for lifecycle actions. - - KB_ACCOUNT_NAME: The name of the system account to be created. - - KB_ACCOUNT_PASSWORD: The password for the system account. // TODO: how to pass the password securely? - - KB_ACCOUNT_STATEMENT: The statement used to create the system account. + Lorry, as a sidecar agent co-located with the database container in the same Pod, + includes a suite of built-in action implementations that are tailored to different database engines. + These are known as "builtin" handlers, includes: `mysql`, `redis`, `mongodb`, `etcd`, + `postgresql`, `official-postgresql`, `apecloud-postgresql`, `wesql`, `oceanbase`, `polardbx`. - Note: This field is immutable once it has been set. - properties: - exec: - description: |- - Defines the command to run. + If the `builtinHandler` field is specified, it instructs Lorry to utilize its internal built-in action handler + to execute the specified lifecycle actions. - This field cannot be updated. - properties: - args: - description: Args represents the arguments that are passed - to the `command` for execution. - items: - type: string - type: array - command: - description: |- - Specifies the command to be executed inside the container. - The working directory for this command is the container's root directory('/'). - Commands are executed directly without a shell environment, meaning shell-specific syntax ('|', etc.) is not supported. - If the shell is required, it must be explicitly invoked in the command. + The `builtinHandler` field is of type `BuiltinActionHandlerType`, + which represents the name of the built-in handler. + The `builtinHandler` specified within the same `ComponentLifecycleActions` should be consistent across all + actions. + This means that if you specify a built-in handler for one action, you should use the same handler + for all other actions throughout the entire `ComponentLifecycleActions` collection. - A successful execution is indicated by an exit status of 0; any non-zero status signifies a failure. - items: - type: string - type: array - container: - description: |- - Specifies the name of the container within the same pod whose resources will be shared with the action. - This allows the action to utilize the specified container's resources without executing within it. + If you need to define lifecycle actions for database engines not covered by the existing built-in support, + or when the pre-existing built-in handlers do not meet your specific needs, + you can use the `customHandler` field to define your own action implementation. - The name must match one of the containers defined in `componentDefinition.spec.runtime`. + Deprecation Notice: - The resources that can be shared are included: + - In the future, the `builtinHandler` field will be deprecated in favor of using the `customHandler` field + for configuring all lifecycle actions. + - Instead of using a name to indicate the built-in action implementations in Lorry, + the recommended approach will be to explicitly invoke the desired action implementation through + a gRPC interface exposed by the sidecar agent. + - Developers will have the flexibility to either use the built-in action implementations provided by Lorry + or develop their own sidecar agent to implement custom actions and expose them via gRPC interfaces. + - This change will allow for greater customization and extensibility of lifecycle actions, + as developers can create their own "builtin" implementations tailored to their specific requirements. + type: string + customHandler: + description: |- + Specifies a user-defined hook or procedure that is called to perform the specific lifecycle action. + It offers a flexible and expandable approach for customizing the behavior of a Component by leveraging + tailored actions. - - volume mounts + An Action can be implemented as either an ExecAction or an HTTPAction, with future versions planning + to support GRPCAction, + thereby accommodating unique logic for different database systems within the Action's framework. + + + In future iterations, all built-in handlers are expected to transition to GRPCAction. + This change means that Lorry or other sidecar agents will expose the implementation of actions + through a GRPC interface for external invocation. + Then the controller will interact with these actions via GRPCAction calls. + properties: + container: + description: |- + Defines the name of the container within the target Pod where the action will be executed. + + + This name must correspond to one of the containers defined in `componentDefinition.spec.runtime`. + If this field is not specified, the default behavior is to use the first container listed in + `componentDefinition.spec.runtime`. This field cannot be updated. + + + Note: This field is reserved for future use and is not currently active. type: string env: description: |- @@ -13699,13 +13722,101 @@ spec: - name type: object type: array + exec: + description: |- + Defines the command to run. + + + This field cannot be updated. + properties: + args: + description: Args represents the arguments that are + passed to the `command` for execution. + items: + type: string + type: array + command: + description: |- + Specifies the command to be executed inside the container. + The working directory for this command is the container's root directory('/'). + Commands are executed directly without a shell environment, meaning shell-specific syntax ('|', etc.) is not supported. + If the shell is required, it must be explicitly invoked in the command. + + + A successful execution is indicated by an exit status of 0; any non-zero status signifies a failure. + items: + type: string + type: array + type: object + http: + description: |- + Specifies the HTTP request to perform. + + + This field cannot be updated. + + + Note: HTTPAction is to be implemented in future version. + properties: + host: + description: |- + Indicates the server's domain name or IP address. Defaults to the Pod's IP. + Prefer setting the "Host" header in httpHeaders when needed. + type: string + httpHeaders: + description: |- + Allows for the inclusion of custom headers in the request. + HTTP permits the use of repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + method: + description: |- + Represents the type of HTTP request to be made, such as "GET," "POST," "PUT," etc. + If not specified, "GET" is the default method. + type: string + path: + description: Specifies the endpoint to be requested + on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Specifies the target port for the HTTP request. + It can be specified either as a numeric value in the range of 1 to 65535, + or as a named port that meets the IANA_SVC_NAME specification. + x-kubernetes-int-or-string: true + scheme: + description: |- + Designates the protocol used to make the request, such as HTTP or HTTPS. + If not specified, HTTP is used by default. + type: string + required: + - port + type: object image: description: |- Specifies the container image to be used for running the Action. When specified, a dedicated container will be created using this image to execute the Action. - All actions with same image will share the same container. + This field is mutually exclusive with the `container` field; only one of them should be provided. This field cannot be updated. @@ -13722,85 +13833,86 @@ spec: This field cannot be updated. + + + Note: This field is reserved for future use and is not currently active. type: string - targetPodSelector: + preCondition: description: |- - Defines the criteria used to select the target Pod(s) for executing the Action. - This is useful when there is no default target replica identified. - It allows for precise control over which Pod(s) the Action should run in. + Specifies the state that the cluster must reach before the Action is executed. + Currently, this is only applicable to the `postProvision` action. - If not specified, the Action will be executed in the pod where the Action is triggered, such as the pod - to be removed or added; or a random pod if the Action is triggered at the component level, such as - post-provision or pre-terminate of the component. + The conditions are as follows: - This field cannot be updated. - enum: - - Any - - All - - Role - - Ordinal - type: string - type: object - preCondition: - description: |- - Specifies the state that the cluster must reach before the Action is executed. - Currently, this is only applicable to the `postProvision` action. + - `Immediately`: Executed right after the Component object is created. + The readiness of the Component and its resources is not guaranteed at this stage. + - `RuntimeReady`: The Action is triggered after the Component object has been created and all associated + runtime resources (e.g. Pods) are in a ready state. + - `ComponentReady`: The Action is triggered after the Component itself is in a ready state. + This process does not affect the readiness state of the Component or the Cluster. + - `ClusterReady`: The Action is executed after the Cluster is in a ready state. + This execution does not alter the Component or the Cluster's state of readiness. - The conditions are as follows: + This field cannot be updated. + type: string + retryPolicy: + description: |- + Defines the strategy to be taken when retrying the Action after a failure. - - `Immediately`: Executed right after the Component object is created. - The readiness of the Component and its resources is not guaranteed at this stage. - - `RuntimeReady`: The Action is triggered after the Component object has been created and all associated - runtime resources (e.g. Pods) are in a ready state. - - `ComponentReady`: The Action is triggered after the Component itself is in a ready state. - This process does not affect the readiness state of the Component or the Cluster. - - `ClusterReady`: The Action is executed after the Cluster is in a ready state. - This execution does not alter the Component or the Cluster's state of readiness. + It specifies the conditions under which the Action should be retried and the limits to apply, + such as the maximum number of retries and backoff strategy. - This field cannot be updated. - type: string - retryPolicy: - description: |- - Defines the strategy to be taken when retrying the Action after a failure. + This field cannot be updated. + properties: + maxRetries: + default: 0 + description: |- + Defines the maximum number of retry attempts that should be made for a given Action. + This value is set to 0 by default, indicating that no retries will be made. + type: integer + retryInterval: + default: 0 + description: |- + Indicates the duration of time to wait between each retry attempt. + This value is set to 0 by default, indicating that there will be no delay between retry attempts. + format: int64 + type: integer + type: object + targetPodSelector: + description: |- + Defines the criteria used to select the target Pod(s) for executing the Action. + This is useful when there is no default target replica identified. + It allows for precise control over which Pod(s) the Action should run in. - It specifies the conditions under which the Action should be retried and the limits to apply, - such as the maximum number of retries and backoff strategy. + This field cannot be updated. - This field cannot be updated. - properties: - maxRetries: - default: 0 - description: |- - Defines the maximum number of retry attempts that should be made for a given Action. - This value is set to 0 by default, indicating that no retries will be made. - type: integer - retryInterval: + Note: This field is reserved for future use and is not currently active. + enum: + - Any + - All + - Role + - Ordinal + type: string + timeoutSeconds: default: 0 description: |- - Indicates the duration of time to wait between each retry attempt. - This value is set to 0 by default, indicating that there will be no delay between retry attempts. - format: int64 - type: integer - type: object - timeoutSeconds: - default: 0 - description: |- - Specifies the maximum duration in seconds that the Action is allowed to run. + Specifies the maximum duration in seconds that the Action is allowed to run. - If the Action does not complete within this time frame, it will be terminated. + If the Action does not complete within this time frame, it will be terminated. - This field cannot be updated. - format: int32 - type: integer + This field cannot be updated. + format: int32 + type: integer + type: object type: object dataDump: description: |- @@ -13824,47 +13936,78 @@ spec: Note: This field is immutable once it has been set. properties: - exec: + builtinHandler: description: |- - Defines the command to run. + Specifies the name of the predefined action handler to be invoked for lifecycle actions. - This field cannot be updated. - properties: - args: - description: Args represents the arguments that are passed - to the `command` for execution. - items: - type: string - type: array - command: - description: |- - Specifies the command to be executed inside the container. - The working directory for this command is the container's root directory('/'). - Commands are executed directly without a shell environment, meaning shell-specific syntax ('|', etc.) is not supported. - If the shell is required, it must be explicitly invoked in the command. + Lorry, as a sidecar agent co-located with the database container in the same Pod, + includes a suite of built-in action implementations that are tailored to different database engines. + These are known as "builtin" handlers, includes: `mysql`, `redis`, `mongodb`, `etcd`, + `postgresql`, `official-postgresql`, `apecloud-postgresql`, `wesql`, `oceanbase`, `polardbx`. - A successful execution is indicated by an exit status of 0; any non-zero status signifies a failure. - items: - type: string - type: array - container: - description: |- - Specifies the name of the container within the same pod whose resources will be shared with the action. - This allows the action to utilize the specified container's resources without executing within it. + If the `builtinHandler` field is specified, it instructs Lorry to utilize its internal built-in action handler + to execute the specified lifecycle actions. - The name must match one of the containers defined in `componentDefinition.spec.runtime`. + The `builtinHandler` field is of type `BuiltinActionHandlerType`, + which represents the name of the built-in handler. + The `builtinHandler` specified within the same `ComponentLifecycleActions` should be consistent across all + actions. + This means that if you specify a built-in handler for one action, you should use the same handler + for all other actions throughout the entire `ComponentLifecycleActions` collection. - The resources that can be shared are included: + If you need to define lifecycle actions for database engines not covered by the existing built-in support, + or when the pre-existing built-in handlers do not meet your specific needs, + you can use the `customHandler` field to define your own action implementation. - - volume mounts + Deprecation Notice: + + + - In the future, the `builtinHandler` field will be deprecated in favor of using the `customHandler` field + for configuring all lifecycle actions. + - Instead of using a name to indicate the built-in action implementations in Lorry, + the recommended approach will be to explicitly invoke the desired action implementation through + a gRPC interface exposed by the sidecar agent. + - Developers will have the flexibility to either use the built-in action implementations provided by Lorry + or develop their own sidecar agent to implement custom actions and expose them via gRPC interfaces. + - This change will allow for greater customization and extensibility of lifecycle actions, + as developers can create their own "builtin" implementations tailored to their specific requirements. + type: string + customHandler: + description: |- + Specifies a user-defined hook or procedure that is called to perform the specific lifecycle action. + It offers a flexible and expandable approach for customizing the behavior of a Component by leveraging + tailored actions. + + + An Action can be implemented as either an ExecAction or an HTTPAction, with future versions planning + to support GRPCAction, + thereby accommodating unique logic for different database systems within the Action's framework. + + + In future iterations, all built-in handlers are expected to transition to GRPCAction. + This change means that Lorry or other sidecar agents will expose the implementation of actions + through a GRPC interface for external invocation. + Then the controller will interact with these actions via GRPCAction calls. + properties: + container: + description: |- + Defines the name of the container within the target Pod where the action will be executed. + + + This name must correspond to one of the containers defined in `componentDefinition.spec.runtime`. + If this field is not specified, the default behavior is to use the first container listed in + `componentDefinition.spec.runtime`. This field cannot be updated. + + + Note: This field is reserved for future use and is not currently active. type: string env: description: |- @@ -13986,108 +14129,197 @@ spec: - name type: object type: array - image: + exec: description: |- - Specifies the container image to be used for running the Action. - - - When specified, a dedicated container will be created using this image to execute the Action. - All actions with same image will share the same container. + Defines the command to run. This field cannot be updated. - type: string - matchingKey: - description: |- - Used in conjunction with the `targetPodSelector` field to refine the selection of target pod(s) for Action execution. - The impact of this field depends on the `targetPodSelector` value: + properties: + args: + description: Args represents the arguments that are + passed to the `command` for execution. + items: + type: string + type: array + command: + description: |- + Specifies the command to be executed inside the container. + The working directory for this command is the container's root directory('/'). + Commands are executed directly without a shell environment, meaning shell-specific syntax ('|', etc.) is not supported. + If the shell is required, it must be explicitly invoked in the command. - - When `targetPodSelector` is set to `Any` or `All`, this field will be ignored. - - When `targetPodSelector` is set to `Role`, only those replicas whose role matches the `matchingKey` - will be selected for the Action. + A successful execution is indicated by an exit status of 0; any non-zero status signifies a failure. + items: + type: string + type: array + type: object + http: + description: |- + Specifies the HTTP request to perform. This field cannot be updated. - type: string - targetPodSelector: - description: |- - Defines the criteria used to select the target Pod(s) for executing the Action. - This is useful when there is no default target replica identified. - It allows for precise control over which Pod(s) the Action should run in. - If not specified, the Action will be executed in the pod where the Action is triggered, such as the pod - to be removed or added; or a random pod if the Action is triggered at the component level, such as - post-provision or pre-terminate of the component. + Note: HTTPAction is to be implemented in future version. + properties: + host: + description: |- + Indicates the server's domain name or IP address. Defaults to the Pod's IP. + Prefer setting the "Host" header in httpHeaders when needed. + type: string + httpHeaders: + description: |- + Allows for the inclusion of custom headers in the request. + HTTP permits the use of repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + method: + description: |- + Represents the type of HTTP request to be made, such as "GET," "POST," "PUT," etc. + If not specified, "GET" is the default method. + type: string + path: + description: Specifies the endpoint to be requested + on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Specifies the target port for the HTTP request. + It can be specified either as a numeric value in the range of 1 to 65535, + or as a named port that meets the IANA_SVC_NAME specification. + x-kubernetes-int-or-string: true + scheme: + description: |- + Designates the protocol used to make the request, such as HTTP or HTTPS. + If not specified, HTTP is used by default. + type: string + required: + - port + type: object + image: + description: |- + Specifies the container image to be used for running the Action. + + + When specified, a dedicated container will be created using this image to execute the Action. + This field is mutually exclusive with the `container` field; only one of them should be provided. This field cannot be updated. - enum: - - Any - - All - - Role - - Ordinal type: string - type: object - preCondition: - description: |- - Specifies the state that the cluster must reach before the Action is executed. - Currently, this is only applicable to the `postProvision` action. + matchingKey: + description: |- + Used in conjunction with the `targetPodSelector` field to refine the selection of target pod(s) for Action execution. + The impact of this field depends on the `targetPodSelector` value: - The conditions are as follows: + - When `targetPodSelector` is set to `Any` or `All`, this field will be ignored. + - When `targetPodSelector` is set to `Role`, only those replicas whose role matches the `matchingKey` + will be selected for the Action. - - `Immediately`: Executed right after the Component object is created. - The readiness of the Component and its resources is not guaranteed at this stage. - - `RuntimeReady`: The Action is triggered after the Component object has been created and all associated - runtime resources (e.g. Pods) are in a ready state. - - `ComponentReady`: The Action is triggered after the Component itself is in a ready state. - This process does not affect the readiness state of the Component or the Cluster. - - `ClusterReady`: The Action is executed after the Cluster is in a ready state. - This execution does not alter the Component or the Cluster's state of readiness. + This field cannot be updated. - This field cannot be updated. - type: string - retryPolicy: - description: |- - Defines the strategy to be taken when retrying the Action after a failure. + Note: This field is reserved for future use and is not currently active. + type: string + preCondition: + description: |- + Specifies the state that the cluster must reach before the Action is executed. + Currently, this is only applicable to the `postProvision` action. - It specifies the conditions under which the Action should be retried and the limits to apply, - such as the maximum number of retries and backoff strategy. + The conditions are as follows: - This field cannot be updated. - properties: - maxRetries: - default: 0 + - `Immediately`: Executed right after the Component object is created. + The readiness of the Component and its resources is not guaranteed at this stage. + - `RuntimeReady`: The Action is triggered after the Component object has been created and all associated + runtime resources (e.g. Pods) are in a ready state. + - `ComponentReady`: The Action is triggered after the Component itself is in a ready state. + This process does not affect the readiness state of the Component or the Cluster. + - `ClusterReady`: The Action is executed after the Cluster is in a ready state. + This execution does not alter the Component or the Cluster's state of readiness. + + + This field cannot be updated. + type: string + retryPolicy: description: |- - Defines the maximum number of retry attempts that should be made for a given Action. - This value is set to 0 by default, indicating that no retries will be made. - type: integer - retryInterval: + Defines the strategy to be taken when retrying the Action after a failure. + + + It specifies the conditions under which the Action should be retried and the limits to apply, + such as the maximum number of retries and backoff strategy. + + + This field cannot be updated. + properties: + maxRetries: + default: 0 + description: |- + Defines the maximum number of retry attempts that should be made for a given Action. + This value is set to 0 by default, indicating that no retries will be made. + type: integer + retryInterval: + default: 0 + description: |- + Indicates the duration of time to wait between each retry attempt. + This value is set to 0 by default, indicating that there will be no delay between retry attempts. + format: int64 + type: integer + type: object + targetPodSelector: + description: |- + Defines the criteria used to select the target Pod(s) for executing the Action. + This is useful when there is no default target replica identified. + It allows for precise control over which Pod(s) the Action should run in. + + + This field cannot be updated. + + + Note: This field is reserved for future use and is not currently active. + enum: + - Any + - All + - Role + - Ordinal + type: string + timeoutSeconds: default: 0 description: |- - Indicates the duration of time to wait between each retry attempt. - This value is set to 0 by default, indicating that there will be no delay between retry attempts. - format: int64 - type: integer - type: object - timeoutSeconds: - default: 0 - description: |- - Specifies the maximum duration in seconds that the Action is allowed to run. + Specifies the maximum duration in seconds that the Action is allowed to run. - If the Action does not complete within this time frame, it will be terminated. + If the Action does not complete within this time frame, it will be terminated. - This field cannot be updated. - format: int32 - type: integer + This field cannot be updated. + format: int32 + type: integer + type: object type: object dataLoad: description: |- @@ -14110,47 +14342,78 @@ spec: Note: This field is immutable once it has been set. properties: - exec: + builtinHandler: description: |- - Defines the command to run. + Specifies the name of the predefined action handler to be invoked for lifecycle actions. - This field cannot be updated. - properties: - args: - description: Args represents the arguments that are passed - to the `command` for execution. - items: - type: string - type: array - command: - description: |- - Specifies the command to be executed inside the container. - The working directory for this command is the container's root directory('/'). - Commands are executed directly without a shell environment, meaning shell-specific syntax ('|', etc.) is not supported. - If the shell is required, it must be explicitly invoked in the command. + Lorry, as a sidecar agent co-located with the database container in the same Pod, + includes a suite of built-in action implementations that are tailored to different database engines. + These are known as "builtin" handlers, includes: `mysql`, `redis`, `mongodb`, `etcd`, + `postgresql`, `official-postgresql`, `apecloud-postgresql`, `wesql`, `oceanbase`, `polardbx`. - A successful execution is indicated by an exit status of 0; any non-zero status signifies a failure. - items: - type: string - type: array - container: - description: |- - Specifies the name of the container within the same pod whose resources will be shared with the action. - This allows the action to utilize the specified container's resources without executing within it. + If the `builtinHandler` field is specified, it instructs Lorry to utilize its internal built-in action handler + to execute the specified lifecycle actions. - The name must match one of the containers defined in `componentDefinition.spec.runtime`. + The `builtinHandler` field is of type `BuiltinActionHandlerType`, + which represents the name of the built-in handler. + The `builtinHandler` specified within the same `ComponentLifecycleActions` should be consistent across all + actions. + This means that if you specify a built-in handler for one action, you should use the same handler + for all other actions throughout the entire `ComponentLifecycleActions` collection. - The resources that can be shared are included: + If you need to define lifecycle actions for database engines not covered by the existing built-in support, + or when the pre-existing built-in handlers do not meet your specific needs, + you can use the `customHandler` field to define your own action implementation. - - volume mounts + Deprecation Notice: + + + - In the future, the `builtinHandler` field will be deprecated in favor of using the `customHandler` field + for configuring all lifecycle actions. + - Instead of using a name to indicate the built-in action implementations in Lorry, + the recommended approach will be to explicitly invoke the desired action implementation through + a gRPC interface exposed by the sidecar agent. + - Developers will have the flexibility to either use the built-in action implementations provided by Lorry + or develop their own sidecar agent to implement custom actions and expose them via gRPC interfaces. + - This change will allow for greater customization and extensibility of lifecycle actions, + as developers can create their own "builtin" implementations tailored to their specific requirements. + type: string + customHandler: + description: |- + Specifies a user-defined hook or procedure that is called to perform the specific lifecycle action. + It offers a flexible and expandable approach for customizing the behavior of a Component by leveraging + tailored actions. + + + An Action can be implemented as either an ExecAction or an HTTPAction, with future versions planning + to support GRPCAction, + thereby accommodating unique logic for different database systems within the Action's framework. + + + In future iterations, all built-in handlers are expected to transition to GRPCAction. + This change means that Lorry or other sidecar agents will expose the implementation of actions + through a GRPC interface for external invocation. + Then the controller will interact with these actions via GRPCAction calls. + properties: + container: + description: |- + Defines the name of the container within the target Pod where the action will be executed. + + + This name must correspond to one of the containers defined in `componentDefinition.spec.runtime`. + If this field is not specified, the default behavior is to use the first container listed in + `componentDefinition.spec.runtime`. This field cannot be updated. + + + Note: This field is reserved for future use and is not currently active. type: string env: description: |- @@ -14272,13 +14535,101 @@ spec: - name type: object type: array + exec: + description: |- + Defines the command to run. + + + This field cannot be updated. + properties: + args: + description: Args represents the arguments that are + passed to the `command` for execution. + items: + type: string + type: array + command: + description: |- + Specifies the command to be executed inside the container. + The working directory for this command is the container's root directory('/'). + Commands are executed directly without a shell environment, meaning shell-specific syntax ('|', etc.) is not supported. + If the shell is required, it must be explicitly invoked in the command. + + + A successful execution is indicated by an exit status of 0; any non-zero status signifies a failure. + items: + type: string + type: array + type: object + http: + description: |- + Specifies the HTTP request to perform. + + + This field cannot be updated. + + + Note: HTTPAction is to be implemented in future version. + properties: + host: + description: |- + Indicates the server's domain name or IP address. Defaults to the Pod's IP. + Prefer setting the "Host" header in httpHeaders when needed. + type: string + httpHeaders: + description: |- + Allows for the inclusion of custom headers in the request. + HTTP permits the use of repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + method: + description: |- + Represents the type of HTTP request to be made, such as "GET," "POST," "PUT," etc. + If not specified, "GET" is the default method. + type: string + path: + description: Specifies the endpoint to be requested + on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Specifies the target port for the HTTP request. + It can be specified either as a numeric value in the range of 1 to 65535, + or as a named port that meets the IANA_SVC_NAME specification. + x-kubernetes-int-or-string: true + scheme: + description: |- + Designates the protocol used to make the request, such as HTTP or HTTPS. + If not specified, HTTP is used by default. + type: string + required: + - port + type: object image: description: |- Specifies the container image to be used for running the Action. When specified, a dedicated container will be created using this image to execute the Action. - All actions with same image will share the same container. + This field is mutually exclusive with the `container` field; only one of them should be provided. This field cannot be updated. @@ -14294,8 +14645,57 @@ spec: will be selected for the Action. + This field cannot be updated. + + + Note: This field is reserved for future use and is not currently active. + type: string + preCondition: + description: |- + Specifies the state that the cluster must reach before the Action is executed. + Currently, this is only applicable to the `postProvision` action. + + + The conditions are as follows: + + + - `Immediately`: Executed right after the Component object is created. + The readiness of the Component and its resources is not guaranteed at this stage. + - `RuntimeReady`: The Action is triggered after the Component object has been created and all associated + runtime resources (e.g. Pods) are in a ready state. + - `ComponentReady`: The Action is triggered after the Component itself is in a ready state. + This process does not affect the readiness state of the Component or the Cluster. + - `ClusterReady`: The Action is executed after the Cluster is in a ready state. + This execution does not alter the Component or the Cluster's state of readiness. + + This field cannot be updated. type: string + retryPolicy: + description: |- + Defines the strategy to be taken when retrying the Action after a failure. + + + It specifies the conditions under which the Action should be retried and the limits to apply, + such as the maximum number of retries and backoff strategy. + + + This field cannot be updated. + properties: + maxRetries: + default: 0 + description: |- + Defines the maximum number of retry attempts that should be made for a given Action. + This value is set to 0 by default, indicating that no retries will be made. + type: integer + retryInterval: + default: 0 + description: |- + Indicates the duration of time to wait between each retry attempt. + This value is set to 0 by default, indicating that there will be no delay between retry attempts. + format: int64 + type: integer + type: object targetPodSelector: description: |- Defines the criteria used to select the target Pod(s) for executing the Action. @@ -14303,139 +14703,150 @@ spec: It allows for precise control over which Pod(s) the Action should run in. - If not specified, the Action will be executed in the pod where the Action is triggered, such as the pod - to be removed or added; or a random pod if the Action is triggered at the component level, such as - post-provision or pre-terminate of the component. + This field cannot be updated. - This field cannot be updated. + Note: This field is reserved for future use and is not currently active. enum: - Any - All - Role - Ordinal type: string - type: object - preCondition: - description: |- - Specifies the state that the cluster must reach before the Action is executed. - Currently, this is only applicable to the `postProvision` action. + timeoutSeconds: + default: 0 + description: |- + Specifies the maximum duration in seconds that the Action is allowed to run. - The conditions are as follows: + If the Action does not complete within this time frame, it will be terminated. - - `Immediately`: Executed right after the Component object is created. - The readiness of the Component and its resources is not guaranteed at this stage. - - `RuntimeReady`: The Action is triggered after the Component object has been created and all associated - runtime resources (e.g. Pods) are in a ready state. - - `ComponentReady`: The Action is triggered after the Component itself is in a ready state. - This process does not affect the readiness state of the Component or the Cluster. - - `ClusterReady`: The Action is executed after the Cluster is in a ready state. - This execution does not alter the Component or the Cluster's state of readiness. + This field cannot be updated. + format: int32 + type: integer + type: object + type: object + memberJoin: + description: |- + Defines the procedure to add a new replica to the replication group. - This field cannot be updated. - type: string - retryPolicy: - description: |- - Defines the strategy to be taken when retrying the Action after a failure. + This action is initiated after a replica pod becomes ready. - It specifies the conditions under which the Action should be retried and the limits to apply, - such as the maximum number of retries and backoff strategy. + The role of the replica (e.g., primary, secondary) will be determined and assigned as part of the action command + implementation, or automatically by the database kernel or a sidecar utility like Patroni that implements + a consensus algorithm. - This field cannot be updated. - properties: - maxRetries: - default: 0 - description: |- - Defines the maximum number of retry attempts that should be made for a given Action. - This value is set to 0 by default, indicating that no retries will be made. - type: integer - retryInterval: - default: 0 - description: |- - Indicates the duration of time to wait between each retry attempt. - This value is set to 0 by default, indicating that there will be no delay between retry attempts. - format: int64 - type: integer - type: object - timeoutSeconds: - default: 0 - description: |- - Specifies the maximum duration in seconds that the Action is allowed to run. + The container executing this action has access to following environment variables: - If the Action does not complete within this time frame, it will be terminated. + - KB_SERVICE_PORT: The port used by the database service. + - KB_SERVICE_USER: The username with the necessary permissions to interact with the database service. + - KB_SERVICE_PASSWORD: The corresponding password for KB_SERVICE_USER to authenticate with the database service. + - KB_PRIMARY_POD_FQDN: The FQDN of the primary Pod within the replication group. + - KB_MEMBER_ADDRESSES: A comma-separated list of Pod addresses for all replicas in the group. + - KB_NEW_MEMBER_POD_NAME: The pod name of the replica being added to the group. + - KB_NEW_MEMBER_POD_IP: The IP address of the replica being added to the group. - This field cannot be updated. - format: int32 - type: integer - type: object - memberJoin: - description: "Defines the procedure to add a new replica to the - replication group.\n\n\nThis action is initiated after a replica - pod becomes ready.\n\n\nThe role of the replica (e.g., primary, - secondary) will be determined and assigned as part of the action - command\nimplementation, or automatically by the database kernel - or a sidecar utility like Patroni that implements\na consensus - algorithm.\n\n\nThe container executing this action has access - to following variables:\n\n\n- KB_JOIN_MEMBER_POD_FQDN: The - pod FQDN of the replica being added to the group.\n- KB_JOIN_MEMBER_POD_NAME: - The pod name of the replica being added to the group.\n\n\nExpected - action output:\n- On Failure: An error message detailing the - reason for any failure encountered\n during the addition of - the new member.\n\n\nFor example, to add a new OBServer to an - OceanBase Cluster in 'zone1', the following command may be used:\n\n\n```yaml\ncommand:\n- - bash\n- -c\n- |\n CLIENT=\"mysql -u $SERVICE_USER -p$SERVICE_PASSWORD - -P $SERVICE_PORT -h $SERVICE_HOST -e\"\n\t $CLIENT \"ALTER - SYSTEM ADD SERVER '$KB_POD_FQDN:$SERVICE_PORT' ZONE 'zone1'\"\n```\n\n\nNote: - This field is immutable once it has been set." + Expected action output: + - On Failure: An error message detailing the reason for any failure encountered + during the addition of the new member. + + + For example, to add a new OBServer to an OceanBase Cluster in 'zone1', the following command may be used: + + + ```yaml + command: + - bash + - -c + - | + ADDRESS=$(KB_MEMBER_ADDRESSES%%,*) + HOST=$(echo $ADDRESS | cut -d ':' -f 1) + PORT=$(echo $ADDRESS | cut -d ':' -f 2) + CLIENT="mysql -u $KB_SERVICE_USER -p$KB_SERVICE_PASSWORD -P $PORT -h $HOST -e" + $CLIENT "ALTER SYSTEM ADD SERVER '$KB_NEW_MEMBER_POD_IP:$KB_SERVICE_PORT' ZONE 'zone1'" + ``` + + + Note: This field is immutable once it has been set. properties: - exec: + builtinHandler: description: |- - Defines the command to run. + Specifies the name of the predefined action handler to be invoked for lifecycle actions. - This field cannot be updated. - properties: - args: - description: Args represents the arguments that are passed - to the `command` for execution. - items: - type: string - type: array - command: - description: |- - Specifies the command to be executed inside the container. - The working directory for this command is the container's root directory('/'). - Commands are executed directly without a shell environment, meaning shell-specific syntax ('|', etc.) is not supported. - If the shell is required, it must be explicitly invoked in the command. + Lorry, as a sidecar agent co-located with the database container in the same Pod, + includes a suite of built-in action implementations that are tailored to different database engines. + These are known as "builtin" handlers, includes: `mysql`, `redis`, `mongodb`, `etcd`, + `postgresql`, `official-postgresql`, `apecloud-postgresql`, `wesql`, `oceanbase`, `polardbx`. - A successful execution is indicated by an exit status of 0; any non-zero status signifies a failure. - items: - type: string - type: array - container: - description: |- - Specifies the name of the container within the same pod whose resources will be shared with the action. - This allows the action to utilize the specified container's resources without executing within it. + If the `builtinHandler` field is specified, it instructs Lorry to utilize its internal built-in action handler + to execute the specified lifecycle actions. - The name must match one of the containers defined in `componentDefinition.spec.runtime`. + The `builtinHandler` field is of type `BuiltinActionHandlerType`, + which represents the name of the built-in handler. + The `builtinHandler` specified within the same `ComponentLifecycleActions` should be consistent across all + actions. + This means that if you specify a built-in handler for one action, you should use the same handler + for all other actions throughout the entire `ComponentLifecycleActions` collection. - The resources that can be shared are included: + If you need to define lifecycle actions for database engines not covered by the existing built-in support, + or when the pre-existing built-in handlers do not meet your specific needs, + you can use the `customHandler` field to define your own action implementation. - - volume mounts + Deprecation Notice: + + + - In the future, the `builtinHandler` field will be deprecated in favor of using the `customHandler` field + for configuring all lifecycle actions. + - Instead of using a name to indicate the built-in action implementations in Lorry, + the recommended approach will be to explicitly invoke the desired action implementation through + a gRPC interface exposed by the sidecar agent. + - Developers will have the flexibility to either use the built-in action implementations provided by Lorry + or develop their own sidecar agent to implement custom actions and expose them via gRPC interfaces. + - This change will allow for greater customization and extensibility of lifecycle actions, + as developers can create their own "builtin" implementations tailored to their specific requirements. + type: string + customHandler: + description: |- + Specifies a user-defined hook or procedure that is called to perform the specific lifecycle action. + It offers a flexible and expandable approach for customizing the behavior of a Component by leveraging + tailored actions. + + + An Action can be implemented as either an ExecAction or an HTTPAction, with future versions planning + to support GRPCAction, + thereby accommodating unique logic for different database systems within the Action's framework. + + + In future iterations, all built-in handlers are expected to transition to GRPCAction. + This change means that Lorry or other sidecar agents will expose the implementation of actions + through a GRPC interface for external invocation. + Then the controller will interact with these actions via GRPCAction calls. + properties: + container: + description: |- + Defines the name of the container within the target Pod where the action will be executed. + + + This name must correspond to one of the containers defined in `componentDefinition.spec.runtime`. + If this field is not specified, the default behavior is to use the first container listed in + `componentDefinition.spec.runtime`. This field cannot be updated. + + + Note: This field is reserved for future use and is not currently active. type: string env: description: |- @@ -14557,13 +14968,101 @@ spec: - name type: object type: array + exec: + description: |- + Defines the command to run. + + + This field cannot be updated. + properties: + args: + description: Args represents the arguments that are + passed to the `command` for execution. + items: + type: string + type: array + command: + description: |- + Specifies the command to be executed inside the container. + The working directory for this command is the container's root directory('/'). + Commands are executed directly without a shell environment, meaning shell-specific syntax ('|', etc.) is not supported. + If the shell is required, it must be explicitly invoked in the command. + + + A successful execution is indicated by an exit status of 0; any non-zero status signifies a failure. + items: + type: string + type: array + type: object + http: + description: |- + Specifies the HTTP request to perform. + + + This field cannot be updated. + + + Note: HTTPAction is to be implemented in future version. + properties: + host: + description: |- + Indicates the server's domain name or IP address. Defaults to the Pod's IP. + Prefer setting the "Host" header in httpHeaders when needed. + type: string + httpHeaders: + description: |- + Allows for the inclusion of custom headers in the request. + HTTP permits the use of repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + method: + description: |- + Represents the type of HTTP request to be made, such as "GET," "POST," "PUT," etc. + If not specified, "GET" is the default method. + type: string + path: + description: Specifies the endpoint to be requested + on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Specifies the target port for the HTTP request. + It can be specified either as a numeric value in the range of 1 to 65535, + or as a named port that meets the IANA_SVC_NAME specification. + x-kubernetes-int-or-string: true + scheme: + description: |- + Designates the protocol used to make the request, such as HTTP or HTTPS. + If not specified, HTTP is used by default. + type: string + required: + - port + type: object image: description: |- Specifies the container image to be used for running the Action. When specified, a dedicated container will be created using this image to execute the Action. - All actions with same image will share the same container. + This field is mutually exclusive with the `container` field; only one of them should be provided. This field cannot be updated. @@ -14579,8 +15078,57 @@ spec: will be selected for the Action. + This field cannot be updated. + + + Note: This field is reserved for future use and is not currently active. + type: string + preCondition: + description: |- + Specifies the state that the cluster must reach before the Action is executed. + Currently, this is only applicable to the `postProvision` action. + + + The conditions are as follows: + + + - `Immediately`: Executed right after the Component object is created. + The readiness of the Component and its resources is not guaranteed at this stage. + - `RuntimeReady`: The Action is triggered after the Component object has been created and all associated + runtime resources (e.g. Pods) are in a ready state. + - `ComponentReady`: The Action is triggered after the Component itself is in a ready state. + This process does not affect the readiness state of the Component or the Cluster. + - `ClusterReady`: The Action is executed after the Cluster is in a ready state. + This execution does not alter the Component or the Cluster's state of readiness. + + This field cannot be updated. type: string + retryPolicy: + description: |- + Defines the strategy to be taken when retrying the Action after a failure. + + + It specifies the conditions under which the Action should be retried and the limits to apply, + such as the maximum number of retries and backoff strategy. + + + This field cannot be updated. + properties: + maxRetries: + default: 0 + description: |- + Defines the maximum number of retry attempts that should be made for a given Action. + This value is set to 0 by default, indicating that no retries will be made. + type: integer + retryInterval: + default: 0 + description: |- + Indicates the duration of time to wait between each retry attempt. + This value is set to 0 by default, indicating that there will be no delay between retry attempts. + format: int64 + type: integer + type: object targetPodSelector: description: |- Defines the criteria used to select the target Pod(s) for executing the Action. @@ -14588,141 +15136,150 @@ spec: It allows for precise control over which Pod(s) the Action should run in. - If not specified, the Action will be executed in the pod where the Action is triggered, such as the pod - to be removed or added; or a random pod if the Action is triggered at the component level, such as - post-provision or pre-terminate of the component. + This field cannot be updated. - This field cannot be updated. + Note: This field is reserved for future use and is not currently active. enum: - Any - All - Role - Ordinal type: string + timeoutSeconds: + default: 0 + description: |- + Specifies the maximum duration in seconds that the Action is allowed to run. + + + If the Action does not complete within this time frame, it will be terminated. + + + This field cannot be updated. + format: int32 + type: integer type: object - preCondition: - description: |- - Specifies the state that the cluster must reach before the Action is executed. - Currently, this is only applicable to the `postProvision` action. + type: object + memberLeave: + description: |- + Defines the procedure to remove a replica from the replication group. - The conditions are as follows: + This action is initiated before remove a replica from the group. + The operator will wait for MemberLeave to complete successfully before releasing the replica and cleaning up + related Kubernetes resources. - - `Immediately`: Executed right after the Component object is created. - The readiness of the Component and its resources is not guaranteed at this stage. - - `RuntimeReady`: The Action is triggered after the Component object has been created and all associated - runtime resources (e.g. Pods) are in a ready state. - - `ComponentReady`: The Action is triggered after the Component itself is in a ready state. - This process does not affect the readiness state of the Component or the Cluster. - - `ClusterReady`: The Action is executed after the Cluster is in a ready state. - This execution does not alter the Component or the Cluster's state of readiness. + The process typically includes updating configurations and informing other group members about the removal. + Data migration is generally not part of this action and should be handled separately if needed. - This field cannot be updated. - type: string - retryPolicy: - description: |- - Defines the strategy to be taken when retrying the Action after a failure. + The container executing this action has access to following environment variables: - It specifies the conditions under which the Action should be retried and the limits to apply, - such as the maximum number of retries and backoff strategy. + - KB_SERVICE_PORT: The port used by the database service. + - KB_SERVICE_USER: The username with the necessary permissions to interact with the database service. + - KB_SERVICE_PASSWORD: The corresponding password for KB_SERVICE_USER to authenticate with the database service. + - KB_PRIMARY_POD_FQDN: The FQDN of the primary Pod within the replication group. + - KB_MEMBER_ADDRESSES: A comma-separated list of Pod addresses for all replicas in the group. + - KB_LEAVE_MEMBER_POD_NAME: The pod name of the replica being removed from the group. + - KB_LEAVE_MEMBER_POD_IP: The IP address of the replica being removed from the group. - This field cannot be updated. - properties: - maxRetries: - default: 0 - description: |- - Defines the maximum number of retry attempts that should be made for a given Action. - This value is set to 0 by default, indicating that no retries will be made. - type: integer - retryInterval: - default: 0 - description: |- - Indicates the duration of time to wait between each retry attempt. - This value is set to 0 by default, indicating that there will be no delay between retry attempts. - format: int64 - type: integer - type: object - timeoutSeconds: - default: 0 + Expected action output: + - On Failure: An error message, if applicable, indicating why the action failed. + + + For example, to remove an OBServer from an OceanBase Cluster in 'zone1', the following command can be executed: + + + ```yaml + command: + - bash + - -c + - | + ADDRESS=$(KB_MEMBER_ADDRESSES%%,*) + HOST=$(echo $ADDRESS | cut -d ':' -f 1) + PORT=$(echo $ADDRESS | cut -d ':' -f 2) + CLIENT="mysql -u $KB_SERVICE_USER -p$KB_SERVICE_PASSWORD -P $PORT -h $HOST -e" + $CLIENT "ALTER SYSTEM DELETE SERVER '$KB_LEAVE_MEMBER_POD_IP:$KB_SERVICE_PORT' ZONE 'zone1'" + ``` + + + Note: This field is immutable once it has been set. + properties: + builtinHandler: description: |- - Specifies the maximum duration in seconds that the Action is allowed to run. + Specifies the name of the predefined action handler to be invoked for lifecycle actions. - If the Action does not complete within this time frame, it will be terminated. + Lorry, as a sidecar agent co-located with the database container in the same Pod, + includes a suite of built-in action implementations that are tailored to different database engines. + These are known as "builtin" handlers, includes: `mysql`, `redis`, `mongodb`, `etcd`, + `postgresql`, `official-postgresql`, `apecloud-postgresql`, `wesql`, `oceanbase`, `polardbx`. - This field cannot be updated. - format: int32 - type: integer - type: object - memberLeave: - description: "Defines the procedure to remove a replica from the - replication group.\n\n\nThis action is initiated before remove - a replica from the group.\nThe operator will wait for MemberLeave - to complete successfully before releasing the replica and cleaning - up\nrelated Kubernetes resources.\n\n\nThe process typically - includes updating configurations and informing other group members - about the removal.\nData migration is generally not part of - this action and should be handled separately if needed.\n\n\nThe - container executing this action has access to following variables:\n\n\n- - KB_LEAVE_MEMBER_POD_FQDN: The pod name of the replica being - removed from the group.\n- KB_LEAVE_MEMBER_POD_NAME: The pod - name of the replica being removed from the group.\n\n\nExpected - action output:\n- On Failure: An error message, if applicable, - indicating why the action failed.\n\n\nFor example, to remove - an OBServer from an OceanBase Cluster in 'zone1', the following - command can be executed:\n\n\n```yaml\ncommand:\n- bash\n- -c\n- - |\n CLIENT=\"mysql -u $SERVICE_USER -p$SERVICE_PASSWORD -P - $SERVICE_PORT -h $SERVICE_HOST -e\"\n\t $CLIENT \"ALTER SYSTEM - DELETE SERVER '$KB_POD_FQDN:$SERVICE_PORT' ZONE 'zone1'\"\n```\n\n\nNote: - This field is immutable once it has been set." - properties: - exec: - description: |- - Defines the command to run. + If the `builtinHandler` field is specified, it instructs Lorry to utilize its internal built-in action handler + to execute the specified lifecycle actions. - This field cannot be updated. - properties: - args: - description: Args represents the arguments that are passed - to the `command` for execution. - items: - type: string - type: array - command: - description: |- - Specifies the command to be executed inside the container. - The working directory for this command is the container's root directory('/'). - Commands are executed directly without a shell environment, meaning shell-specific syntax ('|', etc.) is not supported. - If the shell is required, it must be explicitly invoked in the command. + The `builtinHandler` field is of type `BuiltinActionHandlerType`, + which represents the name of the built-in handler. + The `builtinHandler` specified within the same `ComponentLifecycleActions` should be consistent across all + actions. + This means that if you specify a built-in handler for one action, you should use the same handler + for all other actions throughout the entire `ComponentLifecycleActions` collection. - A successful execution is indicated by an exit status of 0; any non-zero status signifies a failure. - items: - type: string - type: array - container: - description: |- - Specifies the name of the container within the same pod whose resources will be shared with the action. - This allows the action to utilize the specified container's resources without executing within it. + If you need to define lifecycle actions for database engines not covered by the existing built-in support, + or when the pre-existing built-in handlers do not meet your specific needs, + you can use the `customHandler` field to define your own action implementation. - The name must match one of the containers defined in `componentDefinition.spec.runtime`. + Deprecation Notice: - The resources that can be shared are included: + - In the future, the `builtinHandler` field will be deprecated in favor of using the `customHandler` field + for configuring all lifecycle actions. + - Instead of using a name to indicate the built-in action implementations in Lorry, + the recommended approach will be to explicitly invoke the desired action implementation through + a gRPC interface exposed by the sidecar agent. + - Developers will have the flexibility to either use the built-in action implementations provided by Lorry + or develop their own sidecar agent to implement custom actions and expose them via gRPC interfaces. + - This change will allow for greater customization and extensibility of lifecycle actions, + as developers can create their own "builtin" implementations tailored to their specific requirements. + type: string + customHandler: + description: |- + Specifies a user-defined hook or procedure that is called to perform the specific lifecycle action. + It offers a flexible and expandable approach for customizing the behavior of a Component by leveraging + tailored actions. - - volume mounts + An Action can be implemented as either an ExecAction or an HTTPAction, with future versions planning + to support GRPCAction, + thereby accommodating unique logic for different database systems within the Action's framework. + + + In future iterations, all built-in handlers are expected to transition to GRPCAction. + This change means that Lorry or other sidecar agents will expose the implementation of actions + through a GRPC interface for external invocation. + Then the controller will interact with these actions via GRPCAction calls. + properties: + container: + description: |- + Defines the name of the container within the target Pod where the action will be executed. + + + This name must correspond to one of the containers defined in `componentDefinition.spec.runtime`. + If this field is not specified, the default behavior is to use the first container listed in + `componentDefinition.spec.runtime`. This field cannot be updated. + + + Note: This field is reserved for future use and is not currently active. type: string env: description: |- @@ -14844,13 +15401,101 @@ spec: - name type: object type: array + exec: + description: |- + Defines the command to run. + + + This field cannot be updated. + properties: + args: + description: Args represents the arguments that are + passed to the `command` for execution. + items: + type: string + type: array + command: + description: |- + Specifies the command to be executed inside the container. + The working directory for this command is the container's root directory('/'). + Commands are executed directly without a shell environment, meaning shell-specific syntax ('|', etc.) is not supported. + If the shell is required, it must be explicitly invoked in the command. + + + A successful execution is indicated by an exit status of 0; any non-zero status signifies a failure. + items: + type: string + type: array + type: object + http: + description: |- + Specifies the HTTP request to perform. + + + This field cannot be updated. + + + Note: HTTPAction is to be implemented in future version. + properties: + host: + description: |- + Indicates the server's domain name or IP address. Defaults to the Pod's IP. + Prefer setting the "Host" header in httpHeaders when needed. + type: string + httpHeaders: + description: |- + Allows for the inclusion of custom headers in the request. + HTTP permits the use of repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + method: + description: |- + Represents the type of HTTP request to be made, such as "GET," "POST," "PUT," etc. + If not specified, "GET" is the default method. + type: string + path: + description: Specifies the endpoint to be requested + on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Specifies the target port for the HTTP request. + It can be specified either as a numeric value in the range of 1 to 65535, + or as a named port that meets the IANA_SVC_NAME specification. + x-kubernetes-int-or-string: true + scheme: + description: |- + Designates the protocol used to make the request, such as HTTP or HTTPS. + If not specified, HTTP is used by default. + type: string + required: + - port + type: object image: description: |- Specifies the container image to be used for running the Action. When specified, a dedicated container will be created using this image to execute the Action. - All actions with same image will share the same container. + This field is mutually exclusive with the `container` field; only one of them should be provided. This field cannot be updated. @@ -14867,85 +15512,86 @@ spec: This field cannot be updated. + + + Note: This field is reserved for future use and is not currently active. type: string - targetPodSelector: + preCondition: description: |- - Defines the criteria used to select the target Pod(s) for executing the Action. - This is useful when there is no default target replica identified. - It allows for precise control over which Pod(s) the Action should run in. + Specifies the state that the cluster must reach before the Action is executed. + Currently, this is only applicable to the `postProvision` action. - If not specified, the Action will be executed in the pod where the Action is triggered, such as the pod - to be removed or added; or a random pod if the Action is triggered at the component level, such as - post-provision or pre-terminate of the component. + The conditions are as follows: - This field cannot be updated. - enum: - - Any - - All - - Role - - Ordinal - type: string - type: object - preCondition: - description: |- - Specifies the state that the cluster must reach before the Action is executed. - Currently, this is only applicable to the `postProvision` action. + - `Immediately`: Executed right after the Component object is created. + The readiness of the Component and its resources is not guaranteed at this stage. + - `RuntimeReady`: The Action is triggered after the Component object has been created and all associated + runtime resources (e.g. Pods) are in a ready state. + - `ComponentReady`: The Action is triggered after the Component itself is in a ready state. + This process does not affect the readiness state of the Component or the Cluster. + - `ClusterReady`: The Action is executed after the Cluster is in a ready state. + This execution does not alter the Component or the Cluster's state of readiness. - The conditions are as follows: + This field cannot be updated. + type: string + retryPolicy: + description: |- + Defines the strategy to be taken when retrying the Action after a failure. - - `Immediately`: Executed right after the Component object is created. - The readiness of the Component and its resources is not guaranteed at this stage. - - `RuntimeReady`: The Action is triggered after the Component object has been created and all associated - runtime resources (e.g. Pods) are in a ready state. - - `ComponentReady`: The Action is triggered after the Component itself is in a ready state. - This process does not affect the readiness state of the Component or the Cluster. - - `ClusterReady`: The Action is executed after the Cluster is in a ready state. - This execution does not alter the Component or the Cluster's state of readiness. + It specifies the conditions under which the Action should be retried and the limits to apply, + such as the maximum number of retries and backoff strategy. - This field cannot be updated. - type: string - retryPolicy: - description: |- - Defines the strategy to be taken when retrying the Action after a failure. + This field cannot be updated. + properties: + maxRetries: + default: 0 + description: |- + Defines the maximum number of retry attempts that should be made for a given Action. + This value is set to 0 by default, indicating that no retries will be made. + type: integer + retryInterval: + default: 0 + description: |- + Indicates the duration of time to wait between each retry attempt. + This value is set to 0 by default, indicating that there will be no delay between retry attempts. + format: int64 + type: integer + type: object + targetPodSelector: + description: |- + Defines the criteria used to select the target Pod(s) for executing the Action. + This is useful when there is no default target replica identified. + It allows for precise control over which Pod(s) the Action should run in. - It specifies the conditions under which the Action should be retried and the limits to apply, - such as the maximum number of retries and backoff strategy. + This field cannot be updated. - This field cannot be updated. - properties: - maxRetries: - default: 0 - description: |- - Defines the maximum number of retry attempts that should be made for a given Action. - This value is set to 0 by default, indicating that no retries will be made. - type: integer - retryInterval: + Note: This field is reserved for future use and is not currently active. + enum: + - Any + - All + - Role + - Ordinal + type: string + timeoutSeconds: default: 0 description: |- - Indicates the duration of time to wait between each retry attempt. - This value is set to 0 by default, indicating that there will be no delay between retry attempts. - format: int64 - type: integer - type: object - timeoutSeconds: - default: 0 - description: |- - Specifies the maximum duration in seconds that the Action is allowed to run. + Specifies the maximum duration in seconds that the Action is allowed to run. - If the Action does not complete within this time frame, it will be terminated. + If the Action does not complete within this time frame, it will be terminated. - This field cannot be updated. - format: int32 - type: integer + This field cannot be updated. + format: int32 + type: integer + type: object type: object postProvision: description: |- @@ -14960,49 +15606,108 @@ spec: The PostProvision Action is intended to run only once. + The container executing this action has access to following environment variables: + + + - KB_CLUSTER_POD_IP_LIST: Comma-separated list of the cluster's pod IP addresses (e.g., "podIp1,podIp2"). + - KB_CLUSTER_POD_NAME_LIST: Comma-separated list of the cluster's pod names (e.g., "pod1,pod2"). + - KB_CLUSTER_POD_HOST_NAME_LIST: Comma-separated list of host names, each corresponding to a pod in + KB_CLUSTER_POD_NAME_LIST (e.g., "hostName1,hostName2"). + - KB_CLUSTER_POD_HOST_IP_LIST: Comma-separated list of host IP addresses, each corresponding to a pod in + KB_CLUSTER_POD_NAME_LIST (e.g., "hostIp1,hostIp2"). + + + - KB_CLUSTER_COMPONENT_POD_NAME_LIST: Comma-separated list of all pod names within the component + (e.g., "pod1,pod2"). + - KB_CLUSTER_COMPONENT_POD_IP_LIST: Comma-separated list of pod IP addresses, + matching the order of pods in KB_CLUSTER_COMPONENT_POD_NAME_LIST (e.g., "podIp1,podIp2"). + - KB_CLUSTER_COMPONENT_POD_HOST_NAME_LIST: Comma-separated list of host names for each pod, + matching the order of pods in KB_CLUSTER_COMPONENT_POD_NAME_LIST (e.g., "hostName1,hostName2"). + - KB_CLUSTER_COMPONENT_POD_HOST_IP_LIST: Comma-separated list of host IP addresses for each pod, + matching the order of pods in KB_CLUSTER_COMPONENT_POD_NAME_LIST (e.g., "hostIp1,hostIp2"). + + + - KB_CLUSTER_COMPONENT_LIST: Comma-separated list of all cluster components (e.g., "comp1,comp2"). + - KB_CLUSTER_COMPONENT_DELETING_LIST: Comma-separated list of components that are currently being deleted + (e.g., "comp1,comp2"). + - KB_CLUSTER_COMPONENT_UNDELETED_LIST: Comma-separated list of components that are not being deleted + (e.g., "comp1,comp2"). + + Note: This field is immutable once it has been set. properties: - exec: + builtinHandler: description: |- - Defines the command to run. + Specifies the name of the predefined action handler to be invoked for lifecycle actions. - This field cannot be updated. - properties: - args: - description: Args represents the arguments that are passed - to the `command` for execution. - items: - type: string - type: array - command: - description: |- - Specifies the command to be executed inside the container. - The working directory for this command is the container's root directory('/'). - Commands are executed directly without a shell environment, meaning shell-specific syntax ('|', etc.) is not supported. - If the shell is required, it must be explicitly invoked in the command. + Lorry, as a sidecar agent co-located with the database container in the same Pod, + includes a suite of built-in action implementations that are tailored to different database engines. + These are known as "builtin" handlers, includes: `mysql`, `redis`, `mongodb`, `etcd`, + `postgresql`, `official-postgresql`, `apecloud-postgresql`, `wesql`, `oceanbase`, `polardbx`. - A successful execution is indicated by an exit status of 0; any non-zero status signifies a failure. - items: - type: string - type: array - container: - description: |- - Specifies the name of the container within the same pod whose resources will be shared with the action. - This allows the action to utilize the specified container's resources without executing within it. + If the `builtinHandler` field is specified, it instructs Lorry to utilize its internal built-in action handler + to execute the specified lifecycle actions. - The name must match one of the containers defined in `componentDefinition.spec.runtime`. + The `builtinHandler` field is of type `BuiltinActionHandlerType`, + which represents the name of the built-in handler. + The `builtinHandler` specified within the same `ComponentLifecycleActions` should be consistent across all + actions. + This means that if you specify a built-in handler for one action, you should use the same handler + for all other actions throughout the entire `ComponentLifecycleActions` collection. - The resources that can be shared are included: + If you need to define lifecycle actions for database engines not covered by the existing built-in support, + or when the pre-existing built-in handlers do not meet your specific needs, + you can use the `customHandler` field to define your own action implementation. - - volume mounts + Deprecation Notice: + + + - In the future, the `builtinHandler` field will be deprecated in favor of using the `customHandler` field + for configuring all lifecycle actions. + - Instead of using a name to indicate the built-in action implementations in Lorry, + the recommended approach will be to explicitly invoke the desired action implementation through + a gRPC interface exposed by the sidecar agent. + - Developers will have the flexibility to either use the built-in action implementations provided by Lorry + or develop their own sidecar agent to implement custom actions and expose them via gRPC interfaces. + - This change will allow for greater customization and extensibility of lifecycle actions, + as developers can create their own "builtin" implementations tailored to their specific requirements. + type: string + customHandler: + description: |- + Specifies a user-defined hook or procedure that is called to perform the specific lifecycle action. + It offers a flexible and expandable approach for customizing the behavior of a Component by leveraging + tailored actions. + + + An Action can be implemented as either an ExecAction or an HTTPAction, with future versions planning + to support GRPCAction, + thereby accommodating unique logic for different database systems within the Action's framework. + + + In future iterations, all built-in handlers are expected to transition to GRPCAction. + This change means that Lorry or other sidecar agents will expose the implementation of actions + through a GRPC interface for external invocation. + Then the controller will interact with these actions via GRPCAction calls. + properties: + container: + description: |- + Defines the name of the container within the target Pod where the action will be executed. + + + This name must correspond to one of the containers defined in `componentDefinition.spec.runtime`. + If this field is not specified, the default behavior is to use the first container listed in + `componentDefinition.spec.runtime`. This field cannot be updated. + + + Note: This field is reserved for future use and is not currently active. type: string env: description: |- @@ -15124,18 +15829,106 @@ spec: - name type: object type: array - image: + exec: description: |- - Specifies the container image to be used for running the Action. + Defines the command to run. - When specified, a dedicated container will be created using this image to execute the Action. - All actions with same image will share the same container. + This field cannot be updated. + properties: + args: + description: Args represents the arguments that are + passed to the `command` for execution. + items: + type: string + type: array + command: + description: |- + Specifies the command to be executed inside the container. + The working directory for this command is the container's root directory('/'). + Commands are executed directly without a shell environment, meaning shell-specific syntax ('|', etc.) is not supported. + If the shell is required, it must be explicitly invoked in the command. - This field cannot be updated. - type: string - matchingKey: + A successful execution is indicated by an exit status of 0; any non-zero status signifies a failure. + items: + type: string + type: array + type: object + http: + description: |- + Specifies the HTTP request to perform. + + + This field cannot be updated. + + + Note: HTTPAction is to be implemented in future version. + properties: + host: + description: |- + Indicates the server's domain name or IP address. Defaults to the Pod's IP. + Prefer setting the "Host" header in httpHeaders when needed. + type: string + httpHeaders: + description: |- + Allows for the inclusion of custom headers in the request. + HTTP permits the use of repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + method: + description: |- + Represents the type of HTTP request to be made, such as "GET," "POST," "PUT," etc. + If not specified, "GET" is the default method. + type: string + path: + description: Specifies the endpoint to be requested + on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Specifies the target port for the HTTP request. + It can be specified either as a numeric value in the range of 1 to 65535, + or as a named port that meets the IANA_SVC_NAME specification. + x-kubernetes-int-or-string: true + scheme: + description: |- + Designates the protocol used to make the request, such as HTTP or HTTPS. + If not specified, HTTP is used by default. + type: string + required: + - port + type: object + image: + description: |- + Specifies the container image to be used for running the Action. + + + When specified, a dedicated container will be created using this image to execute the Action. + This field is mutually exclusive with the `container` field; only one of them should be provided. + + + This field cannot be updated. + type: string + matchingKey: description: |- Used in conjunction with the `targetPodSelector` field to refine the selection of target pod(s) for Action execution. The impact of this field depends on the `targetPodSelector` value: @@ -15147,85 +15940,86 @@ spec: This field cannot be updated. + + + Note: This field is reserved for future use and is not currently active. type: string - targetPodSelector: + preCondition: description: |- - Defines the criteria used to select the target Pod(s) for executing the Action. - This is useful when there is no default target replica identified. - It allows for precise control over which Pod(s) the Action should run in. + Specifies the state that the cluster must reach before the Action is executed. + Currently, this is only applicable to the `postProvision` action. - If not specified, the Action will be executed in the pod where the Action is triggered, such as the pod - to be removed or added; or a random pod if the Action is triggered at the component level, such as - post-provision or pre-terminate of the component. + The conditions are as follows: - This field cannot be updated. - enum: - - Any - - All - - Role - - Ordinal - type: string - type: object - preCondition: - description: |- - Specifies the state that the cluster must reach before the Action is executed. - Currently, this is only applicable to the `postProvision` action. + - `Immediately`: Executed right after the Component object is created. + The readiness of the Component and its resources is not guaranteed at this stage. + - `RuntimeReady`: The Action is triggered after the Component object has been created and all associated + runtime resources (e.g. Pods) are in a ready state. + - `ComponentReady`: The Action is triggered after the Component itself is in a ready state. + This process does not affect the readiness state of the Component or the Cluster. + - `ClusterReady`: The Action is executed after the Cluster is in a ready state. + This execution does not alter the Component or the Cluster's state of readiness. - The conditions are as follows: + This field cannot be updated. + type: string + retryPolicy: + description: |- + Defines the strategy to be taken when retrying the Action after a failure. - - `Immediately`: Executed right after the Component object is created. - The readiness of the Component and its resources is not guaranteed at this stage. - - `RuntimeReady`: The Action is triggered after the Component object has been created and all associated - runtime resources (e.g. Pods) are in a ready state. - - `ComponentReady`: The Action is triggered after the Component itself is in a ready state. - This process does not affect the readiness state of the Component or the Cluster. - - `ClusterReady`: The Action is executed after the Cluster is in a ready state. - This execution does not alter the Component or the Cluster's state of readiness. + It specifies the conditions under which the Action should be retried and the limits to apply, + such as the maximum number of retries and backoff strategy. - This field cannot be updated. - type: string - retryPolicy: - description: |- - Defines the strategy to be taken when retrying the Action after a failure. + This field cannot be updated. + properties: + maxRetries: + default: 0 + description: |- + Defines the maximum number of retry attempts that should be made for a given Action. + This value is set to 0 by default, indicating that no retries will be made. + type: integer + retryInterval: + default: 0 + description: |- + Indicates the duration of time to wait between each retry attempt. + This value is set to 0 by default, indicating that there will be no delay between retry attempts. + format: int64 + type: integer + type: object + targetPodSelector: + description: |- + Defines the criteria used to select the target Pod(s) for executing the Action. + This is useful when there is no default target replica identified. + It allows for precise control over which Pod(s) the Action should run in. - It specifies the conditions under which the Action should be retried and the limits to apply, - such as the maximum number of retries and backoff strategy. + This field cannot be updated. - This field cannot be updated. - properties: - maxRetries: - default: 0 - description: |- - Defines the maximum number of retry attempts that should be made for a given Action. - This value is set to 0 by default, indicating that no retries will be made. - type: integer - retryInterval: + Note: This field is reserved for future use and is not currently active. + enum: + - Any + - All + - Role + - Ordinal + type: string + timeoutSeconds: default: 0 description: |- - Indicates the duration of time to wait between each retry attempt. - This value is set to 0 by default, indicating that there will be no delay between retry attempts. - format: int64 - type: integer - type: object - timeoutSeconds: - default: 0 - description: |- - Specifies the maximum duration in seconds that the Action is allowed to run. + Specifies the maximum duration in seconds that the Action is allowed to run. - If the Action does not complete within this time frame, it will be terminated. + If the Action does not complete within this time frame, it will be terminated. - This field cannot be updated. - format: int32 - type: integer + This field cannot be updated. + format: int32 + type: integer + type: object type: object preTerminate: description: |- @@ -15240,49 +16034,115 @@ spec: until the PreTerminate action has completed successfully. + The container executing this action has access to following environment variables: + + + - KB_CLUSTER_POD_IP_LIST: Comma-separated list of the cluster's pod IP addresses (e.g., "podIp1,podIp2"). + - KB_CLUSTER_POD_NAME_LIST: Comma-separated list of the cluster's pod names (e.g., "pod1,pod2"). + - KB_CLUSTER_POD_HOST_NAME_LIST: Comma-separated list of host names, each corresponding to a pod in + KB_CLUSTER_POD_NAME_LIST (e.g., "hostName1,hostName2"). + - KB_CLUSTER_POD_HOST_IP_LIST: Comma-separated list of host IP addresses, each corresponding to a pod in + KB_CLUSTER_POD_NAME_LIST (e.g., "hostIp1,hostIp2"). + + + - KB_CLUSTER_COMPONENT_POD_NAME_LIST: Comma-separated list of all pod names within the component + (e.g., "pod1,pod2"). + - KB_CLUSTER_COMPONENT_POD_IP_LIST: Comma-separated list of pod IP addresses, + matching the order of pods in KB_CLUSTER_COMPONENT_POD_NAME_LIST (e.g., "podIp1,podIp2"). + - KB_CLUSTER_COMPONENT_POD_HOST_NAME_LIST: Comma-separated list of host names for each pod, + matching the order of pods in KB_CLUSTER_COMPONENT_POD_NAME_LIST (e.g., "hostName1,hostName2"). + - KB_CLUSTER_COMPONENT_POD_HOST_IP_LIST: Comma-separated list of host IP addresses for each pod, + matching the order of pods in KB_CLUSTER_COMPONENT_POD_NAME_LIST (e.g., "hostIp1,hostIp2"). + + + - KB_CLUSTER_COMPONENT_LIST: Comma-separated list of all cluster components (e.g., "comp1,comp2"). + - KB_CLUSTER_COMPONENT_DELETING_LIST: Comma-separated list of components that are currently being deleted + (e.g., "comp1,comp2"). + - KB_CLUSTER_COMPONENT_UNDELETED_LIST: Comma-separated list of components that are not being deleted + (e.g., "comp1,comp2"). + + + - KB_CLUSTER_COMPONENT_IS_SCALING_IN: Indicates whether the component is currently scaling in. + If this variable is present and set to "true", it denotes that the component is undergoing a scale-in operation. + During scale-in, data rebalancing is necessary to maintain cluster integrity. + Contrast this with a cluster deletion scenario where data rebalancing is not required as the entire cluster + is being cleaned up. + + Note: This field is immutable once it has been set. properties: - exec: + builtinHandler: description: |- - Defines the command to run. + Specifies the name of the predefined action handler to be invoked for lifecycle actions. - This field cannot be updated. - properties: - args: - description: Args represents the arguments that are passed - to the `command` for execution. - items: - type: string - type: array - command: - description: |- - Specifies the command to be executed inside the container. - The working directory for this command is the container's root directory('/'). - Commands are executed directly without a shell environment, meaning shell-specific syntax ('|', etc.) is not supported. - If the shell is required, it must be explicitly invoked in the command. + Lorry, as a sidecar agent co-located with the database container in the same Pod, + includes a suite of built-in action implementations that are tailored to different database engines. + These are known as "builtin" handlers, includes: `mysql`, `redis`, `mongodb`, `etcd`, + `postgresql`, `official-postgresql`, `apecloud-postgresql`, `wesql`, `oceanbase`, `polardbx`. - A successful execution is indicated by an exit status of 0; any non-zero status signifies a failure. - items: - type: string - type: array - container: - description: |- - Specifies the name of the container within the same pod whose resources will be shared with the action. - This allows the action to utilize the specified container's resources without executing within it. + If the `builtinHandler` field is specified, it instructs Lorry to utilize its internal built-in action handler + to execute the specified lifecycle actions. - The name must match one of the containers defined in `componentDefinition.spec.runtime`. + The `builtinHandler` field is of type `BuiltinActionHandlerType`, + which represents the name of the built-in handler. + The `builtinHandler` specified within the same `ComponentLifecycleActions` should be consistent across all + actions. + This means that if you specify a built-in handler for one action, you should use the same handler + for all other actions throughout the entire `ComponentLifecycleActions` collection. - The resources that can be shared are included: + If you need to define lifecycle actions for database engines not covered by the existing built-in support, + or when the pre-existing built-in handlers do not meet your specific needs, + you can use the `customHandler` field to define your own action implementation. - - volume mounts + Deprecation Notice: + + + - In the future, the `builtinHandler` field will be deprecated in favor of using the `customHandler` field + for configuring all lifecycle actions. + - Instead of using a name to indicate the built-in action implementations in Lorry, + the recommended approach will be to explicitly invoke the desired action implementation through + a gRPC interface exposed by the sidecar agent. + - Developers will have the flexibility to either use the built-in action implementations provided by Lorry + or develop their own sidecar agent to implement custom actions and expose them via gRPC interfaces. + - This change will allow for greater customization and extensibility of lifecycle actions, + as developers can create their own "builtin" implementations tailored to their specific requirements. + type: string + customHandler: + description: |- + Specifies a user-defined hook or procedure that is called to perform the specific lifecycle action. + It offers a flexible and expandable approach for customizing the behavior of a Component by leveraging + tailored actions. + + + An Action can be implemented as either an ExecAction or an HTTPAction, with future versions planning + to support GRPCAction, + thereby accommodating unique logic for different database systems within the Action's framework. + + + In future iterations, all built-in handlers are expected to transition to GRPCAction. + This change means that Lorry or other sidecar agents will expose the implementation of actions + through a GRPC interface for external invocation. + Then the controller will interact with these actions via GRPCAction calls. + properties: + container: + description: |- + Defines the name of the container within the target Pod where the action will be executed. + + + This name must correspond to one of the containers defined in `componentDefinition.spec.runtime`. + If this field is not specified, the default behavior is to use the first container listed in + `componentDefinition.spec.runtime`. This field cannot be updated. + + + Note: This field is reserved for future use and is not currently active. type: string env: description: |- @@ -15404,13 +16264,101 @@ spec: - name type: object type: array + exec: + description: |- + Defines the command to run. + + + This field cannot be updated. + properties: + args: + description: Args represents the arguments that are + passed to the `command` for execution. + items: + type: string + type: array + command: + description: |- + Specifies the command to be executed inside the container. + The working directory for this command is the container's root directory('/'). + Commands are executed directly without a shell environment, meaning shell-specific syntax ('|', etc.) is not supported. + If the shell is required, it must be explicitly invoked in the command. + + + A successful execution is indicated by an exit status of 0; any non-zero status signifies a failure. + items: + type: string + type: array + type: object + http: + description: |- + Specifies the HTTP request to perform. + + + This field cannot be updated. + + + Note: HTTPAction is to be implemented in future version. + properties: + host: + description: |- + Indicates the server's domain name or IP address. Defaults to the Pod's IP. + Prefer setting the "Host" header in httpHeaders when needed. + type: string + httpHeaders: + description: |- + Allows for the inclusion of custom headers in the request. + HTTP permits the use of repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + method: + description: |- + Represents the type of HTTP request to be made, such as "GET," "POST," "PUT," etc. + If not specified, "GET" is the default method. + type: string + path: + description: Specifies the endpoint to be requested + on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Specifies the target port for the HTTP request. + It can be specified either as a numeric value in the range of 1 to 65535, + or as a named port that meets the IANA_SVC_NAME specification. + x-kubernetes-int-or-string: true + scheme: + description: |- + Designates the protocol used to make the request, such as HTTP or HTTPS. + If not specified, HTTP is used by default. + type: string + required: + - port + type: object image: description: |- Specifies the container image to be used for running the Action. When specified, a dedicated container will be created using this image to execute the Action. - All actions with same image will share the same container. + This field is mutually exclusive with the `container` field; only one of them should be provided. This field cannot be updated. @@ -15427,85 +16375,86 @@ spec: This field cannot be updated. + + + Note: This field is reserved for future use and is not currently active. type: string - targetPodSelector: + preCondition: description: |- - Defines the criteria used to select the target Pod(s) for executing the Action. - This is useful when there is no default target replica identified. - It allows for precise control over which Pod(s) the Action should run in. + Specifies the state that the cluster must reach before the Action is executed. + Currently, this is only applicable to the `postProvision` action. - If not specified, the Action will be executed in the pod where the Action is triggered, such as the pod - to be removed or added; or a random pod if the Action is triggered at the component level, such as - post-provision or pre-terminate of the component. + The conditions are as follows: + + + - `Immediately`: Executed right after the Component object is created. + The readiness of the Component and its resources is not guaranteed at this stage. + - `RuntimeReady`: The Action is triggered after the Component object has been created and all associated + runtime resources (e.g. Pods) are in a ready state. + - `ComponentReady`: The Action is triggered after the Component itself is in a ready state. + This process does not affect the readiness state of the Component or the Cluster. + - `ClusterReady`: The Action is executed after the Cluster is in a ready state. + This execution does not alter the Component or the Cluster's state of readiness. This field cannot be updated. - enum: - - Any - - All - - Role - - Ordinal type: string - type: object - preCondition: - description: |- - Specifies the state that the cluster must reach before the Action is executed. - Currently, this is only applicable to the `postProvision` action. + retryPolicy: + description: |- + Defines the strategy to be taken when retrying the Action after a failure. - The conditions are as follows: - - - - `Immediately`: Executed right after the Component object is created. - The readiness of the Component and its resources is not guaranteed at this stage. - - `RuntimeReady`: The Action is triggered after the Component object has been created and all associated - runtime resources (e.g. Pods) are in a ready state. - - `ComponentReady`: The Action is triggered after the Component itself is in a ready state. - This process does not affect the readiness state of the Component or the Cluster. - - `ClusterReady`: The Action is executed after the Cluster is in a ready state. - This execution does not alter the Component or the Cluster's state of readiness. + It specifies the conditions under which the Action should be retried and the limits to apply, + such as the maximum number of retries and backoff strategy. - This field cannot be updated. - type: string - retryPolicy: - description: |- - Defines the strategy to be taken when retrying the Action after a failure. + This field cannot be updated. + properties: + maxRetries: + default: 0 + description: |- + Defines the maximum number of retry attempts that should be made for a given Action. + This value is set to 0 by default, indicating that no retries will be made. + type: integer + retryInterval: + default: 0 + description: |- + Indicates the duration of time to wait between each retry attempt. + This value is set to 0 by default, indicating that there will be no delay between retry attempts. + format: int64 + type: integer + type: object + targetPodSelector: + description: |- + Defines the criteria used to select the target Pod(s) for executing the Action. + This is useful when there is no default target replica identified. + It allows for precise control over which Pod(s) the Action should run in. - It specifies the conditions under which the Action should be retried and the limits to apply, - such as the maximum number of retries and backoff strategy. + This field cannot be updated. - This field cannot be updated. - properties: - maxRetries: - default: 0 - description: |- - Defines the maximum number of retry attempts that should be made for a given Action. - This value is set to 0 by default, indicating that no retries will be made. - type: integer - retryInterval: + Note: This field is reserved for future use and is not currently active. + enum: + - Any + - All + - Role + - Ordinal + type: string + timeoutSeconds: default: 0 description: |- - Indicates the duration of time to wait between each retry attempt. - This value is set to 0 by default, indicating that there will be no delay between retry attempts. - format: int64 - type: integer - type: object - timeoutSeconds: - default: 0 - description: |- - Specifies the maximum duration in seconds that the Action is allowed to run. + Specifies the maximum duration in seconds that the Action is allowed to run. - If the Action does not complete within this time frame, it will be terminated. + If the Action does not complete within this time frame, it will be terminated. - This field cannot be updated. - format: int32 - type: integer + This field cannot be updated. + format: int32 + type: integer + type: object type: object readonly: description: |- @@ -15520,6 +16469,9 @@ spec: - KB_POD_FQDN: The FQDN of the replica pod whose role is being checked. + - KB_SERVICE_PORT: The port used by the database service. + - KB_SERVICE_USER: The username with the necessary permissions to interact with the database service. + - KB_SERVICE_PASSWORD: The corresponding password for KB_SERVICE_USER to authenticate with the database service. Expected action output: @@ -15528,47 +16480,78 @@ spec: Note: This field is immutable once it has been set. properties: - exec: + builtinHandler: description: |- - Defines the command to run. + Specifies the name of the predefined action handler to be invoked for lifecycle actions. - This field cannot be updated. - properties: - args: - description: Args represents the arguments that are passed - to the `command` for execution. - items: - type: string - type: array - command: - description: |- - Specifies the command to be executed inside the container. - The working directory for this command is the container's root directory('/'). - Commands are executed directly without a shell environment, meaning shell-specific syntax ('|', etc.) is not supported. - If the shell is required, it must be explicitly invoked in the command. + Lorry, as a sidecar agent co-located with the database container in the same Pod, + includes a suite of built-in action implementations that are tailored to different database engines. + These are known as "builtin" handlers, includes: `mysql`, `redis`, `mongodb`, `etcd`, + `postgresql`, `official-postgresql`, `apecloud-postgresql`, `wesql`, `oceanbase`, `polardbx`. - A successful execution is indicated by an exit status of 0; any non-zero status signifies a failure. - items: - type: string - type: array - container: - description: |- - Specifies the name of the container within the same pod whose resources will be shared with the action. - This allows the action to utilize the specified container's resources without executing within it. + If the `builtinHandler` field is specified, it instructs Lorry to utilize its internal built-in action handler + to execute the specified lifecycle actions. - The name must match one of the containers defined in `componentDefinition.spec.runtime`. + The `builtinHandler` field is of type `BuiltinActionHandlerType`, + which represents the name of the built-in handler. + The `builtinHandler` specified within the same `ComponentLifecycleActions` should be consistent across all + actions. + This means that if you specify a built-in handler for one action, you should use the same handler + for all other actions throughout the entire `ComponentLifecycleActions` collection. - The resources that can be shared are included: + If you need to define lifecycle actions for database engines not covered by the existing built-in support, + or when the pre-existing built-in handlers do not meet your specific needs, + you can use the `customHandler` field to define your own action implementation. - - volume mounts + Deprecation Notice: + + + - In the future, the `builtinHandler` field will be deprecated in favor of using the `customHandler` field + for configuring all lifecycle actions. + - Instead of using a name to indicate the built-in action implementations in Lorry, + the recommended approach will be to explicitly invoke the desired action implementation through + a gRPC interface exposed by the sidecar agent. + - Developers will have the flexibility to either use the built-in action implementations provided by Lorry + or develop their own sidecar agent to implement custom actions and expose them via gRPC interfaces. + - This change will allow for greater customization and extensibility of lifecycle actions, + as developers can create their own "builtin" implementations tailored to their specific requirements. + type: string + customHandler: + description: |- + Specifies a user-defined hook or procedure that is called to perform the specific lifecycle action. + It offers a flexible and expandable approach for customizing the behavior of a Component by leveraging + tailored actions. + + + An Action can be implemented as either an ExecAction or an HTTPAction, with future versions planning + to support GRPCAction, + thereby accommodating unique logic for different database systems within the Action's framework. + + + In future iterations, all built-in handlers are expected to transition to GRPCAction. + This change means that Lorry or other sidecar agents will expose the implementation of actions + through a GRPC interface for external invocation. + Then the controller will interact with these actions via GRPCAction calls. + properties: + container: + description: |- + Defines the name of the container within the target Pod where the action will be executed. + + + This name must correspond to one of the containers defined in `componentDefinition.spec.runtime`. + If this field is not specified, the default behavior is to use the first container listed in + `componentDefinition.spec.runtime`. This field cannot be updated. + + + Note: This field is reserved for future use and is not currently active. type: string env: description: |- @@ -15690,13 +16673,101 @@ spec: - name type: object type: array + exec: + description: |- + Defines the command to run. + + + This field cannot be updated. + properties: + args: + description: Args represents the arguments that are + passed to the `command` for execution. + items: + type: string + type: array + command: + description: |- + Specifies the command to be executed inside the container. + The working directory for this command is the container's root directory('/'). + Commands are executed directly without a shell environment, meaning shell-specific syntax ('|', etc.) is not supported. + If the shell is required, it must be explicitly invoked in the command. + + + A successful execution is indicated by an exit status of 0; any non-zero status signifies a failure. + items: + type: string + type: array + type: object + http: + description: |- + Specifies the HTTP request to perform. + + + This field cannot be updated. + + + Note: HTTPAction is to be implemented in future version. + properties: + host: + description: |- + Indicates the server's domain name or IP address. Defaults to the Pod's IP. + Prefer setting the "Host" header in httpHeaders when needed. + type: string + httpHeaders: + description: |- + Allows for the inclusion of custom headers in the request. + HTTP permits the use of repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + method: + description: |- + Represents the type of HTTP request to be made, such as "GET," "POST," "PUT," etc. + If not specified, "GET" is the default method. + type: string + path: + description: Specifies the endpoint to be requested + on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Specifies the target port for the HTTP request. + It can be specified either as a numeric value in the range of 1 to 65535, + or as a named port that meets the IANA_SVC_NAME specification. + x-kubernetes-int-or-string: true + scheme: + description: |- + Designates the protocol used to make the request, such as HTTP or HTTPS. + If not specified, HTTP is used by default. + type: string + required: + - port + type: object image: description: |- Specifies the container image to be used for running the Action. When specified, a dedicated container will be created using this image to execute the Action. - All actions with same image will share the same container. + This field is mutually exclusive with the `container` field; only one of them should be provided. This field cannot be updated. @@ -15713,85 +16784,86 @@ spec: This field cannot be updated. + + + Note: This field is reserved for future use and is not currently active. type: string - targetPodSelector: + preCondition: description: |- - Defines the criteria used to select the target Pod(s) for executing the Action. - This is useful when there is no default target replica identified. - It allows for precise control over which Pod(s) the Action should run in. + Specifies the state that the cluster must reach before the Action is executed. + Currently, this is only applicable to the `postProvision` action. - If not specified, the Action will be executed in the pod where the Action is triggered, such as the pod - to be removed or added; or a random pod if the Action is triggered at the component level, such as - post-provision or pre-terminate of the component. + The conditions are as follows: - This field cannot be updated. - enum: - - Any - - All - - Role - - Ordinal - type: string - type: object - preCondition: - description: |- - Specifies the state that the cluster must reach before the Action is executed. - Currently, this is only applicable to the `postProvision` action. + - `Immediately`: Executed right after the Component object is created. + The readiness of the Component and its resources is not guaranteed at this stage. + - `RuntimeReady`: The Action is triggered after the Component object has been created and all associated + runtime resources (e.g. Pods) are in a ready state. + - `ComponentReady`: The Action is triggered after the Component itself is in a ready state. + This process does not affect the readiness state of the Component or the Cluster. + - `ClusterReady`: The Action is executed after the Cluster is in a ready state. + This execution does not alter the Component or the Cluster's state of readiness. - The conditions are as follows: + This field cannot be updated. + type: string + retryPolicy: + description: |- + Defines the strategy to be taken when retrying the Action after a failure. - - `Immediately`: Executed right after the Component object is created. - The readiness of the Component and its resources is not guaranteed at this stage. - - `RuntimeReady`: The Action is triggered after the Component object has been created and all associated - runtime resources (e.g. Pods) are in a ready state. - - `ComponentReady`: The Action is triggered after the Component itself is in a ready state. - This process does not affect the readiness state of the Component or the Cluster. - - `ClusterReady`: The Action is executed after the Cluster is in a ready state. - This execution does not alter the Component or the Cluster's state of readiness. + It specifies the conditions under which the Action should be retried and the limits to apply, + such as the maximum number of retries and backoff strategy. - This field cannot be updated. - type: string - retryPolicy: - description: |- - Defines the strategy to be taken when retrying the Action after a failure. + This field cannot be updated. + properties: + maxRetries: + default: 0 + description: |- + Defines the maximum number of retry attempts that should be made for a given Action. + This value is set to 0 by default, indicating that no retries will be made. + type: integer + retryInterval: + default: 0 + description: |- + Indicates the duration of time to wait between each retry attempt. + This value is set to 0 by default, indicating that there will be no delay between retry attempts. + format: int64 + type: integer + type: object + targetPodSelector: + description: |- + Defines the criteria used to select the target Pod(s) for executing the Action. + This is useful when there is no default target replica identified. + It allows for precise control over which Pod(s) the Action should run in. - It specifies the conditions under which the Action should be retried and the limits to apply, - such as the maximum number of retries and backoff strategy. + This field cannot be updated. - This field cannot be updated. - properties: - maxRetries: - default: 0 - description: |- - Defines the maximum number of retry attempts that should be made for a given Action. - This value is set to 0 by default, indicating that no retries will be made. - type: integer - retryInterval: + Note: This field is reserved for future use and is not currently active. + enum: + - Any + - All + - Role + - Ordinal + type: string + timeoutSeconds: default: 0 description: |- - Indicates the duration of time to wait between each retry attempt. - This value is set to 0 by default, indicating that there will be no delay between retry attempts. - format: int64 - type: integer - type: object - timeoutSeconds: - default: 0 - description: |- - Specifies the maximum duration in seconds that the Action is allowed to run. + Specifies the maximum duration in seconds that the Action is allowed to run. - If the Action does not complete within this time frame, it will be terminated. + If the Action does not complete within this time frame, it will be terminated. - This field cannot be updated. - format: int32 - type: integer + This field cannot be updated. + format: int32 + type: integer + type: object type: object readwrite: description: |- @@ -15808,6 +16880,9 @@ spec: - KB_POD_FQDN: The FQDN of the replica pod whose role is being checked. + - KB_SERVICE_PORT: The port used by the database service. + - KB_SERVICE_USER: The username with the necessary permissions to interact with the database service. + - KB_SERVICE_PASSWORD: The corresponding password for KB_SERVICE_USER to authenticate with the database service. Expected action output: @@ -15816,47 +16891,78 @@ spec: Note: This field is immutable once it has been set. properties: - exec: + builtinHandler: description: |- - Defines the command to run. + Specifies the name of the predefined action handler to be invoked for lifecycle actions. - This field cannot be updated. - properties: - args: - description: Args represents the arguments that are passed - to the `command` for execution. - items: - type: string - type: array - command: - description: |- - Specifies the command to be executed inside the container. - The working directory for this command is the container's root directory('/'). - Commands are executed directly without a shell environment, meaning shell-specific syntax ('|', etc.) is not supported. - If the shell is required, it must be explicitly invoked in the command. + Lorry, as a sidecar agent co-located with the database container in the same Pod, + includes a suite of built-in action implementations that are tailored to different database engines. + These are known as "builtin" handlers, includes: `mysql`, `redis`, `mongodb`, `etcd`, + `postgresql`, `official-postgresql`, `apecloud-postgresql`, `wesql`, `oceanbase`, `polardbx`. - A successful execution is indicated by an exit status of 0; any non-zero status signifies a failure. - items: - type: string - type: array - container: - description: |- - Specifies the name of the container within the same pod whose resources will be shared with the action. - This allows the action to utilize the specified container's resources without executing within it. + If the `builtinHandler` field is specified, it instructs Lorry to utilize its internal built-in action handler + to execute the specified lifecycle actions. - The name must match one of the containers defined in `componentDefinition.spec.runtime`. + The `builtinHandler` field is of type `BuiltinActionHandlerType`, + which represents the name of the built-in handler. + The `builtinHandler` specified within the same `ComponentLifecycleActions` should be consistent across all + actions. + This means that if you specify a built-in handler for one action, you should use the same handler + for all other actions throughout the entire `ComponentLifecycleActions` collection. - The resources that can be shared are included: + If you need to define lifecycle actions for database engines not covered by the existing built-in support, + or when the pre-existing built-in handlers do not meet your specific needs, + you can use the `customHandler` field to define your own action implementation. - - volume mounts + Deprecation Notice: + + + - In the future, the `builtinHandler` field will be deprecated in favor of using the `customHandler` field + for configuring all lifecycle actions. + - Instead of using a name to indicate the built-in action implementations in Lorry, + the recommended approach will be to explicitly invoke the desired action implementation through + a gRPC interface exposed by the sidecar agent. + - Developers will have the flexibility to either use the built-in action implementations provided by Lorry + or develop their own sidecar agent to implement custom actions and expose them via gRPC interfaces. + - This change will allow for greater customization and extensibility of lifecycle actions, + as developers can create their own "builtin" implementations tailored to their specific requirements. + type: string + customHandler: + description: |- + Specifies a user-defined hook or procedure that is called to perform the specific lifecycle action. + It offers a flexible and expandable approach for customizing the behavior of a Component by leveraging + tailored actions. + + + An Action can be implemented as either an ExecAction or an HTTPAction, with future versions planning + to support GRPCAction, + thereby accommodating unique logic for different database systems within the Action's framework. + + + In future iterations, all built-in handlers are expected to transition to GRPCAction. + This change means that Lorry or other sidecar agents will expose the implementation of actions + through a GRPC interface for external invocation. + Then the controller will interact with these actions via GRPCAction calls. + properties: + container: + description: |- + Defines the name of the container within the target Pod where the action will be executed. + + + This name must correspond to one of the containers defined in `componentDefinition.spec.runtime`. + If this field is not specified, the default behavior is to use the first container listed in + `componentDefinition.spec.runtime`. This field cannot be updated. + + + Note: This field is reserved for future use and is not currently active. type: string env: description: |- @@ -15978,13 +17084,101 @@ spec: - name type: object type: array + exec: + description: |- + Defines the command to run. + + + This field cannot be updated. + properties: + args: + description: Args represents the arguments that are + passed to the `command` for execution. + items: + type: string + type: array + command: + description: |- + Specifies the command to be executed inside the container. + The working directory for this command is the container's root directory('/'). + Commands are executed directly without a shell environment, meaning shell-specific syntax ('|', etc.) is not supported. + If the shell is required, it must be explicitly invoked in the command. + + + A successful execution is indicated by an exit status of 0; any non-zero status signifies a failure. + items: + type: string + type: array + type: object + http: + description: |- + Specifies the HTTP request to perform. + + + This field cannot be updated. + + + Note: HTTPAction is to be implemented in future version. + properties: + host: + description: |- + Indicates the server's domain name or IP address. Defaults to the Pod's IP. + Prefer setting the "Host" header in httpHeaders when needed. + type: string + httpHeaders: + description: |- + Allows for the inclusion of custom headers in the request. + HTTP permits the use of repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + method: + description: |- + Represents the type of HTTP request to be made, such as "GET," "POST," "PUT," etc. + If not specified, "GET" is the default method. + type: string + path: + description: Specifies the endpoint to be requested + on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Specifies the target port for the HTTP request. + It can be specified either as a numeric value in the range of 1 to 65535, + or as a named port that meets the IANA_SVC_NAME specification. + x-kubernetes-int-or-string: true + scheme: + description: |- + Designates the protocol used to make the request, such as HTTP or HTTPS. + If not specified, HTTP is used by default. + type: string + required: + - port + type: object image: description: |- Specifies the container image to be used for running the Action. When specified, a dedicated container will be created using this image to execute the Action. - All actions with same image will share the same container. + This field is mutually exclusive with the `container` field; only one of them should be provided. This field cannot be updated. @@ -16000,8 +17194,57 @@ spec: will be selected for the Action. + This field cannot be updated. + + + Note: This field is reserved for future use and is not currently active. + type: string + preCondition: + description: |- + Specifies the state that the cluster must reach before the Action is executed. + Currently, this is only applicable to the `postProvision` action. + + + The conditions are as follows: + + + - `Immediately`: Executed right after the Component object is created. + The readiness of the Component and its resources is not guaranteed at this stage. + - `RuntimeReady`: The Action is triggered after the Component object has been created and all associated + runtime resources (e.g. Pods) are in a ready state. + - `ComponentReady`: The Action is triggered after the Component itself is in a ready state. + This process does not affect the readiness state of the Component or the Cluster. + - `ClusterReady`: The Action is executed after the Cluster is in a ready state. + This execution does not alter the Component or the Cluster's state of readiness. + + This field cannot be updated. type: string + retryPolicy: + description: |- + Defines the strategy to be taken when retrying the Action after a failure. + + + It specifies the conditions under which the Action should be retried and the limits to apply, + such as the maximum number of retries and backoff strategy. + + + This field cannot be updated. + properties: + maxRetries: + default: 0 + description: |- + Defines the maximum number of retry attempts that should be made for a given Action. + This value is set to 0 by default, indicating that no retries will be made. + type: integer + retryInterval: + default: 0 + description: |- + Indicates the duration of time to wait between each retry attempt. + This value is set to 0 by default, indicating that there will be no delay between retry attempts. + format: int64 + type: integer + type: object targetPodSelector: description: |- Defines the criteria used to select the target Pod(s) for executing the Action. @@ -16009,129 +17252,112 @@ spec: It allows for precise control over which Pod(s) the Action should run in. - If not specified, the Action will be executed in the pod where the Action is triggered, such as the pod - to be removed or added; or a random pod if the Action is triggered at the component level, such as - post-provision or pre-terminate of the component. + This field cannot be updated. - This field cannot be updated. + Note: This field is reserved for future use and is not currently active. enum: - Any - All - Role - Ordinal type: string - type: object - preCondition: - description: |- - Specifies the state that the cluster must reach before the Action is executed. - Currently, this is only applicable to the `postProvision` action. + timeoutSeconds: + default: 0 + description: |- + Specifies the maximum duration in seconds that the Action is allowed to run. - The conditions are as follows: + If the Action does not complete within this time frame, it will be terminated. - - `Immediately`: Executed right after the Component object is created. - The readiness of the Component and its resources is not guaranteed at this stage. - - `RuntimeReady`: The Action is triggered after the Component object has been created and all associated - runtime resources (e.g. Pods) are in a ready state. - - `ComponentReady`: The Action is triggered after the Component itself is in a ready state. - This process does not affect the readiness state of the Component or the Cluster. - - `ClusterReady`: The Action is executed after the Cluster is in a ready state. - This execution does not alter the Component or the Cluster's state of readiness. + This field cannot be updated. + format: int32 + type: integer + type: object + type: object + reconfigure: + description: |- + Defines the procedure that update a replica with new configuration. - This field cannot be updated. - type: string - retryPolicy: + Note: This field is immutable once it has been set. + + + This Action is reserved for future versions. + properties: + builtinHandler: description: |- - Defines the strategy to be taken when retrying the Action after a failure. + Specifies the name of the predefined action handler to be invoked for lifecycle actions. - It specifies the conditions under which the Action should be retried and the limits to apply, - such as the maximum number of retries and backoff strategy. + Lorry, as a sidecar agent co-located with the database container in the same Pod, + includes a suite of built-in action implementations that are tailored to different database engines. + These are known as "builtin" handlers, includes: `mysql`, `redis`, `mongodb`, `etcd`, + `postgresql`, `official-postgresql`, `apecloud-postgresql`, `wesql`, `oceanbase`, `polardbx`. - This field cannot be updated. - properties: - maxRetries: - default: 0 - description: |- - Defines the maximum number of retry attempts that should be made for a given Action. - This value is set to 0 by default, indicating that no retries will be made. - type: integer - retryInterval: - default: 0 - description: |- - Indicates the duration of time to wait between each retry attempt. - This value is set to 0 by default, indicating that there will be no delay between retry attempts. - format: int64 - type: integer - type: object - timeoutSeconds: - default: 0 - description: |- - Specifies the maximum duration in seconds that the Action is allowed to run. + If the `builtinHandler` field is specified, it instructs Lorry to utilize its internal built-in action handler + to execute the specified lifecycle actions. - If the Action does not complete within this time frame, it will be terminated. + The `builtinHandler` field is of type `BuiltinActionHandlerType`, + which represents the name of the built-in handler. + The `builtinHandler` specified within the same `ComponentLifecycleActions` should be consistent across all + actions. + This means that if you specify a built-in handler for one action, you should use the same handler + for all other actions throughout the entire `ComponentLifecycleActions` collection. - This field cannot be updated. - format: int32 - type: integer - type: object - reconfigure: - description: |- - Defines the procedure that update a replica with new configuration. + If you need to define lifecycle actions for database engines not covered by the existing built-in support, + or when the pre-existing built-in handlers do not meet your specific needs, + you can use the `customHandler` field to define your own action implementation. - Note: This field is immutable once it has been set. + Deprecation Notice: - This Action is reserved for future versions. - properties: - exec: + - In the future, the `builtinHandler` field will be deprecated in favor of using the `customHandler` field + for configuring all lifecycle actions. + - Instead of using a name to indicate the built-in action implementations in Lorry, + the recommended approach will be to explicitly invoke the desired action implementation through + a gRPC interface exposed by the sidecar agent. + - Developers will have the flexibility to either use the built-in action implementations provided by Lorry + or develop their own sidecar agent to implement custom actions and expose them via gRPC interfaces. + - This change will allow for greater customization and extensibility of lifecycle actions, + as developers can create their own "builtin" implementations tailored to their specific requirements. + type: string + customHandler: description: |- - Defines the command to run. + Specifies a user-defined hook or procedure that is called to perform the specific lifecycle action. + It offers a flexible and expandable approach for customizing the behavior of a Component by leveraging + tailored actions. - This field cannot be updated. - properties: - args: - description: Args represents the arguments that are passed - to the `command` for execution. - items: - type: string - type: array - command: - description: |- - Specifies the command to be executed inside the container. - The working directory for this command is the container's root directory('/'). - Commands are executed directly without a shell environment, meaning shell-specific syntax ('|', etc.) is not supported. - If the shell is required, it must be explicitly invoked in the command. + An Action can be implemented as either an ExecAction or an HTTPAction, with future versions planning + to support GRPCAction, + thereby accommodating unique logic for different database systems within the Action's framework. - A successful execution is indicated by an exit status of 0; any non-zero status signifies a failure. - items: - type: string - type: array + In future iterations, all built-in handlers are expected to transition to GRPCAction. + This change means that Lorry or other sidecar agents will expose the implementation of actions + through a GRPC interface for external invocation. + Then the controller will interact with these actions via GRPCAction calls. + properties: container: description: |- - Specifies the name of the container within the same pod whose resources will be shared with the action. - This allows the action to utilize the specified container's resources without executing within it. - - - The name must match one of the containers defined in `componentDefinition.spec.runtime`. + Defines the name of the container within the target Pod where the action will be executed. - The resources that can be shared are included: + This name must correspond to one of the containers defined in `componentDefinition.spec.runtime`. + If this field is not specified, the default behavior is to use the first container listed in + `componentDefinition.spec.runtime`. - - volume mounts + This field cannot be updated. - This field cannot be updated. + Note: This field is reserved for future use and is not currently active. type: string env: description: |- @@ -16253,13 +17479,101 @@ spec: - name type: object type: array + exec: + description: |- + Defines the command to run. + + + This field cannot be updated. + properties: + args: + description: Args represents the arguments that are + passed to the `command` for execution. + items: + type: string + type: array + command: + description: |- + Specifies the command to be executed inside the container. + The working directory for this command is the container's root directory('/'). + Commands are executed directly without a shell environment, meaning shell-specific syntax ('|', etc.) is not supported. + If the shell is required, it must be explicitly invoked in the command. + + + A successful execution is indicated by an exit status of 0; any non-zero status signifies a failure. + items: + type: string + type: array + type: object + http: + description: |- + Specifies the HTTP request to perform. + + + This field cannot be updated. + + + Note: HTTPAction is to be implemented in future version. + properties: + host: + description: |- + Indicates the server's domain name or IP address. Defaults to the Pod's IP. + Prefer setting the "Host" header in httpHeaders when needed. + type: string + httpHeaders: + description: |- + Allows for the inclusion of custom headers in the request. + HTTP permits the use of repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + method: + description: |- + Represents the type of HTTP request to be made, such as "GET," "POST," "PUT," etc. + If not specified, "GET" is the default method. + type: string + path: + description: Specifies the endpoint to be requested + on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Specifies the target port for the HTTP request. + It can be specified either as a numeric value in the range of 1 to 65535, + or as a named port that meets the IANA_SVC_NAME specification. + x-kubernetes-int-or-string: true + scheme: + description: |- + Designates the protocol used to make the request, such as HTTP or HTTPS. + If not specified, HTTP is used by default. + type: string + required: + - port + type: object image: description: |- Specifies the container image to be used for running the Action. When specified, a dedicated container will be created using this image to execute the Action. - All actions with same image will share the same container. + This field is mutually exclusive with the `container` field; only one of them should be provided. This field cannot be updated. @@ -16276,92 +17590,93 @@ spec: This field cannot be updated. + + + Note: This field is reserved for future use and is not currently active. type: string - targetPodSelector: + preCondition: description: |- - Defines the criteria used to select the target Pod(s) for executing the Action. - This is useful when there is no default target replica identified. - It allows for precise control over which Pod(s) the Action should run in. + Specifies the state that the cluster must reach before the Action is executed. + Currently, this is only applicable to the `postProvision` action. - If not specified, the Action will be executed in the pod where the Action is triggered, such as the pod - to be removed or added; or a random pod if the Action is triggered at the component level, such as - post-provision or pre-terminate of the component. + The conditions are as follows: + + + - `Immediately`: Executed right after the Component object is created. + The readiness of the Component and its resources is not guaranteed at this stage. + - `RuntimeReady`: The Action is triggered after the Component object has been created and all associated + runtime resources (e.g. Pods) are in a ready state. + - `ComponentReady`: The Action is triggered after the Component itself is in a ready state. + This process does not affect the readiness state of the Component or the Cluster. + - `ClusterReady`: The Action is executed after the Cluster is in a ready state. + This execution does not alter the Component or the Cluster's state of readiness. This field cannot be updated. - enum: - - Any - - All - - Role - - Ordinal type: string - type: object - preCondition: - description: |- - Specifies the state that the cluster must reach before the Action is executed. - Currently, this is only applicable to the `postProvision` action. - - - The conditions are as follows: + retryPolicy: + description: |- + Defines the strategy to be taken when retrying the Action after a failure. - - `Immediately`: Executed right after the Component object is created. - The readiness of the Component and its resources is not guaranteed at this stage. - - `RuntimeReady`: The Action is triggered after the Component object has been created and all associated - runtime resources (e.g. Pods) are in a ready state. - - `ComponentReady`: The Action is triggered after the Component itself is in a ready state. - This process does not affect the readiness state of the Component or the Cluster. - - `ClusterReady`: The Action is executed after the Cluster is in a ready state. - This execution does not alter the Component or the Cluster's state of readiness. + It specifies the conditions under which the Action should be retried and the limits to apply, + such as the maximum number of retries and backoff strategy. - This field cannot be updated. - type: string - retryPolicy: - description: |- - Defines the strategy to be taken when retrying the Action after a failure. + This field cannot be updated. + properties: + maxRetries: + default: 0 + description: |- + Defines the maximum number of retry attempts that should be made for a given Action. + This value is set to 0 by default, indicating that no retries will be made. + type: integer + retryInterval: + default: 0 + description: |- + Indicates the duration of time to wait between each retry attempt. + This value is set to 0 by default, indicating that there will be no delay between retry attempts. + format: int64 + type: integer + type: object + targetPodSelector: + description: |- + Defines the criteria used to select the target Pod(s) for executing the Action. + This is useful when there is no default target replica identified. + It allows for precise control over which Pod(s) the Action should run in. - It specifies the conditions under which the Action should be retried and the limits to apply, - such as the maximum number of retries and backoff strategy. + This field cannot be updated. - This field cannot be updated. - properties: - maxRetries: - default: 0 - description: |- - Defines the maximum number of retry attempts that should be made for a given Action. - This value is set to 0 by default, indicating that no retries will be made. - type: integer - retryInterval: + Note: This field is reserved for future use and is not currently active. + enum: + - Any + - All + - Role + - Ordinal + type: string + timeoutSeconds: default: 0 description: |- - Indicates the duration of time to wait between each retry attempt. - This value is set to 0 by default, indicating that there will be no delay between retry attempts. - format: int64 - type: integer - type: object - timeoutSeconds: - default: 0 - description: |- - Specifies the maximum duration in seconds that the Action is allowed to run. + Specifies the maximum duration in seconds that the Action is allowed to run. - If the Action does not complete within this time frame, it will be terminated. + If the Action does not complete within this time frame, it will be terminated. - This field cannot be updated. - format: int32 - type: integer + This field cannot be updated. + format: int32 + type: integer + type: object type: object roleProbe: description: |- Defines the procedure which is invoked regularly to assess the role of replicas. - This action is periodically triggered at the specified interval to determine the role of each replica. + This action is periodically triggered by Lorry at the specified interval to determine the role of each replica. Upon successful execution, the action's output designates the role of the replica, which should match one of the predefined role names within `componentDefinition.spec.roles`. The output is then compared with the previous successful execution result. @@ -16374,10 +17689,13 @@ spec: Without this, services that rely on roleSelectors might improperly direct traffic to wrong replicas. - The container executing this action has access to following variables: + The container executing this action has access to following environment variables: - KB_POD_FQDN: The FQDN of the Pod whose role is being assessed. + - KB_SERVICE_PORT: The port used by the database service. + - KB_SERVICE_USER: The username with the necessary permissions to interact with the database service. + - KB_SERVICE_PASSWORD: The corresponding password for KB_SERVICE_USER to authenticate with the database service. Expected output of this action: @@ -16388,47 +17706,78 @@ spec: Note: This field is immutable once it has been set. properties: - exec: + builtinHandler: description: |- - Defines the command to run. + Specifies the name of the predefined action handler to be invoked for lifecycle actions. - This field cannot be updated. - properties: - args: - description: Args represents the arguments that are passed - to the `command` for execution. - items: - type: string - type: array - command: - description: |- - Specifies the command to be executed inside the container. - The working directory for this command is the container's root directory('/'). - Commands are executed directly without a shell environment, meaning shell-specific syntax ('|', etc.) is not supported. - If the shell is required, it must be explicitly invoked in the command. + Lorry, as a sidecar agent co-located with the database container in the same Pod, + includes a suite of built-in action implementations that are tailored to different database engines. + These are known as "builtin" handlers, includes: `mysql`, `redis`, `mongodb`, `etcd`, + `postgresql`, `official-postgresql`, `apecloud-postgresql`, `wesql`, `oceanbase`, `polardbx`. - A successful execution is indicated by an exit status of 0; any non-zero status signifies a failure. - items: - type: string - type: array - container: - description: |- - Specifies the name of the container within the same pod whose resources will be shared with the action. - This allows the action to utilize the specified container's resources without executing within it. + If the `builtinHandler` field is specified, it instructs Lorry to utilize its internal built-in action handler + to execute the specified lifecycle actions. - The name must match one of the containers defined in `componentDefinition.spec.runtime`. + The `builtinHandler` field is of type `BuiltinActionHandlerType`, + which represents the name of the built-in handler. + The `builtinHandler` specified within the same `ComponentLifecycleActions` should be consistent across all + actions. + This means that if you specify a built-in handler for one action, you should use the same handler + for all other actions throughout the entire `ComponentLifecycleActions` collection. - The resources that can be shared are included: + If you need to define lifecycle actions for database engines not covered by the existing built-in support, + or when the pre-existing built-in handlers do not meet your specific needs, + you can use the `customHandler` field to define your own action implementation. - - volume mounts + Deprecation Notice: + + + - In the future, the `builtinHandler` field will be deprecated in favor of using the `customHandler` field + for configuring all lifecycle actions. + - Instead of using a name to indicate the built-in action implementations in Lorry, + the recommended approach will be to explicitly invoke the desired action implementation through + a gRPC interface exposed by the sidecar agent. + - Developers will have the flexibility to either use the built-in action implementations provided by Lorry + or develop their own sidecar agent to implement custom actions and expose them via gRPC interfaces. + - This change will allow for greater customization and extensibility of lifecycle actions, + as developers can create their own "builtin" implementations tailored to their specific requirements. + type: string + customHandler: + description: |- + Specifies a user-defined hook or procedure that is called to perform the specific lifecycle action. + It offers a flexible and expandable approach for customizing the behavior of a Component by leveraging + tailored actions. + + + An Action can be implemented as either an ExecAction or an HTTPAction, with future versions planning + to support GRPCAction, + thereby accommodating unique logic for different database systems within the Action's framework. + + + In future iterations, all built-in handlers are expected to transition to GRPCAction. + This change means that Lorry or other sidecar agents will expose the implementation of actions + through a GRPC interface for external invocation. + Then the controller will interact with these actions via GRPCAction calls. + properties: + container: + description: |- + Defines the name of the container within the target Pod where the action will be executed. + + + This name must correspond to one of the containers defined in `componentDefinition.spec.runtime`. + If this field is not specified, the default behavior is to use the first container listed in + `componentDefinition.spec.runtime`. This field cannot be updated. + + + Note: This field is reserved for future use and is not currently active. type: string env: description: |- @@ -16550,13 +17899,101 @@ spec: - name type: object type: array + exec: + description: |- + Defines the command to run. + + + This field cannot be updated. + properties: + args: + description: Args represents the arguments that are + passed to the `command` for execution. + items: + type: string + type: array + command: + description: |- + Specifies the command to be executed inside the container. + The working directory for this command is the container's root directory('/'). + Commands are executed directly without a shell environment, meaning shell-specific syntax ('|', etc.) is not supported. + If the shell is required, it must be explicitly invoked in the command. + + + A successful execution is indicated by an exit status of 0; any non-zero status signifies a failure. + items: + type: string + type: array + type: object + http: + description: |- + Specifies the HTTP request to perform. + + + This field cannot be updated. + + + Note: HTTPAction is to be implemented in future version. + properties: + host: + description: |- + Indicates the server's domain name or IP address. Defaults to the Pod's IP. + Prefer setting the "Host" header in httpHeaders when needed. + type: string + httpHeaders: + description: |- + Allows for the inclusion of custom headers in the request. + HTTP permits the use of repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + method: + description: |- + Represents the type of HTTP request to be made, such as "GET," "POST," "PUT," etc. + If not specified, "GET" is the default method. + type: string + path: + description: Specifies the endpoint to be requested + on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Specifies the target port for the HTTP request. + It can be specified either as a numeric value in the range of 1 to 65535, + or as a named port that meets the IANA_SVC_NAME specification. + x-kubernetes-int-or-string: true + scheme: + description: |- + Designates the protocol used to make the request, such as HTTP or HTTPS. + If not specified, HTTP is used by default. + type: string + required: + - port + type: object image: description: |- Specifies the container image to be used for running the Action. When specified, a dedicated container will be created using this image to execute the Action. - All actions with same image will share the same container. + This field is mutually exclusive with the `container` field; only one of them should be provided. This field cannot be updated. @@ -16572,8 +18009,57 @@ spec: will be selected for the Action. + This field cannot be updated. + + + Note: This field is reserved for future use and is not currently active. + type: string + preCondition: + description: |- + Specifies the state that the cluster must reach before the Action is executed. + Currently, this is only applicable to the `postProvision` action. + + + The conditions are as follows: + + + - `Immediately`: Executed right after the Component object is created. + The readiness of the Component and its resources is not guaranteed at this stage. + - `RuntimeReady`: The Action is triggered after the Component object has been created and all associated + runtime resources (e.g. Pods) are in a ready state. + - `ComponentReady`: The Action is triggered after the Component itself is in a ready state. + This process does not affect the readiness state of the Component or the Cluster. + - `ClusterReady`: The Action is executed after the Cluster is in a ready state. + This execution does not alter the Component or the Cluster's state of readiness. + + This field cannot be updated. type: string + retryPolicy: + description: |- + Defines the strategy to be taken when retrying the Action after a failure. + + + It specifies the conditions under which the Action should be retried and the limits to apply, + such as the maximum number of retries and backoff strategy. + + + This field cannot be updated. + properties: + maxRetries: + default: 0 + description: |- + Defines the maximum number of retry attempts that should be made for a given Action. + This value is set to 0 by default, indicating that no retries will be made. + type: integer + retryInterval: + default: 0 + description: |- + Indicates the duration of time to wait between each retry attempt. + This value is set to 0 by default, indicating that there will be no delay between retry attempts. + format: int64 + type: integer + type: object targetPodSelector: description: |- Defines the criteria used to select the target Pod(s) for executing the Action. @@ -16581,25 +18067,29 @@ spec: It allows for precise control over which Pod(s) the Action should run in. - If not specified, the Action will be executed in the pod where the Action is triggered, such as the pod - to be removed or added; or a random pod if the Action is triggered at the component level, such as - post-provision or pre-terminate of the component. + This field cannot be updated. - This field cannot be updated. + Note: This field is reserved for future use and is not currently active. enum: - Any - All - Role - Ordinal type: string + timeoutSeconds: + default: 0 + description: |- + Specifies the maximum duration in seconds that the Action is allowed to run. + + + If the Action does not complete within this time frame, it will be terminated. + + + This field cannot be updated. + format: int32 + type: integer type: object - failureThreshold: - description: |- - Minimum consecutive failures for the probe to be considered failed after having succeeded. - Defaults to 3. Minimum value is 1. - format: int32 - type: integer initialDelaySeconds: description: |- Specifies the number of seconds to wait after the container has started before the RoleProbe @@ -16612,129 +18102,410 @@ spec: Default to 10 seconds. Minimum value is 1. format: int32 type: integer - preCondition: + timeoutSeconds: description: |- - Specifies the state that the cluster must reach before the Action is executed. - Currently, this is only applicable to the `postProvision` action. + Specifies the number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + format: int32 + type: integer + type: object + switchover: + description: |- + Defines the procedure for a controlled transition of leadership from the current leader to a new replica. + This approach aims to minimize downtime and maintain availability in systems with a leader-follower topology, + during events such as planned maintenance or when performing stop, shutdown, restart, or upgrade operations + involving the current leader node. - The conditions are as follows: + The container executing this action has access to following environment variables: - - `Immediately`: Executed right after the Component object is created. - The readiness of the Component and its resources is not guaranteed at this stage. - - `RuntimeReady`: The Action is triggered after the Component object has been created and all associated - runtime resources (e.g. Pods) are in a ready state. - - `ComponentReady`: The Action is triggered after the Component itself is in a ready state. - This process does not affect the readiness state of the Component or the Cluster. - - `ClusterReady`: The Action is executed after the Cluster is in a ready state. - This execution does not alter the Component or the Cluster's state of readiness. + - KB_SWITCHOVER_CANDIDATE_NAME: The name of the pod for the new leader candidate, which may not be specified (empty). + - KB_SWITCHOVER_CANDIDATE_FQDN: The FQDN of the new leader candidate's pod, which may not be specified (empty). + - KB_LEADER_POD_IP: The IP address of the current leader's pod prior to the switchover. + - KB_LEADER_POD_NAME: The name of the current leader's pod prior to the switchover. + - KB_LEADER_POD_FQDN: The FQDN of the current leader's pod prior to the switchover. - This field cannot be updated. - type: string - retryPolicy: - description: |- - Defines the strategy to be taken when retrying the Action after a failure. + The environment variables with the following prefixes are deprecated and will be removed in future releases: - It specifies the conditions under which the Action should be retried and the limits to apply, - such as the maximum number of retries and backoff strategy. + - KB_REPLICATION_PRIMARY_POD_ + - KB_CONSENSUS_LEADER_POD_ - This field cannot be updated. + Note: This field is immutable once it has been set. + properties: + scriptSpecSelectors: + description: |- + Used to define the selectors for the scriptSpecs that need to be referenced. + If this field is set, the scripts defined under the 'scripts' field can be invoked or referenced within an Action. + + + This field is deprecated from v0.9. + This field is maintained for backward compatibility and its use is discouraged. + Existing usage should be updated to the current preferred approach to avoid compatibility issues in future releases. + items: + properties: + name: + description: Represents the name of the ScriptSpec referent. + maxLength: 63 + pattern: ^[a-z0-9]([a-z0-9\.\-]*[a-z0-9])?$ + type: string + required: + - name + type: object + type: array + withCandidate: + description: |- + Represents the switchover process for a specified candidate primary or leader instance. + Note that only Action.Exec is currently supported, while Action.HTTP is not. properties: - maxRetries: - default: 0 + container: description: |- - Defines the maximum number of retry attempts that should be made for a given Action. - This value is set to 0 by default, indicating that no retries will be made. - type: integer - retryInterval: - default: 0 + Defines the name of the container within the target Pod where the action will be executed. + + + This name must correspond to one of the containers defined in `componentDefinition.spec.runtime`. + If this field is not specified, the default behavior is to use the first container listed in + `componentDefinition.spec.runtime`. + + + This field cannot be updated. + + + Note: This field is reserved for future use and is not currently active. + type: string + env: description: |- - Indicates the duration of time to wait between each retry attempt. - This value is set to 0 by default, indicating that there will be no delay between retry attempts. - format: int64 - type: integer - type: object - successThreshold: - description: |- - Minimum consecutive successes for the probe to be considered successful after having failed. - Defaults to 1. Minimum value is 1. - format: int32 - type: integer - timeoutSeconds: - default: 0 - description: |- - Specifies the maximum duration in seconds that the Action is allowed to run. + Represents a list of environment variables that will be injected into the container. + These variables enable the container to adapt its behavior based on the environment it's running in. - If the Action does not complete within this time frame, it will be terminated. + This field cannot be updated. + items: + description: EnvVar represents an environment variable + present in a Container. + properties: + name: + description: Name of the environment variable. Must + be a C_IDENTIFIER. + type: string + value: + description: |- + Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in the container and + any service environment variables. If a variable cannot be resolved, + the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless of whether the variable + exists or not. + Defaults to "". + type: string + valueFrom: + description: Source for the environment variable's + value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select + in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required for + volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format + of the exposed resources, defaults to + "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in the + pod's namespace + properties: + key: + description: The key of the secret to select + from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + exec: + description: |- + Defines the command to run. - This field cannot be updated. - format: int32 - type: integer - type: object - switchover: - description: |- - Defines the procedure for a controlled transition of leadership from the current leader to a new replica. - This approach aims to minimize downtime and maintain availability in systems with a leader-follower topology, - during events such as planned maintenance or when performing stop, shutdown, restart, or upgrade operations - involving the current leader node. + This field cannot be updated. + properties: + args: + description: Args represents the arguments that are + passed to the `command` for execution. + items: + type: string + type: array + command: + description: |- + Specifies the command to be executed inside the container. + The working directory for this command is the container's root directory('/'). + Commands are executed directly without a shell environment, meaning shell-specific syntax ('|', etc.) is not supported. + If the shell is required, it must be explicitly invoked in the command. - The container executing this action has access to following variables: + A successful execution is indicated by an exit status of 0; any non-zero status signifies a failure. + items: + type: string + type: array + type: object + http: + description: |- + Specifies the HTTP request to perform. - - KB_SWITCHOVER_CANDIDATE_NAME: The name of the pod for the new leader candidate, which may not be specified (empty). - - KB_SWITCHOVER_CANDIDATE_FQDN: The FQDN of the new leader candidate's pod, which may not be specified (empty). + This field cannot be updated. - Note: This field is immutable once it has been set. - properties: - exec: - description: |- - Defines the command to run. + Note: HTTPAction is to be implemented in future version. + properties: + host: + description: |- + Indicates the server's domain name or IP address. Defaults to the Pod's IP. + Prefer setting the "Host" header in httpHeaders when needed. + type: string + httpHeaders: + description: |- + Allows for the inclusion of custom headers in the request. + HTTP permits the use of repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + method: + description: |- + Represents the type of HTTP request to be made, such as "GET," "POST," "PUT," etc. + If not specified, "GET" is the default method. + type: string + path: + description: Specifies the endpoint to be requested + on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Specifies the target port for the HTTP request. + It can be specified either as a numeric value in the range of 1 to 65535, + or as a named port that meets the IANA_SVC_NAME specification. + x-kubernetes-int-or-string: true + scheme: + description: |- + Designates the protocol used to make the request, such as HTTP or HTTPS. + If not specified, HTTP is used by default. + type: string + required: + - port + type: object + image: + description: |- + Specifies the container image to be used for running the Action. - This field cannot be updated. - properties: - args: - description: Args represents the arguments that are passed - to the `command` for execution. - items: - type: string - type: array - command: + When specified, a dedicated container will be created using this image to execute the Action. + This field is mutually exclusive with the `container` field; only one of them should be provided. + + + This field cannot be updated. + type: string + matchingKey: + description: |- + Used in conjunction with the `targetPodSelector` field to refine the selection of target pod(s) for Action execution. + The impact of this field depends on the `targetPodSelector` value: + + + - When `targetPodSelector` is set to `Any` or `All`, this field will be ignored. + - When `targetPodSelector` is set to `Role`, only those replicas whose role matches the `matchingKey` + will be selected for the Action. + + + This field cannot be updated. + + + Note: This field is reserved for future use and is not currently active. + type: string + preCondition: + description: |- + Specifies the state that the cluster must reach before the Action is executed. + Currently, this is only applicable to the `postProvision` action. + + + The conditions are as follows: + + + - `Immediately`: Executed right after the Component object is created. + The readiness of the Component and its resources is not guaranteed at this stage. + - `RuntimeReady`: The Action is triggered after the Component object has been created and all associated + runtime resources (e.g. Pods) are in a ready state. + - `ComponentReady`: The Action is triggered after the Component itself is in a ready state. + This process does not affect the readiness state of the Component or the Cluster. + - `ClusterReady`: The Action is executed after the Cluster is in a ready state. + This execution does not alter the Component or the Cluster's state of readiness. + + + This field cannot be updated. + type: string + retryPolicy: + description: |- + Defines the strategy to be taken when retrying the Action after a failure. + + + It specifies the conditions under which the Action should be retried and the limits to apply, + such as the maximum number of retries and backoff strategy. + + + This field cannot be updated. + properties: + maxRetries: + default: 0 + description: |- + Defines the maximum number of retry attempts that should be made for a given Action. + This value is set to 0 by default, indicating that no retries will be made. + type: integer + retryInterval: + default: 0 + description: |- + Indicates the duration of time to wait between each retry attempt. + This value is set to 0 by default, indicating that there will be no delay between retry attempts. + format: int64 + type: integer + type: object + targetPodSelector: + description: |- + Defines the criteria used to select the target Pod(s) for executing the Action. + This is useful when there is no default target replica identified. + It allows for precise control over which Pod(s) the Action should run in. + + + This field cannot be updated. + + + Note: This field is reserved for future use and is not currently active. + enum: + - Any + - All + - Role + - Ordinal + type: string + timeoutSeconds: + default: 0 description: |- - Specifies the command to be executed inside the container. - The working directory for this command is the container's root directory('/'). - Commands are executed directly without a shell environment, meaning shell-specific syntax ('|', etc.) is not supported. - If the shell is required, it must be explicitly invoked in the command. + Specifies the maximum duration in seconds that the Action is allowed to run. - A successful execution is indicated by an exit status of 0; any non-zero status signifies a failure. - items: - type: string - type: array - container: - description: |- - Specifies the name of the container within the same pod whose resources will be shared with the action. - This allows the action to utilize the specified container's resources without executing within it. + If the Action does not complete within this time frame, it will be terminated. - The name must match one of the containers defined in `componentDefinition.spec.runtime`. + This field cannot be updated. + format: int32 + type: integer + type: object + withoutCandidate: + description: |- + Represents a switchover process that does not involve a specific candidate primary or leader instance. + As with the previous field, only Action.Exec is currently supported, not Action.HTTP. + properties: + container: + description: |- + Defines the name of the container within the target Pod where the action will be executed. - The resources that can be shared are included: + This name must correspond to one of the containers defined in `componentDefinition.spec.runtime`. + If this field is not specified, the default behavior is to use the first container listed in + `componentDefinition.spec.runtime`. - - volume mounts + This field cannot be updated. - This field cannot be updated. + Note: This field is reserved for future use and is not currently active. type: string env: description: |- @@ -16856,13 +18627,101 @@ spec: - name type: object type: array + exec: + description: |- + Defines the command to run. + + + This field cannot be updated. + properties: + args: + description: Args represents the arguments that are + passed to the `command` for execution. + items: + type: string + type: array + command: + description: |- + Specifies the command to be executed inside the container. + The working directory for this command is the container's root directory('/'). + Commands are executed directly without a shell environment, meaning shell-specific syntax ('|', etc.) is not supported. + If the shell is required, it must be explicitly invoked in the command. + + + A successful execution is indicated by an exit status of 0; any non-zero status signifies a failure. + items: + type: string + type: array + type: object + http: + description: |- + Specifies the HTTP request to perform. + + + This field cannot be updated. + + + Note: HTTPAction is to be implemented in future version. + properties: + host: + description: |- + Indicates the server's domain name or IP address. Defaults to the Pod's IP. + Prefer setting the "Host" header in httpHeaders when needed. + type: string + httpHeaders: + description: |- + Allows for the inclusion of custom headers in the request. + HTTP permits the use of repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + method: + description: |- + Represents the type of HTTP request to be made, such as "GET," "POST," "PUT," etc. + If not specified, "GET" is the default method. + type: string + path: + description: Specifies the endpoint to be requested + on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Specifies the target port for the HTTP request. + It can be specified either as a numeric value in the range of 1 to 65535, + or as a named port that meets the IANA_SVC_NAME specification. + x-kubernetes-int-or-string: true + scheme: + description: |- + Designates the protocol used to make the request, such as HTTP or HTTPS. + If not specified, HTTP is used by default. + type: string + required: + - port + type: object image: description: |- Specifies the container image to be used for running the Action. When specified, a dedicated container will be created using this image to execute the Action. - All actions with same image will share the same container. + This field is mutually exclusive with the `container` field; only one of them should be provided. This field cannot be updated. @@ -16879,85 +18738,86 @@ spec: This field cannot be updated. + + + Note: This field is reserved for future use and is not currently active. type: string - targetPodSelector: + preCondition: description: |- - Defines the criteria used to select the target Pod(s) for executing the Action. - This is useful when there is no default target replica identified. - It allows for precise control over which Pod(s) the Action should run in. + Specifies the state that the cluster must reach before the Action is executed. + Currently, this is only applicable to the `postProvision` action. - If not specified, the Action will be executed in the pod where the Action is triggered, such as the pod - to be removed or added; or a random pod if the Action is triggered at the component level, such as - post-provision or pre-terminate of the component. + The conditions are as follows: - This field cannot be updated. - enum: - - Any - - All - - Role - - Ordinal - type: string - type: object - preCondition: - description: |- - Specifies the state that the cluster must reach before the Action is executed. - Currently, this is only applicable to the `postProvision` action. + - `Immediately`: Executed right after the Component object is created. + The readiness of the Component and its resources is not guaranteed at this stage. + - `RuntimeReady`: The Action is triggered after the Component object has been created and all associated + runtime resources (e.g. Pods) are in a ready state. + - `ComponentReady`: The Action is triggered after the Component itself is in a ready state. + This process does not affect the readiness state of the Component or the Cluster. + - `ClusterReady`: The Action is executed after the Cluster is in a ready state. + This execution does not alter the Component or the Cluster's state of readiness. - The conditions are as follows: + This field cannot be updated. + type: string + retryPolicy: + description: |- + Defines the strategy to be taken when retrying the Action after a failure. - - `Immediately`: Executed right after the Component object is created. - The readiness of the Component and its resources is not guaranteed at this stage. - - `RuntimeReady`: The Action is triggered after the Component object has been created and all associated - runtime resources (e.g. Pods) are in a ready state. - - `ComponentReady`: The Action is triggered after the Component itself is in a ready state. - This process does not affect the readiness state of the Component or the Cluster. - - `ClusterReady`: The Action is executed after the Cluster is in a ready state. - This execution does not alter the Component or the Cluster's state of readiness. + It specifies the conditions under which the Action should be retried and the limits to apply, + such as the maximum number of retries and backoff strategy. - This field cannot be updated. - type: string - retryPolicy: - description: |- - Defines the strategy to be taken when retrying the Action after a failure. + This field cannot be updated. + properties: + maxRetries: + default: 0 + description: |- + Defines the maximum number of retry attempts that should be made for a given Action. + This value is set to 0 by default, indicating that no retries will be made. + type: integer + retryInterval: + default: 0 + description: |- + Indicates the duration of time to wait between each retry attempt. + This value is set to 0 by default, indicating that there will be no delay between retry attempts. + format: int64 + type: integer + type: object + targetPodSelector: + description: |- + Defines the criteria used to select the target Pod(s) for executing the Action. + This is useful when there is no default target replica identified. + It allows for precise control over which Pod(s) the Action should run in. - It specifies the conditions under which the Action should be retried and the limits to apply, - such as the maximum number of retries and backoff strategy. + This field cannot be updated. - This field cannot be updated. - properties: - maxRetries: - default: 0 - description: |- - Defines the maximum number of retry attempts that should be made for a given Action. - This value is set to 0 by default, indicating that no retries will be made. - type: integer - retryInterval: + Note: This field is reserved for future use and is not currently active. + enum: + - Any + - All + - Role + - Ordinal + type: string + timeoutSeconds: default: 0 description: |- - Indicates the duration of time to wait between each retry attempt. - This value is set to 0 by default, indicating that there will be no delay between retry attempts. - format: int64 - type: integer - type: object - timeoutSeconds: - default: 0 - description: |- - Specifies the maximum duration in seconds that the Action is allowed to run. + Specifies the maximum duration in seconds that the Action is allowed to run. - If the Action does not complete within this time frame, it will be terminated. + If the Action does not complete within this time frame, it will be terminated. - This field cannot be updated. - format: int32 - type: integer + This field cannot be updated. + format: int32 + type: integer + type: object type: object type: object logConfigs: @@ -17027,6 +18887,40 @@ spec: format: int32 minimum: 0 type: integer + monitor: + description: |- + Deprecated since v0.9 + monitor is monitoring config which provided by provider. + properties: + builtIn: + default: false + description: |- + builtIn is a switch to enable KubeBlocks builtIn monitoring. + If BuiltIn is set to true, monitor metrics will be scraped automatically. + If BuiltIn is set to false, the provider should set ExporterConfig and Sidecar container own. + type: boolean + exporterConfig: + description: |- + exporterConfig provided by provider, which specify necessary information to Time Series Database. + exporterConfig is valid when builtIn is false. + properties: + scrapePath: + default: /metrics + description: scrapePath is exporter url path for Time Series + Database to scrape metrics. + maxLength: 128 + type: string + scrapePort: + anyOf: + - type: integer + - type: string + description: scrapePort is exporter port for Time Series Database + to scrape metrics. + x-kubernetes-int-or-string: true + required: + - scrapePort + type: object + type: object podManagementPolicy: description: |- InstanceSet controls the creation of pods during initial scale up, replacement of pods on nodes, and scaling down. @@ -17144,6 +19038,19 @@ spec: - message: the minimum replicas limit should be no greater than the maximum rule: self.minReplicas <= self.maxReplicas + roleArbitrator: + default: External + description: |- + This field has been deprecated since v0.9. + This field is maintained for backward compatibility and its use is discouraged. + Existing usage should be updated to the current preferred approach to avoid compatibility issues in future releases. + + + This field is immutable. + enum: + - External + - Lorry + type: string roles: description: |- Enumerate all possible roles assigned to each replica of the Component, influencing its behavior. @@ -25572,29 +27479,6 @@ spec: description: Source for the variable's value. Cannot be used if value is not empty. properties: - clusterVarRef: - description: Selects a defined var of a Cluster. - properties: - clusterName: - description: Reference to the name of the Cluster object. - enum: - - Required - - Optional - type: string - clusterUID: - description: Reference to the UID of the Cluster object. - enum: - - Required - - Optional - type: string - namespace: - description: Reference to the namespace of the Cluster - object. - enum: - - Required - - Optional - type: string - type: object componentVarRef: description: Selects a defined var of a Component. properties: @@ -25610,6 +27494,14 @@ spec: - Required - Optional type: string + instanceNames: + description: |- + Reference to the pod name list of the component. + and the value will be presented in the following format: name1,name2,... + enum: + - Required + - Optional + type: string multipleClusterObjectOption: description: |- This option defines the behavior when multiple component objects match the specified @CompDef. @@ -25674,57 +27566,12 @@ spec: - Required - Optional type: string - podFQDNsForRole: - description: |- - Reference to the pod FQDN list of the component that have a specific role. - The value will be presented in the following format: FQDN1,FQDN2,... - properties: - option: - description: VarOption defines whether a variable - is required or optional. - enum: - - Required - - Optional - type: string - role: - type: string - type: object - podNames: - description: |- - Reference to the pod name list of the component. - and the value will be presented in the following format: name1,name2,... - enum: - - Required - - Optional - type: string - podNamesForRole: - description: |- - Reference to the pod name list of the component that have a specific role. - The value will be presented in the following format: name1,name2,... - properties: - option: - description: VarOption defines whether a variable - is required or optional. - enum: - - Required - - Optional - type: string - role: - type: string - type: object replicas: description: Reference to the replicas of the component. enum: - Required - Optional type: string - shortName: - description: Reference to the short name of the Component - object. - enum: - - Required - - Optional - type: string type: object configMapKeyRef: description: Selects a key of a ConfigMap. @@ -26133,13 +27980,6 @@ spec: - Optional type: string type: object - serviceType: - description: ServiceType references the type of the - service. - enum: - - Required - - Optional - type: string type: object type: object required: diff --git a/deploy/helm/crds/apps.kubeblocks.io_clusterdefinitions.yaml b/deploy/helm/crds/apps.kubeblocks.io_clusterdefinitions.yaml index 133edfc7b7d..7bfc5b8b7ef 100644 --- a/deploy/helm/crds/apps.kubeblocks.io_clusterdefinitions.yaml +++ b/deploy/helm/crds/apps.kubeblocks.io_clusterdefinitions.yaml @@ -255,6 +255,9876 @@ spec: spec: description: ClusterDefinitionSpec defines the desired state of ClusterDefinition. properties: + componentDefs: + description: |- + Provides the definitions for the cluster components. + + + Deprecated since v0.9. + Components should now be individually defined using ComponentDefinition and + collectively referenced via `topology.components`. + This field is maintained for backward compatibility and its use is discouraged. + Existing usage should be updated to the current preferred approach to avoid compatibility issues in future releases. + items: + description: |- + ClusterComponentDefinition defines a Component within a ClusterDefinition but is deprecated and + has been replaced by ComponentDefinition. + + + Deprecated: Use ComponentDefinition instead. This type is deprecated as of version 0.8. + properties: + characterType: + description: Defines well-known database component name, such + as mongos(mongodb), proxy(redis), mariadb(mysql). + type: string + componentDefRef: + description: |- + Used to inject values from other components into the current component. Values will be saved and updated in a + configmap and mounted to the current component. + items: + description: |- + ComponentDefRef is used to select the component and its fields to be referenced. + + + Deprecated since v0.8. + properties: + componentDefName: + description: The name of the componentDef to be selected. + type: string + componentRefEnv: + description: The values that are to be injected as environment + variables into each component. + items: + description: |- + ComponentRefEnv specifies name and value of an env. + + + Deprecated since v0.8. + properties: + name: + description: The name of the env, it must be a C + identifier. + pattern: ^[A-Za-z_][A-Za-z0-9_]*$ + type: string + value: + description: The value of the env. + type: string + valueFrom: + description: The source from which the value of + the env. + properties: + fieldPath: + description: |- + The jsonpath of the source to select when the Type is `FieldRef`. + Two objects are registered in the jsonpath: `componentDef` and `components`: + + + - `componentDef` is the component definition object specified in `componentRef.componentDefName`. + - `components` are the component list objects referring to the component definition object. + type: string + format: + default: ="$POD_FQDN" + description: |- + Defines the format of each headless service address. + Three builtin variables can be used as placeholders: `$POD_ORDINAL`, `$POD_FQDN`, `$POD_NAME` + + + - `$POD_ORDINAL` represents the ordinal of the pod. + - `$POD_FQDN` represents the fully qualified domain name of the pod. + - `$POD_NAME` represents the name of the pod. + type: string + joinWith: + default: ',' + description: The string used to join the values + of headless service addresses. + type: string + type: + allOf: + - enum: + - FieldRef + - ServiceRef + - HeadlessServiceRef + - enum: + - FieldRef + - ServiceRef + - HeadlessServiceRef + description: 'Specifies the source to select. + It can be one of three types: `FieldRef`, + `ServiceRef`, `HeadlessServiceRef`.' + type: string + required: + - type + type: object + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + failurePolicy: + allOf: + - enum: + - Ignore + - Fail + - enum: + - Ignore + - Fail + description: Defines the policy to be followed in case + of a failure in finding the component. + type: string + required: + - componentDefName + type: object + type: array + x-kubernetes-list-map-keys: + - componentDefName + x-kubernetes-list-type: map + configSpecs: + description: Defines the template of configurations. + items: + properties: + asEnvFrom: + description: |- + Specifies the containers to inject the ConfigMap parameters as environment variables. + + + This is useful when application images accept parameters through environment variables and + generate the final configuration file in the startup script based on these variables. + + + This field allows users to specify a list of container names, and KubeBlocks will inject the environment + variables converted from the ConfigMap into these designated containers. This provides a flexible way to + pass the configuration items from the ConfigMap to the container without modifying the image. + + + Deprecated: `asEnvFrom` has been deprecated since 0.9.0 and will be removed in 0.10.0. + Use `injectEnvTo` instead. + items: + type: string + type: array + x-kubernetes-list-type: set + constraintRef: + description: Specifies the name of the referenced configuration + constraints object. + maxLength: 63 + pattern: ^[a-z0-9]([a-z0-9\.\-]*[a-z0-9])?$ + type: string + defaultMode: + description: |- + The operator attempts to set default file permissions for scripts (0555) and configurations (0444). + However, certain database engines may require different file permissions. + You can specify the desired file permissions here. + + + Must be specified as an octal value between 0000 and 0777 (inclusive), + or as a decimal value between 0 and 511 (inclusive). + YAML supports both octal and decimal values for file permissions. + + + Please note that this setting only affects the permissions of the files themselves. + Directories within the specified path are not impacted by this setting. + It's important to be aware that this setting might conflict with other options + that influence the file mode, such as fsGroup. + In such cases, the resulting file mode may have additional bits set. + Refers to documents of k8s.ConfigMapVolumeSource.defaultMode for more information. + format: int32 + type: integer + injectEnvTo: + description: |- + Specifies the containers to inject the ConfigMap parameters as environment variables. + + + This is useful when application images accept parameters through environment variables and + generate the final configuration file in the startup script based on these variables. + + + This field allows users to specify a list of container names, and KubeBlocks will inject the environment + variables converted from the ConfigMap into these designated containers. This provides a flexible way to + pass the configuration items from the ConfigMap to the container without modifying the image. + items: + type: string + type: array + x-kubernetes-list-type: set + keys: + description: |- + Specifies the configuration files within the ConfigMap that support dynamic updates. + + + A configuration template (provided in the form of a ConfigMap) may contain templates for multiple + configuration files. + Each configuration file corresponds to a key in the ConfigMap. + Some of these configuration files may support dynamic modification and reloading without requiring + a pod restart. + + + If empty or omitted, all configuration files in the ConfigMap are assumed to support dynamic updates, + and ConfigConstraint applies to all keys. + items: + type: string + type: array + x-kubernetes-list-type: set + legacyRenderedConfigSpec: + description: |- + Specifies the secondary rendered config spec for pod-specific customization. + + + The template is rendered inside the pod (by the "config-manager" sidecar container) and merged with the main + template's render result to generate the final configuration file. + + + This field is intended to handle scenarios where different pods within the same Component have + varying configurations. It allows for pod-specific customization of the configuration. + + + Note: This field will be deprecated in future versions, and the functionality will be moved to + `cluster.spec.componentSpecs[*].instances[*]`. + properties: + namespace: + default: default + description: |- + Specifies the namespace of the referenced configuration template ConfigMap object. + An empty namespace is equivalent to the "default" namespace. + pattern: ^[a-z0-9]([a-z0-9\-]*[a-z0-9])?$ + type: string + policy: + default: none + description: Defines the strategy for merging externally + imported templates into component templates. + enum: + - patch + - replace + - none + type: string + templateRef: + description: Specifies the name of the referenced + configuration template ConfigMap object. + pattern: ^[a-z0-9]([a-z0-9\.\-]*[a-z0-9])?$ + type: string + required: + - templateRef + type: object + name: + description: Specifies the name of the configuration template. + maxLength: 63 + pattern: ^[a-z0-9]([a-z0-9\.\-]*[a-z0-9])?$ + type: string + namespace: + default: default + description: |- + Specifies the namespace of the referenced configuration template ConfigMap object. + An empty namespace is equivalent to the "default" namespace. + maxLength: 63 + pattern: ^[a-z0-9]([a-z0-9\-]*[a-z0-9])?$ + type: string + reRenderResourceTypes: + description: |- + Specifies whether the configuration needs to be re-rendered after v-scale or h-scale operations to reflect changes. + + + In some scenarios, the configuration may need to be updated to reflect the changes in resource allocation + or cluster topology. Examples: + + + - Redis: adjust maxmemory after v-scale operation. + - MySQL: increase max connections after v-scale operation. + - Zookeeper: update zoo.cfg with new node addresses after h-scale operation. + items: + description: RerenderResourceType defines the resource + requirements for a component. + enum: + - vscale + - hscale + - tls + type: string + type: array + x-kubernetes-list-type: set + templateRef: + description: Specifies the name of the referenced configuration + template ConfigMap object. + maxLength: 63 + pattern: ^[a-z0-9]([a-z0-9\.\-]*[a-z0-9])?$ + type: string + volumeName: + description: |- + Refers to the volume name of PodTemplate. The configuration file produced through the configuration + template will be mounted to the corresponding volume. Must be a DNS_LABEL name. + The volume name must be defined in podSpec.containers[*].volumeMounts. + maxLength: 63 + pattern: ^[a-z]([a-z0-9\-]*[a-z0-9])?$ + type: string + required: + - name + - volumeName + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + consensusSpec: + description: Defines spec for `Consensus` workloads. It's required + if the workload type is `Consensus`. + properties: + followers: + description: Members of the consensus set that have voting + rights but are not the leader. + items: + description: ConsensusMember is deprecated since v0.7. + properties: + accessMode: + default: ReadWrite + description: Specifies the services that this member + is capable of providing. + enum: + - None + - Readonly + - ReadWrite + type: string + name: + default: leader + description: Specifies the name of the consensus member. + type: string + replicas: + default: 0 + description: |- + Indicates the number of Pods that perform this role. + The default is 1 for `Leader`, 0 for `Learner`, others for `Followers`. + format: int32 + minimum: 0 + type: integer + required: + - accessMode + - name + type: object + type: array + leader: + description: Represents a single leader in the consensus + set. + properties: + accessMode: + default: ReadWrite + description: Specifies the services that this member + is capable of providing. + enum: + - None + - Readonly + - ReadWrite + type: string + name: + default: leader + description: Specifies the name of the consensus member. + type: string + replicas: + default: 0 + description: |- + Indicates the number of Pods that perform this role. + The default is 1 for `Leader`, 0 for `Learner`, others for `Followers`. + format: int32 + minimum: 0 + type: integer + required: + - accessMode + - name + type: object + learner: + description: Represents a member of the consensus set that + does not have voting rights. + properties: + accessMode: + default: ReadWrite + description: Specifies the services that this member + is capable of providing. + enum: + - None + - Readonly + - ReadWrite + type: string + name: + default: leader + description: Specifies the name of the consensus member. + type: string + replicas: + default: 0 + description: |- + Indicates the number of Pods that perform this role. + The default is 1 for `Leader`, 0 for `Learner`, others for `Followers`. + format: int32 + minimum: 0 + type: integer + required: + - accessMode + - name + type: object + llPodManagementPolicy: + description: |- + Controls the creation of pods during initial scale up, replacement of pods on nodes, and scaling down. + + + - `OrderedReady`: Creates pods in increasing order (pod-0, then pod-1, etc). The controller waits until each pod + is ready before continuing. Pods are removed in reverse order when scaling down. + - `Parallel`: Creates pods in parallel to match the desired scale without waiting. All pods are deleted at once + when scaling down. + type: string + llUpdateStrategy: + description: |- + Specifies the low-level StatefulSetUpdateStrategy to be used when updating Pods in the StatefulSet upon a + revision to the Template. + `UpdateStrategy` will be ignored if this is provided. + properties: + rollingUpdate: + description: RollingUpdate is used to communicate parameters + when Type is RollingUpdateStatefulSetStrategyType. + properties: + maxUnavailable: + anyOf: + - type: integer + - type: string + description: |- + The maximum number of pods that can be unavailable during the update. + Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). + Absolute number is calculated from percentage by rounding up. This can not be 0. + Defaults to 1. This field is alpha-level and is only honored by servers that enable the + MaxUnavailableStatefulSet feature. The field applies to all pods in the range 0 to + Replicas-1. That means if there is any unavailable pod in the range 0 to Replicas-1, it + will be counted towards MaxUnavailable. + x-kubernetes-int-or-string: true + partition: + description: |- + Partition indicates the ordinal at which the StatefulSet should be partitioned + for updates. During a rolling update, all pods from ordinal Replicas-1 to + Partition are updated. All pods from ordinal Partition-1 to 0 remain untouched. + This is helpful in being able to do a canary based deployment. The default value is 0. + format: int32 + type: integer + type: object + type: + description: |- + Type indicates the type of the StatefulSetUpdateStrategy. + Default is RollingUpdate. + type: string + type: object + updateStrategy: + default: Serial + description: |- + Specifies the strategy for updating Pods. + For workloadType=`Consensus`, the update strategy can be one of the following: + + + - `Serial`: Updates Members sequentially to minimize component downtime. + - `BestEffortParallel`: Updates Members in parallel to minimize component write downtime. Majority remains online + at all times. + - `Parallel`: Forces parallel updates. + enum: + - Serial + - BestEffortParallel + - Parallel + type: string + required: + - leader + type: object + customLabelSpecs: + description: Used for custom label tags which you want to add + to the component resources. + items: + description: CustomLabelSpec is deprecated since v0.8. + properties: + key: + description: The key of the label. + type: string + resources: + description: The resources that will be patched with the + label. + items: + description: GVKResource is deprecated since v0.8. + properties: + gvk: + description: |- + Represents the GVK of a resource, such as "v1/Pod", "apps/v1/StatefulSet", etc. + When a resource matching this is found by the selector, a custom label will be added if it doesn't already exist, + or updated if it does. + type: string + selector: + additionalProperties: + type: string + description: A label query used to filter a set + of resources. + type: object + required: + - gvk + type: object + type: array + value: + description: The value of the label. + type: string + required: + - key + - value + type: object + type: array + x-kubernetes-list-map-keys: + - key + x-kubernetes-list-type: map + description: + description: Description of the component definition. + type: string + exporter: + description: Defines the metrics exporter. + properties: + containerName: + description: Specifies the name of the built-in metrics + exporter container. + type: string + scrapePath: + description: |- + Specifies the http/https url path to scrape for metrics. + If empty, Prometheus uses the default value (e.g. `/metrics`). + type: string + scrapePort: + description: Specifies the port name to scrape for metrics. + type: string + scrapeScheme: + description: |- + Specifies the schema to use for scraping. + `http` and `https` are the expected values unless you rewrite the `__scheme__` label via relabeling. + If empty, Prometheus uses the default value `http`. + enum: + - http + - https + type: string + type: object + horizontalScalePolicy: + description: Defines the behavior of horizontal scale. + properties: + backupPolicyTemplateName: + description: Refers to the backup policy template. + type: string + type: + default: None + description: |- + Determines the data synchronization method when a component scales out. + The policy can be one of the following: {None, CloneVolume}. The default policy is `None`. + + + - `None`: This is the default policy. It creates an empty volume without data cloning. + - `CloneVolume`: This policy clones data to newly scaled pods. It first tries to use a volume snapshot. + If volume snapshot is not enabled, it will attempt to use a backup tool. If neither method works, it will report an error. + - `Snapshot`: This policy is deprecated and is an alias for CloneVolume. + enum: + - None + - CloneVolume + - Snapshot + type: string + volumeMountsName: + description: |- + Specifies the volumeMount of the container to backup. + This only works if Type is not None. If not specified, the first volumeMount will be selected. + type: string + type: object + logConfigs: + description: Specify the logging files which can be observed + and configured by cluster users. + items: + properties: + filePathPattern: + description: |- + Specifies the paths or patterns identifying where the log files are stored. + This field allows the system to locate and manage log files effectively. + + + Examples: + + + - /home/postgres/pgdata/pgroot/data/log/postgresql-* + - /data/mysql/log/mysqld-error.log + maxLength: 4096 + type: string + name: + description: |- + Specifies a descriptive label for the log type, such as 'slow' for a MySQL slow log file. + It provides a clear identification of the log's purpose and content. + maxLength: 128 + type: string + required: + - filePathPattern + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + monitor: + description: |- + Deprecated since v0.9 + monitor is monitoring config which provided by provider. + properties: + builtIn: + default: false + description: |- + builtIn is a switch to enable KubeBlocks builtIn monitoring. + If BuiltIn is set to true, monitor metrics will be scraped automatically. + If BuiltIn is set to false, the provider should set ExporterConfig and Sidecar container own. + type: boolean + exporterConfig: + description: |- + exporterConfig provided by provider, which specify necessary information to Time Series Database. + exporterConfig is valid when builtIn is false. + properties: + scrapePath: + default: /metrics + description: scrapePath is exporter url path for Time + Series Database to scrape metrics. + maxLength: 128 + type: string + scrapePort: + anyOf: + - type: integer + - type: string + description: scrapePort is exporter port for Time Series + Database to scrape metrics. + x-kubernetes-int-or-string: true + required: + - scrapePort + type: object + type: object + name: + description: |- + This name could be used as default name of `cluster.spec.componentSpecs.name`, and needs to conform with same + validation rules as `cluster.spec.componentSpecs.name`, currently complying with IANA Service Naming rule. + This name will apply to cluster objects as the value of label "apps.kubeblocks.io/component-name". + maxLength: 22 + pattern: ^[a-z]([a-z0-9\-]*[a-z0-9])?$ + type: string + podSpec: + description: Defines the pod spec template of component. + properties: + activeDeadlineSeconds: + description: |- + Optional duration in seconds the pod may be active on the node relative to + StartTime before the system will actively try to mark it failed and kill associated containers. + Value must be a positive integer. + format: int64 + type: integer + affinity: + description: If specified, the pod's scheduling constraints + properties: + nodeAffinity: + description: Describes node affinity scheduling rules + for the pod. + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node matches the corresponding matchExpressions; the + node(s) with the highest sum are the most preferred. + items: + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). + properties: + preference: + description: A node selector term, associated + with the corresponding weight. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that + the selector applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that + the selector applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + weight: + description: Weight associated with matching + the corresponding nodeSelectorTerm, in the + range 1-100. + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. + properties: + nodeSelectorTerms: + description: Required. A list of node selector + terms. The terms are ORed. + items: + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that + the selector applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that + the selector applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + type: array + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + description: Describes pod affinity scheduling rules + (e.g. co-locate this pod in the same node, zone, etc. + as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched + WeightedPodAffinityTerm fields are added per-node + to find the most preferred node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, + associated with the corresponding weight. + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a + list of label selector requirements. + The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. + Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a + list of label selector requirements. + The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: |- + weight associated with matching the corresponding podAffinityTerm, + in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. + items: + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. + Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + description: Describes pod anti-affinity scheduling + rules (e.g. avoid putting this pod in the same node, + zone, etc. as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the anti-affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched + WeightedPodAffinityTerm fields are added per-node + to find the most preferred node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, + associated with the corresponding weight. + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a + list of label selector requirements. + The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. + Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a + list of label selector requirements. + The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: |- + weight associated with matching the corresponding podAffinityTerm, + in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the anti-affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the anti-affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. + items: + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. + Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + automountServiceAccountToken: + description: AutomountServiceAccountToken indicates whether + a service account token should be automatically mounted. + type: boolean + containers: + description: |- + List of containers belonging to the pod. + Containers cannot currently be added or removed. + There must be at least one container in a Pod. + Cannot be updated. + items: + description: A single application container that you want + to run within a pod. + properties: + args: + description: |- + Arguments to the entrypoint. + The container image's CMD is used if this is not provided. + Variable references $(VAR_NAME) are expanded using the container's environment. If a variable + cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will + produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless + of whether the variable exists or not. Cannot be updated. + More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell + items: + type: string + type: array + command: + description: |- + Entrypoint array. Not executed within a shell. + The container image's ENTRYPOINT is used if this is not provided. + Variable references $(VAR_NAME) are expanded using the container's environment. If a variable + cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will + produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless + of whether the variable exists or not. Cannot be updated. + More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell + items: + type: string + type: array + env: + description: |- + List of environment variables to set in the container. + Cannot be updated. + items: + description: EnvVar represents an environment variable + present in a Container. + properties: + name: + description: Name of the environment variable. + Must be a C_IDENTIFIER. + type: string + value: + description: |- + Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in the container and + any service environment variables. If a variable cannot be resolved, + the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless of whether the variable + exists or not. + Defaults to "". + type: string + valueFrom: + description: Source for the environment variable's + value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the + FieldPath is written in terms of, + defaults to "v1". + type: string + fieldPath: + description: Path of the field to select + in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required + for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format + of the exposed resources, defaults + to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to + select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in + the pod's namespace + properties: + key: + description: The key of the secret to + select from. Must be a valid secret + key. + type: string + 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 + optional: + description: Specify whether the Secret + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + envFrom: + description: |- + List of sources to populate environment variables in the container. + The keys defined within a source must be a C_IDENTIFIER. All invalid keys + will be reported as an event when the container is starting. When a key exists in multiple + sources, the value associated with the last source will take precedence. + Values defined by an Env with a duplicate key will take precedence. + Cannot be updated. + items: + description: EnvFromSource represents the source + of a set of ConfigMaps + properties: + configMapRef: + description: The ConfigMap to select from + 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 + optional: + description: Specify whether the ConfigMap + must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + description: An optional identifier to prepend + to each key in the ConfigMap. Must be a C_IDENTIFIER. + type: string + secretRef: + description: The Secret to select from + 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 + optional: + description: Specify whether the Secret + must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + image: + description: |- + Container image name. + More info: https://kubernetes.io/docs/concepts/containers/images + This field is optional to allow higher level config management to default or override + container images in workload controllers like Deployments and StatefulSets. + type: string + imagePullPolicy: + description: |- + Image pull policy. + One of Always, Never, IfNotPresent. + Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/containers/images#updating-images + type: string + lifecycle: + description: |- + Actions that the management system should take in response to container lifecycle events. + Cannot be updated. + properties: + postStart: + description: |- + PostStart is called immediately after a container is created. If the handler fails, + the container is terminated and restarted according to its restart policy. + Other management of the container blocks until the hook completes. + More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks + properties: + exec: + description: Exec specifies the action to + take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in + the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a + custom header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP + server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + sleep: + description: Sleep represents the duration + that the container should sleep before being + terminated. + properties: + seconds: + description: Seconds is the number of + seconds to sleep. + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + description: |- + Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept + for the backward compatibility. There are no validation of this field and + lifecycle hooks will fail in runtime when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + description: |- + PreStop is called immediately before a container is terminated due to an + API request or management event such as liveness/startup probe failure, + preemption, resource contention, etc. The handler is not called if the + container crashes or exits. The Pod's termination grace period countdown begins before the + PreStop hook is executed. Regardless of the outcome of the handler, the + container will eventually terminate within the Pod's termination grace + period (unless delayed by finalizers). Other management of the container blocks until the hook completes + or until the termination grace period is reached. + More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks + properties: + exec: + description: Exec specifies the action to + take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in + the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a + custom header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP + server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + sleep: + description: Sleep represents the duration + that the container should sleep before being + terminated. + properties: + seconds: + description: Seconds is the number of + seconds to sleep. + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + description: |- + Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept + for the backward compatibility. There are no validation of this field and + lifecycle hooks will fail in runtime when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + description: |- + Periodic probe of container liveness. + Container will be restarted if the probe fails. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving + a GRPC port. + properties: + port: + description: Port number of the gRPC service. + Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the + request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + name: + description: |- + Name of the container specified as a DNS_LABEL. + Each container in a pod must have a unique name (DNS_LABEL). + Cannot be updated. + type: string + ports: + description: |- + List of ports to expose from the container. Not specifying a port here + DOES NOT prevent that port from being exposed. Any port which is + listening on the default "0.0.0.0" address inside a container will be + accessible from the network. + Modifying this array with strategic merge patch may corrupt the data. + For more information See https://github.com/kubernetes/kubernetes/issues/108255. + Cannot be updated. + items: + description: ContainerPort represents a network + port in a single container. + properties: + containerPort: + description: |- + Number of port to expose on the pod's IP address. + This must be a valid port number, 0 < x < 65536. + format: int32 + type: integer + hostIP: + description: What host IP to bind the external + port to. + type: string + hostPort: + description: |- + Number of port to expose on the host. + If specified, this must be a valid port number, 0 < x < 65536. + If HostNetwork is specified, this must match ContainerPort. + Most containers do not need this. + format: int32 + type: integer + name: + description: |- + If specified, this must be an IANA_SVC_NAME and unique within the pod. Each + named port in a pod must have a unique name. Name for the port that can be + referred to by services. + type: string + protocol: + default: TCP + description: |- + Protocol for port. Must be UDP, TCP, or SCTP. + Defaults to "TCP". + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + description: |- + Periodic probe of container service readiness. + Container will be removed from service endpoints if the probe fails. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving + a GRPC port. + properties: + port: + description: Port number of the gRPC service. + Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the + request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + resizePolicy: + description: Resources resize policy for the container. + items: + description: ContainerResizePolicy represents resource + resize policy for the container. + properties: + resourceName: + description: |- + Name of the resource to which this resource resize policy applies. + Supported values: cpu, memory. + type: string + restartPolicy: + description: |- + Restart policy to apply when specified resource is resized. + If not specified, it defaults to NotRequired. + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + description: |- + Compute Resources required by this container. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + properties: + claims: + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + + + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + + + This field is immutable. It can only be set for containers. + items: + description: ResourceClaim references one entry + in PodSpec.ResourceClaims. + properties: + name: + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + restartPolicy: + description: |- + RestartPolicy defines the restart behavior of individual containers in a pod. + This field may only be set for init containers, and the only allowed value is "Always". + For non-init containers or when this field is not specified, + the restart behavior is defined by the Pod's restart policy and the container type. + Setting the RestartPolicy as "Always" for the init container will have the following effect: + this init container will be continually restarted on + exit until all regular containers have terminated. Once all regular + containers have completed, all init containers with restartPolicy "Always" + will be shut down. This lifecycle differs from normal init containers and + is often referred to as a "sidecar" container. Although this init + container still starts in the init container sequence, it does not wait + for the container to complete before proceeding to the next init + container. Instead, the next init container starts immediately after this + init container is started, or after any startupProbe has successfully + completed. + type: string + securityContext: + description: |- + SecurityContext defines the security options the container should be run with. + If set, the fields of SecurityContext override the equivalent fields of PodSecurityContext. + More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ + properties: + allowPrivilegeEscalation: + description: |- + AllowPrivilegeEscalation controls whether a process can gain more + privileges than its parent process. This bool directly controls if + the no_new_privs flag will be set on the container process. + AllowPrivilegeEscalation is true always when the container is: + 1) run as Privileged + 2) has CAP_SYS_ADMIN + Note that this field cannot be set when spec.os.name is windows. + type: boolean + capabilities: + description: |- + The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the container runtime. + Note that this field cannot be set when spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX + capabilities type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX + capabilities type + type: string + type: array + type: object + privileged: + description: |- + Run container in privileged mode. + Processes in privileged containers are essentially equivalent to root on the host. + Defaults to false. + Note that this field cannot be set when spec.os.name is windows. + type: boolean + procMount: + description: |- + procMount denotes the type of proc mount to use for the containers. + The default is DefaultProcMount which uses the container runtime defaults for + readonly paths and masked paths. + This requires the ProcMountType feature flag to be enabled. + Note that this field cannot be set when spec.os.name is windows. + type: string + readOnlyRootFilesystem: + description: |- + Whether this container has a read-only root filesystem. + Default is false. + Note that this field cannot be set when spec.os.name is windows. + type: boolean + runAsGroup: + description: |- + The GID to run the entrypoint of the container process. + Uses runtime default if unset. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: |- + Indicates that the container must run as a non-root user. + If true, the Kubelet will validate the image at runtime to ensure that it + does not run as UID 0 (root) and fail to start the container if it does. + If unset or false, no such validation will be performed. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: |- + The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: |- + The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random SELinux context for each + container. May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label + that applies to the container. + type: string + role: + description: Role is a SELinux role label + that applies to the container. + type: string + type: + description: Type is a SELinux type label + that applies to the container. + type: string + user: + description: User is a SELinux user label + that applies to the container. + type: string + type: object + seccompProfile: + description: |- + The seccomp options to use by this container. If seccomp options are + provided at both the pod & container level, the container options + override the pod options. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile defined in a file on the node should be used. + The profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be set for any other type. + type: string + type: + description: |- + type indicates which kind of seccomp profile will be applied. + Valid options are: + + + Localhost - a profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile should be used. + Unconfined - no profile should be applied. + type: string + required: + - type + type: object + windowsOptions: + description: |- + The Windows specific settings applied to all containers. + If unspecified, the options from the PodSecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: |- + GMSACredentialSpec is where the GMSA admission webhook + (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the + GMSA credential spec named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the + name of the GMSA credential spec to use. + type: string + hostProcess: + description: |- + HostProcess determines if a container should be run as a 'Host Process' container. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: |- + The UserName in Windows to run the entrypoint of the container process. + Defaults to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: string + type: object + type: object + startupProbe: + description: |- + StartupProbe indicates that the Pod has successfully initialized. + If specified, no other probes are executed until this completes successfully. + If this probe fails, the Pod will be restarted, just as if the livenessProbe failed. + This can be used to provide different probe parameters at the beginning of a Pod's lifecycle, + when it might take a long time to load data or warm a cache, than during steady-state operation. + This cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving + a GRPC port. + properties: + port: + description: Port number of the gRPC service. + Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the + request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + stdin: + description: |- + Whether this container should allocate a buffer for stdin in the container runtime. If this + is not set, reads from stdin in the container will always result in EOF. + Default is false. + type: boolean + stdinOnce: + description: |- + Whether the container runtime should close the stdin channel after it has been opened by + a single attach. When stdin is true the stdin stream will remain open across multiple attach + sessions. If stdinOnce is set to true, stdin is opened on container start, is empty until the + first client attaches to stdin, and then remains open and accepts data until the client disconnects, + at which time stdin is closed and remains closed until the container is restarted. If this + flag is false, a container processes that reads from stdin will never receive an EOF. + Default is false + type: boolean + terminationMessagePath: + description: |- + Optional: Path at which the file to which the container's termination message + will be written is mounted into the container's filesystem. + Message written is intended to be brief final status, such as an assertion failure message. + Will be truncated by the node if greater than 4096 bytes. The total message length across + all containers will be limited to 12kb. + Defaults to /dev/termination-log. + Cannot be updated. + type: string + terminationMessagePolicy: + description: |- + Indicate how the termination message should be populated. File will use the contents of + terminationMessagePath to populate the container status message on both success and failure. + FallbackToLogsOnError will use the last chunk of container log output if the termination + message file is empty and the container exited with an error. + The log output is limited to 2048 bytes or 80 lines, whichever is smaller. + Defaults to File. + Cannot be updated. + type: string + tty: + description: |- + Whether this container should allocate a TTY for itself, also requires 'stdin' to be true. + Default is false. + type: boolean + volumeDevices: + description: volumeDevices is the list of block devices + to be used by the container. + items: + description: volumeDevice describes a mapping of + a raw block device within a container. + properties: + devicePath: + description: devicePath is the path inside of + the container that the device will be mapped + to. + type: string + name: + description: name must match the name of a persistentVolumeClaim + in the pod + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + description: |- + Pod volumes to mount into the container's filesystem. + Cannot be updated. + items: + description: VolumeMount describes a mounting of + a Volume within a container. + properties: + mountPath: + description: |- + Path within the container at which the volume should be mounted. Must + not contain ':'. + type: string + mountPropagation: + description: |- + mountPropagation determines how mounts are propagated from the host + to container and the other way around. + When not set, MountPropagationNone is used. + This field is beta in 1.10. + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: |- + Mounted read-only if true, read-write otherwise (false or unspecified). + Defaults to false. + type: boolean + subPath: + description: |- + Path within the volume from which the container's volume should be mounted. + Defaults to "" (volume's root). + type: string + subPathExpr: + description: |- + Expanded path within the volume from which the container's volume should be mounted. + Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment. + Defaults to "" (volume's root). + SubPathExpr and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + description: |- + Container's working directory. + If not specified, the container runtime's default will be used, which + might be configured in the container image. + Cannot be updated. + type: string + required: + - name + type: object + type: array + dnsConfig: + description: |- + Specifies the DNS parameters of a pod. + Parameters specified here will be merged to the generated DNS + configuration based on DNSPolicy. + properties: + nameservers: + description: |- + A list of DNS name server IP addresses. + This will be appended to the base nameservers generated from DNSPolicy. + Duplicated nameservers will be removed. + items: + type: string + type: array + options: + description: |- + A list of DNS resolver options. + This will be merged with the base options generated from DNSPolicy. + Duplicated entries will be removed. Resolution options given in Options + will override those that appear in the base DNSPolicy. + items: + description: PodDNSConfigOption defines DNS resolver + options of a pod. + properties: + name: + description: Required. + type: string + value: + type: string + type: object + type: array + searches: + description: |- + A list of DNS search domains for host-name lookup. + This will be appended to the base search paths generated from DNSPolicy. + Duplicated search paths will be removed. + items: + type: string + type: array + type: object + dnsPolicy: + description: |- + Set DNS policy for the pod. + Defaults to "ClusterFirst". + Valid values are 'ClusterFirstWithHostNet', 'ClusterFirst', 'Default' or 'None'. + DNS parameters given in DNSConfig will be merged with the policy selected with DNSPolicy. + To have DNS options set along with hostNetwork, you have to specify DNS policy + explicitly to 'ClusterFirstWithHostNet'. + type: string + enableServiceLinks: + description: |- + EnableServiceLinks indicates whether information about services should be injected into pod's + environment variables, matching the syntax of Docker links. + Optional: Defaults to true. + type: boolean + ephemeralContainers: + description: |- + List of ephemeral containers run in this pod. Ephemeral containers may be run in an existing + pod to perform user-initiated actions such as debugging. This list cannot be specified when + creating a pod, and it cannot be modified by updating the pod spec. In order to add an + ephemeral container to an existing pod, use the pod's ephemeralcontainers subresource. + items: + description: |- + An EphemeralContainer is a temporary container that you may add to an existing Pod for + user-initiated activities such as debugging. Ephemeral containers have no resource or + scheduling guarantees, and they will not be restarted when they exit or when a Pod is + removed or restarted. The kubelet may evict a Pod if an ephemeral container causes the + Pod to exceed its resource allocation. + + + To add an ephemeral container, use the ephemeralcontainers subresource of an existing + Pod. Ephemeral containers may not be removed or restarted. + properties: + args: + description: |- + Arguments to the entrypoint. + The image's CMD is used if this is not provided. + Variable references $(VAR_NAME) are expanded using the container's environment. If a variable + cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will + produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless + of whether the variable exists or not. Cannot be updated. + More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell + items: + type: string + type: array + command: + description: |- + Entrypoint array. Not executed within a shell. + The image's ENTRYPOINT is used if this is not provided. + Variable references $(VAR_NAME) are expanded using the container's environment. If a variable + cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will + produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless + of whether the variable exists or not. Cannot be updated. + More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell + items: + type: string + type: array + env: + description: |- + List of environment variables to set in the container. + Cannot be updated. + items: + description: EnvVar represents an environment variable + present in a Container. + properties: + name: + description: Name of the environment variable. + Must be a C_IDENTIFIER. + type: string + value: + description: |- + Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in the container and + any service environment variables. If a variable cannot be resolved, + the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless of whether the variable + exists or not. + Defaults to "". + type: string + valueFrom: + description: Source for the environment variable's + value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the + FieldPath is written in terms of, + defaults to "v1". + type: string + fieldPath: + description: Path of the field to select + in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required + for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format + of the exposed resources, defaults + to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to + select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in + the pod's namespace + properties: + key: + description: The key of the secret to + select from. Must be a valid secret + key. + type: string + 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 + optional: + description: Specify whether the Secret + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + envFrom: + description: |- + List of sources to populate environment variables in the container. + The keys defined within a source must be a C_IDENTIFIER. All invalid keys + will be reported as an event when the container is starting. When a key exists in multiple + sources, the value associated with the last source will take precedence. + Values defined by an Env with a duplicate key will take precedence. + Cannot be updated. + items: + description: EnvFromSource represents the source + of a set of ConfigMaps + properties: + configMapRef: + description: The ConfigMap to select from + 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 + optional: + description: Specify whether the ConfigMap + must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + description: An optional identifier to prepend + to each key in the ConfigMap. Must be a C_IDENTIFIER. + type: string + secretRef: + description: The Secret to select from + 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 + optional: + description: Specify whether the Secret + must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + image: + description: |- + Container image name. + More info: https://kubernetes.io/docs/concepts/containers/images + type: string + imagePullPolicy: + description: |- + Image pull policy. + One of Always, Never, IfNotPresent. + Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/containers/images#updating-images + type: string + lifecycle: + description: Lifecycle is not allowed for ephemeral + containers. + properties: + postStart: + description: |- + PostStart is called immediately after a container is created. If the handler fails, + the container is terminated and restarted according to its restart policy. + Other management of the container blocks until the hook completes. + More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks + properties: + exec: + description: Exec specifies the action to + take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in + the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a + custom header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP + server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + sleep: + description: Sleep represents the duration + that the container should sleep before being + terminated. + properties: + seconds: + description: Seconds is the number of + seconds to sleep. + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + description: |- + Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept + for the backward compatibility. There are no validation of this field and + lifecycle hooks will fail in runtime when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + description: |- + PreStop is called immediately before a container is terminated due to an + API request or management event such as liveness/startup probe failure, + preemption, resource contention, etc. The handler is not called if the + container crashes or exits. The Pod's termination grace period countdown begins before the + PreStop hook is executed. Regardless of the outcome of the handler, the + container will eventually terminate within the Pod's termination grace + period (unless delayed by finalizers). Other management of the container blocks until the hook completes + or until the termination grace period is reached. + More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks + properties: + exec: + description: Exec specifies the action to + take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in + the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a + custom header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP + server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + sleep: + description: Sleep represents the duration + that the container should sleep before being + terminated. + properties: + seconds: + description: Seconds is the number of + seconds to sleep. + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + description: |- + Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept + for the backward compatibility. There are no validation of this field and + lifecycle hooks will fail in runtime when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + description: Probes are not allowed for ephemeral + containers. + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving + a GRPC port. + properties: + port: + description: Port number of the gRPC service. + Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the + request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + name: + description: |- + Name of the ephemeral container specified as a DNS_LABEL. + This name must be unique among all containers, init containers and ephemeral containers. + type: string + ports: + description: Ports are not allowed for ephemeral containers. + items: + description: ContainerPort represents a network + port in a single container. + properties: + containerPort: + description: |- + Number of port to expose on the pod's IP address. + This must be a valid port number, 0 < x < 65536. + format: int32 + type: integer + hostIP: + description: What host IP to bind the external + port to. + type: string + hostPort: + description: |- + Number of port to expose on the host. + If specified, this must be a valid port number, 0 < x < 65536. + If HostNetwork is specified, this must match ContainerPort. + Most containers do not need this. + format: int32 + type: integer + name: + description: |- + If specified, this must be an IANA_SVC_NAME and unique within the pod. Each + named port in a pod must have a unique name. Name for the port that can be + referred to by services. + type: string + protocol: + default: TCP + description: |- + Protocol for port. Must be UDP, TCP, or SCTP. + Defaults to "TCP". + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + description: Probes are not allowed for ephemeral + containers. + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving + a GRPC port. + properties: + port: + description: Port number of the gRPC service. + Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the + request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + resizePolicy: + description: Resources resize policy for the container. + items: + description: ContainerResizePolicy represents resource + resize policy for the container. + properties: + resourceName: + description: |- + Name of the resource to which this resource resize policy applies. + Supported values: cpu, memory. + type: string + restartPolicy: + description: |- + Restart policy to apply when specified resource is resized. + If not specified, it defaults to NotRequired. + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + description: |- + Resources are not allowed for ephemeral containers. Ephemeral containers use spare resources + already allocated to the pod. + properties: + claims: + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + + + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + + + This field is immutable. It can only be set for containers. + items: + description: ResourceClaim references one entry + in PodSpec.ResourceClaims. + properties: + name: + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + restartPolicy: + description: |- + Restart policy for the container to manage the restart behavior of each + container within a pod. + This may only be set for init containers. You cannot set this field on + ephemeral containers. + type: string + securityContext: + description: |- + Optional: SecurityContext defines the security options the ephemeral container should be run with. + If set, the fields of SecurityContext override the equivalent fields of PodSecurityContext. + properties: + allowPrivilegeEscalation: + description: |- + AllowPrivilegeEscalation controls whether a process can gain more + privileges than its parent process. This bool directly controls if + the no_new_privs flag will be set on the container process. + AllowPrivilegeEscalation is true always when the container is: + 1) run as Privileged + 2) has CAP_SYS_ADMIN + Note that this field cannot be set when spec.os.name is windows. + type: boolean + capabilities: + description: |- + The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the container runtime. + Note that this field cannot be set when spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX + capabilities type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX + capabilities type + type: string + type: array + type: object + privileged: + description: |- + Run container in privileged mode. + Processes in privileged containers are essentially equivalent to root on the host. + Defaults to false. + Note that this field cannot be set when spec.os.name is windows. + type: boolean + procMount: + description: |- + procMount denotes the type of proc mount to use for the containers. + The default is DefaultProcMount which uses the container runtime defaults for + readonly paths and masked paths. + This requires the ProcMountType feature flag to be enabled. + Note that this field cannot be set when spec.os.name is windows. + type: string + readOnlyRootFilesystem: + description: |- + Whether this container has a read-only root filesystem. + Default is false. + Note that this field cannot be set when spec.os.name is windows. + type: boolean + runAsGroup: + description: |- + The GID to run the entrypoint of the container process. + Uses runtime default if unset. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: |- + Indicates that the container must run as a non-root user. + If true, the Kubelet will validate the image at runtime to ensure that it + does not run as UID 0 (root) and fail to start the container if it does. + If unset or false, no such validation will be performed. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: |- + The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: |- + The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random SELinux context for each + container. May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label + that applies to the container. + type: string + role: + description: Role is a SELinux role label + that applies to the container. + type: string + type: + description: Type is a SELinux type label + that applies to the container. + type: string + user: + description: User is a SELinux user label + that applies to the container. + type: string + type: object + seccompProfile: + description: |- + The seccomp options to use by this container. If seccomp options are + provided at both the pod & container level, the container options + override the pod options. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile defined in a file on the node should be used. + The profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be set for any other type. + type: string + type: + description: |- + type indicates which kind of seccomp profile will be applied. + Valid options are: + + + Localhost - a profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile should be used. + Unconfined - no profile should be applied. + type: string + required: + - type + type: object + windowsOptions: + description: |- + The Windows specific settings applied to all containers. + If unspecified, the options from the PodSecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: |- + GMSACredentialSpec is where the GMSA admission webhook + (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the + GMSA credential spec named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the + name of the GMSA credential spec to use. + type: string + hostProcess: + description: |- + HostProcess determines if a container should be run as a 'Host Process' container. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: |- + The UserName in Windows to run the entrypoint of the container process. + Defaults to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: string + type: object + type: object + startupProbe: + description: Probes are not allowed for ephemeral + containers. + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving + a GRPC port. + properties: + port: + description: Port number of the gRPC service. + Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the + request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + stdin: + description: |- + Whether this container should allocate a buffer for stdin in the container runtime. If this + is not set, reads from stdin in the container will always result in EOF. + Default is false. + type: boolean + stdinOnce: + description: |- + Whether the container runtime should close the stdin channel after it has been opened by + a single attach. When stdin is true the stdin stream will remain open across multiple attach + sessions. If stdinOnce is set to true, stdin is opened on container start, is empty until the + first client attaches to stdin, and then remains open and accepts data until the client disconnects, + at which time stdin is closed and remains closed until the container is restarted. If this + flag is false, a container processes that reads from stdin will never receive an EOF. + Default is false + type: boolean + targetContainerName: + description: |- + If set, the name of the container from PodSpec that this ephemeral container targets. + The ephemeral container will be run in the namespaces (IPC, PID, etc) of this container. + If not set then the ephemeral container uses the namespaces configured in the Pod spec. + + + The container runtime must implement support for this feature. If the runtime does not + support namespace targeting then the result of setting this field is undefined. + type: string + terminationMessagePath: + description: |- + Optional: Path at which the file to which the container's termination message + will be written is mounted into the container's filesystem. + Message written is intended to be brief final status, such as an assertion failure message. + Will be truncated by the node if greater than 4096 bytes. The total message length across + all containers will be limited to 12kb. + Defaults to /dev/termination-log. + Cannot be updated. + type: string + terminationMessagePolicy: + description: |- + Indicate how the termination message should be populated. File will use the contents of + terminationMessagePath to populate the container status message on both success and failure. + FallbackToLogsOnError will use the last chunk of container log output if the termination + message file is empty and the container exited with an error. + The log output is limited to 2048 bytes or 80 lines, whichever is smaller. + Defaults to File. + Cannot be updated. + type: string + tty: + description: |- + Whether this container should allocate a TTY for itself, also requires 'stdin' to be true. + Default is false. + type: boolean + volumeDevices: + description: volumeDevices is the list of block devices + to be used by the container. + items: + description: volumeDevice describes a mapping of + a raw block device within a container. + properties: + devicePath: + description: devicePath is the path inside of + the container that the device will be mapped + to. + type: string + name: + description: name must match the name of a persistentVolumeClaim + in the pod + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + description: |- + Pod volumes to mount into the container's filesystem. Subpath mounts are not allowed for ephemeral containers. + Cannot be updated. + items: + description: VolumeMount describes a mounting of + a Volume within a container. + properties: + mountPath: + description: |- + Path within the container at which the volume should be mounted. Must + not contain ':'. + type: string + mountPropagation: + description: |- + mountPropagation determines how mounts are propagated from the host + to container and the other way around. + When not set, MountPropagationNone is used. + This field is beta in 1.10. + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: |- + Mounted read-only if true, read-write otherwise (false or unspecified). + Defaults to false. + type: boolean + subPath: + description: |- + Path within the volume from which the container's volume should be mounted. + Defaults to "" (volume's root). + type: string + subPathExpr: + description: |- + Expanded path within the volume from which the container's volume should be mounted. + Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment. + Defaults to "" (volume's root). + SubPathExpr and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + description: |- + Container's working directory. + If not specified, the container runtime's default will be used, which + might be configured in the container image. + Cannot be updated. + type: string + required: + - name + type: object + type: array + hostAliases: + description: |- + HostAliases is an optional list of hosts and IPs that will be injected into the pod's hosts + file if specified. This is only valid for non-hostNetwork pods. + items: + description: |- + HostAlias holds the mapping between IP and hostnames that will be injected as an entry in the + pod's hosts file. + properties: + hostnames: + description: Hostnames for the above IP address. + items: + type: string + type: array + ip: + description: IP address of the host file entry. + type: string + type: object + type: array + hostIPC: + description: |- + Use the host's ipc namespace. + Optional: Default to false. + type: boolean + hostNetwork: + description: |- + Host networking requested for this pod. Use the host's network namespace. + If this option is set, the ports that will be used must be specified. + Default to false. + type: boolean + hostPID: + description: |- + Use the host's pid namespace. + Optional: Default to false. + type: boolean + hostUsers: + description: |- + Use the host's user namespace. + Optional: Default to true. + If set to true or not present, the pod will be run in the host user namespace, useful + for when the pod needs a feature only available to the host user namespace, such as + loading a kernel module with CAP_SYS_MODULE. + When set to false, a new userns is created for the pod. Setting false is useful for + mitigating container breakout vulnerabilities even allowing users to run their + containers as root without actually having root privileges on the host. + This field is alpha-level and is only honored by servers that enable the UserNamespacesSupport feature. + type: boolean + hostname: + description: |- + Specifies the hostname of the Pod + If not specified, the pod's hostname will be set to a system-defined value. + type: string + imagePullSecrets: + description: |- + ImagePullSecrets is an optional list of references to secrets in the same namespace to use for pulling any of the images used by this PodSpec. + If specified, these secrets will be passed to individual puller implementations for them to use. + More info: https://kubernetes.io/docs/concepts/containers/images#specifying-imagepullsecrets-on-a-pod + items: + 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? + type: string + type: object + x-kubernetes-map-type: atomic + type: array + initContainers: + description: |- + List of initialization containers belonging to the pod. + Init containers are executed in order prior to containers being started. If any + init container fails, the pod is considered to have failed and is handled according + to its restartPolicy. The name for an init container or normal container must be + unique among all containers. + Init containers may not have Lifecycle actions, Readiness probes, Liveness probes, or Startup probes. + The resourceRequirements of an init container are taken into account during scheduling + by finding the highest request/limit for each resource type, and then using the max of + of that value or the sum of the normal containers. Limits are applied to init containers + in a similar fashion. + Init containers cannot currently be added or removed. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/init-containers/ + items: + description: A single application container that you want + to run within a pod. + properties: + args: + description: |- + Arguments to the entrypoint. + The container image's CMD is used if this is not provided. + Variable references $(VAR_NAME) are expanded using the container's environment. If a variable + cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will + produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless + of whether the variable exists or not. Cannot be updated. + More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell + items: + type: string + type: array + command: + description: |- + Entrypoint array. Not executed within a shell. + The container image's ENTRYPOINT is used if this is not provided. + Variable references $(VAR_NAME) are expanded using the container's environment. If a variable + cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will + produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless + of whether the variable exists or not. Cannot be updated. + More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell + items: + type: string + type: array + env: + description: |- + List of environment variables to set in the container. + Cannot be updated. + items: + description: EnvVar represents an environment variable + present in a Container. + properties: + name: + description: Name of the environment variable. + Must be a C_IDENTIFIER. + type: string + value: + description: |- + Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in the container and + any service environment variables. If a variable cannot be resolved, + the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless of whether the variable + exists or not. + Defaults to "". + type: string + valueFrom: + description: Source for the environment variable's + value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the + FieldPath is written in terms of, + defaults to "v1". + type: string + fieldPath: + description: Path of the field to select + in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required + for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format + of the exposed resources, defaults + to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to + select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in + the pod's namespace + properties: + key: + description: The key of the secret to + select from. Must be a valid secret + key. + type: string + 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 + optional: + description: Specify whether the Secret + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + envFrom: + description: |- + List of sources to populate environment variables in the container. + The keys defined within a source must be a C_IDENTIFIER. All invalid keys + will be reported as an event when the container is starting. When a key exists in multiple + sources, the value associated with the last source will take precedence. + Values defined by an Env with a duplicate key will take precedence. + Cannot be updated. + items: + description: EnvFromSource represents the source + of a set of ConfigMaps + properties: + configMapRef: + description: The ConfigMap to select from + 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 + optional: + description: Specify whether the ConfigMap + must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + description: An optional identifier to prepend + to each key in the ConfigMap. Must be a C_IDENTIFIER. + type: string + secretRef: + description: The Secret to select from + 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 + optional: + description: Specify whether the Secret + must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + image: + description: |- + Container image name. + More info: https://kubernetes.io/docs/concepts/containers/images + This field is optional to allow higher level config management to default or override + container images in workload controllers like Deployments and StatefulSets. + type: string + imagePullPolicy: + description: |- + Image pull policy. + One of Always, Never, IfNotPresent. + Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/containers/images#updating-images + type: string + lifecycle: + description: |- + Actions that the management system should take in response to container lifecycle events. + Cannot be updated. + properties: + postStart: + description: |- + PostStart is called immediately after a container is created. If the handler fails, + the container is terminated and restarted according to its restart policy. + Other management of the container blocks until the hook completes. + More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks + properties: + exec: + description: Exec specifies the action to + take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in + the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a + custom header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP + server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + sleep: + description: Sleep represents the duration + that the container should sleep before being + terminated. + properties: + seconds: + description: Seconds is the number of + seconds to sleep. + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + description: |- + Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept + for the backward compatibility. There are no validation of this field and + lifecycle hooks will fail in runtime when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + description: |- + PreStop is called immediately before a container is terminated due to an + API request or management event such as liveness/startup probe failure, + preemption, resource contention, etc. The handler is not called if the + container crashes or exits. The Pod's termination grace period countdown begins before the + PreStop hook is executed. Regardless of the outcome of the handler, the + container will eventually terminate within the Pod's termination grace + period (unless delayed by finalizers). Other management of the container blocks until the hook completes + or until the termination grace period is reached. + More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks + properties: + exec: + description: Exec specifies the action to + take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in + the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a + custom header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP + server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + sleep: + description: Sleep represents the duration + that the container should sleep before being + terminated. + properties: + seconds: + description: Seconds is the number of + seconds to sleep. + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + description: |- + Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept + for the backward compatibility. There are no validation of this field and + lifecycle hooks will fail in runtime when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + description: |- + Periodic probe of container liveness. + Container will be restarted if the probe fails. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving + a GRPC port. + properties: + port: + description: Port number of the gRPC service. + Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the + request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + name: + description: |- + Name of the container specified as a DNS_LABEL. + Each container in a pod must have a unique name (DNS_LABEL). + Cannot be updated. + type: string + ports: + description: |- + List of ports to expose from the container. Not specifying a port here + DOES NOT prevent that port from being exposed. Any port which is + listening on the default "0.0.0.0" address inside a container will be + accessible from the network. + Modifying this array with strategic merge patch may corrupt the data. + For more information See https://github.com/kubernetes/kubernetes/issues/108255. + Cannot be updated. + items: + description: ContainerPort represents a network + port in a single container. + properties: + containerPort: + description: |- + Number of port to expose on the pod's IP address. + This must be a valid port number, 0 < x < 65536. + format: int32 + type: integer + hostIP: + description: What host IP to bind the external + port to. + type: string + hostPort: + description: |- + Number of port to expose on the host. + If specified, this must be a valid port number, 0 < x < 65536. + If HostNetwork is specified, this must match ContainerPort. + Most containers do not need this. + format: int32 + type: integer + name: + description: |- + If specified, this must be an IANA_SVC_NAME and unique within the pod. Each + named port in a pod must have a unique name. Name for the port that can be + referred to by services. + type: string + protocol: + default: TCP + description: |- + Protocol for port. Must be UDP, TCP, or SCTP. + Defaults to "TCP". + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + description: |- + Periodic probe of container service readiness. + Container will be removed from service endpoints if the probe fails. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving + a GRPC port. + properties: + port: + description: Port number of the gRPC service. + Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the + request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + resizePolicy: + description: Resources resize policy for the container. + items: + description: ContainerResizePolicy represents resource + resize policy for the container. + properties: + resourceName: + description: |- + Name of the resource to which this resource resize policy applies. + Supported values: cpu, memory. + type: string + restartPolicy: + description: |- + Restart policy to apply when specified resource is resized. + If not specified, it defaults to NotRequired. + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + description: |- + Compute Resources required by this container. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + properties: + claims: + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + + + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + + + This field is immutable. It can only be set for containers. + items: + description: ResourceClaim references one entry + in PodSpec.ResourceClaims. + properties: + name: + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + restartPolicy: + description: |- + RestartPolicy defines the restart behavior of individual containers in a pod. + This field may only be set for init containers, and the only allowed value is "Always". + For non-init containers or when this field is not specified, + the restart behavior is defined by the Pod's restart policy and the container type. + Setting the RestartPolicy as "Always" for the init container will have the following effect: + this init container will be continually restarted on + exit until all regular containers have terminated. Once all regular + containers have completed, all init containers with restartPolicy "Always" + will be shut down. This lifecycle differs from normal init containers and + is often referred to as a "sidecar" container. Although this init + container still starts in the init container sequence, it does not wait + for the container to complete before proceeding to the next init + container. Instead, the next init container starts immediately after this + init container is started, or after any startupProbe has successfully + completed. + type: string + securityContext: + description: |- + SecurityContext defines the security options the container should be run with. + If set, the fields of SecurityContext override the equivalent fields of PodSecurityContext. + More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ + properties: + allowPrivilegeEscalation: + description: |- + AllowPrivilegeEscalation controls whether a process can gain more + privileges than its parent process. This bool directly controls if + the no_new_privs flag will be set on the container process. + AllowPrivilegeEscalation is true always when the container is: + 1) run as Privileged + 2) has CAP_SYS_ADMIN + Note that this field cannot be set when spec.os.name is windows. + type: boolean + capabilities: + description: |- + The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the container runtime. + Note that this field cannot be set when spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX + capabilities type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX + capabilities type + type: string + type: array + type: object + privileged: + description: |- + Run container in privileged mode. + Processes in privileged containers are essentially equivalent to root on the host. + Defaults to false. + Note that this field cannot be set when spec.os.name is windows. + type: boolean + procMount: + description: |- + procMount denotes the type of proc mount to use for the containers. + The default is DefaultProcMount which uses the container runtime defaults for + readonly paths and masked paths. + This requires the ProcMountType feature flag to be enabled. + Note that this field cannot be set when spec.os.name is windows. + type: string + readOnlyRootFilesystem: + description: |- + Whether this container has a read-only root filesystem. + Default is false. + Note that this field cannot be set when spec.os.name is windows. + type: boolean + runAsGroup: + description: |- + The GID to run the entrypoint of the container process. + Uses runtime default if unset. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: |- + Indicates that the container must run as a non-root user. + If true, the Kubelet will validate the image at runtime to ensure that it + does not run as UID 0 (root) and fail to start the container if it does. + If unset or false, no such validation will be performed. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: |- + The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: |- + The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random SELinux context for each + container. May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label + that applies to the container. + type: string + role: + description: Role is a SELinux role label + that applies to the container. + type: string + type: + description: Type is a SELinux type label + that applies to the container. + type: string + user: + description: User is a SELinux user label + that applies to the container. + type: string + type: object + seccompProfile: + description: |- + The seccomp options to use by this container. If seccomp options are + provided at both the pod & container level, the container options + override the pod options. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile defined in a file on the node should be used. + The profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be set for any other type. + type: string + type: + description: |- + type indicates which kind of seccomp profile will be applied. + Valid options are: + + + Localhost - a profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile should be used. + Unconfined - no profile should be applied. + type: string + required: + - type + type: object + windowsOptions: + description: |- + The Windows specific settings applied to all containers. + If unspecified, the options from the PodSecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: |- + GMSACredentialSpec is where the GMSA admission webhook + (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the + GMSA credential spec named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the + name of the GMSA credential spec to use. + type: string + hostProcess: + description: |- + HostProcess determines if a container should be run as a 'Host Process' container. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: |- + The UserName in Windows to run the entrypoint of the container process. + Defaults to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: string + type: object + type: object + startupProbe: + description: |- + StartupProbe indicates that the Pod has successfully initialized. + If specified, no other probes are executed until this completes successfully. + If this probe fails, the Pod will be restarted, just as if the livenessProbe failed. + This can be used to provide different probe parameters at the beginning of a Pod's lifecycle, + when it might take a long time to load data or warm a cache, than during steady-state operation. + This cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving + a GRPC port. + properties: + port: + description: Port number of the gRPC service. + Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the + request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + stdin: + description: |- + Whether this container should allocate a buffer for stdin in the container runtime. If this + is not set, reads from stdin in the container will always result in EOF. + Default is false. + type: boolean + stdinOnce: + description: |- + Whether the container runtime should close the stdin channel after it has been opened by + a single attach. When stdin is true the stdin stream will remain open across multiple attach + sessions. If stdinOnce is set to true, stdin is opened on container start, is empty until the + first client attaches to stdin, and then remains open and accepts data until the client disconnects, + at which time stdin is closed and remains closed until the container is restarted. If this + flag is false, a container processes that reads from stdin will never receive an EOF. + Default is false + type: boolean + terminationMessagePath: + description: |- + Optional: Path at which the file to which the container's termination message + will be written is mounted into the container's filesystem. + Message written is intended to be brief final status, such as an assertion failure message. + Will be truncated by the node if greater than 4096 bytes. The total message length across + all containers will be limited to 12kb. + Defaults to /dev/termination-log. + Cannot be updated. + type: string + terminationMessagePolicy: + description: |- + Indicate how the termination message should be populated. File will use the contents of + terminationMessagePath to populate the container status message on both success and failure. + FallbackToLogsOnError will use the last chunk of container log output if the termination + message file is empty and the container exited with an error. + The log output is limited to 2048 bytes or 80 lines, whichever is smaller. + Defaults to File. + Cannot be updated. + type: string + tty: + description: |- + Whether this container should allocate a TTY for itself, also requires 'stdin' to be true. + Default is false. + type: boolean + volumeDevices: + description: volumeDevices is the list of block devices + to be used by the container. + items: + description: volumeDevice describes a mapping of + a raw block device within a container. + properties: + devicePath: + description: devicePath is the path inside of + the container that the device will be mapped + to. + type: string + name: + description: name must match the name of a persistentVolumeClaim + in the pod + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + description: |- + Pod volumes to mount into the container's filesystem. + Cannot be updated. + items: + description: VolumeMount describes a mounting of + a Volume within a container. + properties: + mountPath: + description: |- + Path within the container at which the volume should be mounted. Must + not contain ':'. + type: string + mountPropagation: + description: |- + mountPropagation determines how mounts are propagated from the host + to container and the other way around. + When not set, MountPropagationNone is used. + This field is beta in 1.10. + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: |- + Mounted read-only if true, read-write otherwise (false or unspecified). + Defaults to false. + type: boolean + subPath: + description: |- + Path within the volume from which the container's volume should be mounted. + Defaults to "" (volume's root). + type: string + subPathExpr: + description: |- + Expanded path within the volume from which the container's volume should be mounted. + Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment. + Defaults to "" (volume's root). + SubPathExpr and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + description: |- + Container's working directory. + If not specified, the container runtime's default will be used, which + might be configured in the container image. + Cannot be updated. + type: string + required: + - name + type: object + type: array + nodeName: + description: |- + NodeName is a request to schedule this pod onto a specific node. If it is non-empty, + the scheduler simply schedules this pod onto that node, assuming that it fits resource + requirements. + type: string + nodeSelector: + additionalProperties: + type: string + description: |- + NodeSelector is a selector which must be true for the pod to fit on a node. + Selector which must match a node's labels for the pod to be scheduled on that node. + More info: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ + type: object + x-kubernetes-map-type: atomic + os: + description: |- + Specifies the OS of the containers in the pod. + Some pod and container fields are restricted if this is set. + + + If the OS field is set to linux, the following fields must be unset: + -securityContext.windowsOptions + + + If the OS field is set to windows, following fields must be unset: + - spec.hostPID + - spec.hostIPC + - spec.hostUsers + - spec.securityContext.seLinuxOptions + - spec.securityContext.seccompProfile + - spec.securityContext.fsGroup + - spec.securityContext.fsGroupChangePolicy + - spec.securityContext.sysctls + - spec.shareProcessNamespace + - spec.securityContext.runAsUser + - spec.securityContext.runAsGroup + - spec.securityContext.supplementalGroups + - spec.containers[*].securityContext.seLinuxOptions + - spec.containers[*].securityContext.seccompProfile + - spec.containers[*].securityContext.capabilities + - spec.containers[*].securityContext.readOnlyRootFilesystem + - spec.containers[*].securityContext.privileged + - spec.containers[*].securityContext.allowPrivilegeEscalation + - spec.containers[*].securityContext.procMount + - spec.containers[*].securityContext.runAsUser + - spec.containers[*].securityContext.runAsGroup + properties: + name: + description: |- + Name is the name of the operating system. The currently supported values are linux and windows. + Additional value may be defined in future and can be one of: + https://github.com/opencontainers/runtime-spec/blob/master/config.md#platform-specific-configuration + Clients should expect to handle additional values and treat unrecognized values in this field as os: null + type: string + required: + - name + type: object + overhead: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Overhead represents the resource overhead associated with running a pod for a given RuntimeClass. + This field will be autopopulated at admission time by the RuntimeClass admission controller. If + the RuntimeClass admission controller is enabled, overhead must not be set in Pod create requests. + The RuntimeClass admission controller will reject Pod create requests which have the overhead already + set. If RuntimeClass is configured and selected in the PodSpec, Overhead will be set to the value + defined in the corresponding RuntimeClass, otherwise it will remain unset and treated as zero. + More info: https://git.k8s.io/enhancements/keps/sig-node/688-pod-overhead/README.md + type: object + preemptionPolicy: + description: |- + PreemptionPolicy is the Policy for preempting pods with lower priority. + One of Never, PreemptLowerPriority. + Defaults to PreemptLowerPriority if unset. + type: string + priority: + description: |- + The priority value. Various system components use this field to find the + priority of the pod. When Priority Admission Controller is enabled, it + prevents users from setting this field. The admission controller populates + this field from PriorityClassName. + The higher the value, the higher the priority. + format: int32 + type: integer + priorityClassName: + description: |- + If specified, indicates the pod's priority. "system-node-critical" and + "system-cluster-critical" are two special keywords which indicate the + highest priorities with the former being the highest priority. Any other + name must be defined by creating a PriorityClass object with that name. + If not specified, the pod priority will be default or zero if there is no + default. + type: string + readinessGates: + description: |- + If specified, all readiness gates will be evaluated for pod readiness. + A pod is ready when all its containers are ready AND + all conditions specified in the readiness gates have status equal to "True" + More info: https://git.k8s.io/enhancements/keps/sig-network/580-pod-readiness-gates + items: + description: PodReadinessGate contains the reference to + a pod condition + properties: + conditionType: + description: ConditionType refers to a condition in + the pod's condition list with matching type. + type: string + required: + - conditionType + type: object + type: array + resourceClaims: + description: |- + ResourceClaims defines which ResourceClaims must be allocated + and reserved before the Pod is allowed to start. The resources + will be made available to those containers which consume them + by name. + + + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + + + This field is immutable. + items: + description: |- + PodResourceClaim references exactly one ResourceClaim through a ClaimSource. + It adds a name to it that uniquely identifies the ResourceClaim inside the Pod. + Containers that need access to the ResourceClaim reference it with this name. + properties: + name: + description: |- + Name uniquely identifies this resource claim inside the pod. + This must be a DNS_LABEL. + type: string + source: + description: Source describes where to find the ResourceClaim. + properties: + resourceClaimName: + description: |- + ResourceClaimName is the name of a ResourceClaim object in the same + namespace as this pod. + type: string + resourceClaimTemplateName: + description: |- + ResourceClaimTemplateName is the name of a ResourceClaimTemplate + object in the same namespace as this pod. + + + The template will be used to create a new ResourceClaim, which will + be bound to this pod. When this pod is deleted, the ResourceClaim + will also be deleted. The pod name and resource name, along with a + generated component, will be used to form a unique name for the + ResourceClaim, which will be recorded in pod.status.resourceClaimStatuses. + + + This field is immutable and no changes will be made to the + corresponding ResourceClaim by the control plane after creating the + ResourceClaim. + type: string + type: object + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + restartPolicy: + description: |- + Restart policy for all containers within the pod. + One of Always, OnFailure, Never. In some contexts, only a subset of those values may be permitted. + Default to Always. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#restart-policy + type: string + runtimeClassName: + description: |- + RuntimeClassName refers to a RuntimeClass object in the node.k8s.io group, which should be used + to run this pod. If no RuntimeClass resource matches the named class, the pod will not be run. + If unset or empty, the "legacy" RuntimeClass will be used, which is an implicit class with an + empty definition that uses the default runtime handler. + More info: https://git.k8s.io/enhancements/keps/sig-node/585-runtime-class + type: string + schedulerName: + description: |- + If specified, the pod will be dispatched by specified scheduler. + If not specified, the pod will be dispatched by default scheduler. + type: string + schedulingGates: + description: |- + SchedulingGates is an opaque list of values that if specified will block scheduling the pod. + If schedulingGates is not empty, the pod will stay in the SchedulingGated state and the + scheduler will not attempt to schedule the pod. + + + SchedulingGates can only be set at pod creation time, and be removed only afterwards. + + + This is a beta feature enabled by the PodSchedulingReadiness feature gate. + items: + description: PodSchedulingGate is associated to a Pod + to guard its scheduling. + properties: + name: + description: |- + Name of the scheduling gate. + Each scheduling gate must have a unique name field. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + securityContext: + description: |- + SecurityContext holds pod-level security attributes and common container settings. + Optional: Defaults to empty. See type description for default values of each field. + properties: + fsGroup: + description: |- + A special supplemental group that applies to all containers in a pod. + Some volume types allow the Kubelet to change the ownership of that volume + to be owned by the pod: + + + 1. The owning GID will be the FSGroup + 2. The setgid bit is set (new files created in the volume will be owned by FSGroup) + 3. The permission bits are OR'd with rw-rw---- + + + If unset, the Kubelet will not modify the ownership and permissions of any volume. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + fsGroupChangePolicy: + description: |- + fsGroupChangePolicy defines behavior of changing ownership and permission of the volume + before being exposed inside Pod. This field will only apply to + volume types which support fsGroup based ownership(and permissions). + It will have no effect on ephemeral volume types such as: secret, configmaps + and emptydir. + Valid values are "OnRootMismatch" and "Always". If not specified, "Always" is used. + Note that this field cannot be set when spec.os.name is windows. + type: string + runAsGroup: + description: |- + The GID to run the entrypoint of the container process. + Uses runtime default if unset. + May also be set in SecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence + for that container. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: |- + Indicates that the container must run as a non-root user. + If true, the Kubelet will validate the image at runtime to ensure that it + does not run as UID 0 (root) and fail to start the container if it does. + If unset or false, no such validation will be performed. + May also be set in SecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: |- + The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in SecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence + for that container. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: |- + The SELinux context to be applied to all containers. + If unspecified, the container runtime will allocate a random SELinux context for each + container. May also be set in SecurityContext. If set in + both SecurityContext and PodSecurityContext, the value specified in SecurityContext + takes precedence for that container. + Note that this field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies + to the container. + type: string + role: + description: Role is a SELinux role label that applies + to the container. + type: string + type: + description: Type is a SELinux type label that applies + to the container. + type: string + user: + description: User is a SELinux user label that applies + to the container. + type: string + type: object + seccompProfile: + description: |- + The seccomp options to use by the containers in this pod. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile defined in a file on the node should be used. + The profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be set for any other type. + type: string + type: + description: |- + type indicates which kind of seccomp profile will be applied. + Valid options are: + + + Localhost - a profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile should be used. + Unconfined - no profile should be applied. + type: string + required: + - type + type: object + supplementalGroups: + description: |- + A list of groups applied to the first process run in each container, in addition + to the container's primary GID, the fsGroup (if specified), and group memberships + defined in the container image for the uid of the container process. If unspecified, + no additional groups are added to any container. Note that group memberships + defined in the container image for the uid of the container process are still effective, + even if they are not included in this list. + Note that this field cannot be set when spec.os.name is windows. + items: + format: int64 + type: integer + type: array + sysctls: + description: |- + Sysctls hold a list of namespaced sysctls used for the pod. Pods with unsupported + sysctls (by the container runtime) might fail to launch. + Note that this field cannot be set when spec.os.name is windows. + items: + description: Sysctl defines a kernel parameter to + be set + properties: + name: + description: Name of a property to set + type: string + value: + description: Value of a property to set + type: string + required: + - name + - value + type: object + type: array + windowsOptions: + description: |- + The Windows specific settings applied to all containers. + If unspecified, the options within a container's SecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: |- + GMSACredentialSpec is where the GMSA admission webhook + (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the + GMSA credential spec named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name + of the GMSA credential spec to use. + type: string + hostProcess: + description: |- + HostProcess determines if a container should be run as a 'Host Process' container. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: |- + The UserName in Windows to run the entrypoint of the container process. + Defaults to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: string + type: object + type: object + serviceAccount: + description: |- + DeprecatedServiceAccount is a depreciated alias for ServiceAccountName. + Deprecated: Use serviceAccountName instead. + type: string + serviceAccountName: + description: |- + ServiceAccountName is the name of the ServiceAccount to use to run this pod. + More info: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/ + type: string + setHostnameAsFQDN: + description: |- + If true the pod's hostname will be configured as the pod's FQDN, rather than the leaf name (the default). + In Linux containers, this means setting the FQDN in the hostname field of the kernel (the nodename field of struct utsname). + In Windows containers, this means setting the registry value of hostname for the registry key HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters to FQDN. + If a pod does not have FQDN, this has no effect. + Default to false. + type: boolean + shareProcessNamespace: + description: |- + Share a single process namespace between all of the containers in a pod. + When this is set containers will be able to view and signal processes from other containers + in the same pod, and the first process in each container will not be assigned PID 1. + HostPID and ShareProcessNamespace cannot both be set. + Optional: Default to false. + type: boolean + subdomain: + description: |- + If specified, the fully qualified Pod hostname will be "...svc.". + If not specified, the pod will not have a domainname at all. + type: string + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully. May be decreased in delete request. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + If this value is nil, the default grace period will be used instead. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + Defaults to 30 seconds. + format: int64 + type: integer + tolerations: + description: If specified, the pod's tolerations. + items: + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . + properties: + effect: + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. + type: string + operator: + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. + type: string + tolerationSeconds: + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. + format: int64 + type: integer + value: + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. + type: string + type: object + type: array + topologySpreadConstraints: + description: |- + TopologySpreadConstraints describes how a group of pods ought to spread across topology + domains. Scheduler will schedule pods in a way which abides by the constraints. + All topologySpreadConstraints are ANDed. + items: + description: TopologySpreadConstraint specifies how to + spread matching pods among the given topology. + properties: + labelSelector: + description: |- + LabelSelector is used to find matching pods. + Pods that match this label selector are counted to determine the number of pods + in their corresponding topology domain. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select the pods over which + spreading will be calculated. The keys are used to lookup values from the + incoming pod labels, those key-value labels are ANDed with labelSelector + to select the group of existing pods over which spreading will be calculated + for the incoming pod. The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + MatchLabelKeys cannot be set when LabelSelector isn't set. + Keys that don't exist in the incoming pod labels will + be ignored. A null or empty list means only match against labelSelector. + + + This is a beta field and requires the MatchLabelKeysInPodTopologySpread feature gate to be enabled (enabled by default). + items: + type: string + type: array + x-kubernetes-list-type: atomic + maxSkew: + description: |- + MaxSkew describes the degree to which pods may be unevenly distributed. + When `whenUnsatisfiable=DoNotSchedule`, it is the maximum permitted difference + between the number of matching pods in the target topology and the global minimum. + The global minimum is the minimum number of matching pods in an eligible domain + or zero if the number of eligible domains is less than MinDomains. + For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same + labelSelector spread as 2/2/1: + In this case, the global minimum is 1. + | zone1 | zone2 | zone3 | + | P P | P P | P | + - if MaxSkew is 1, incoming pod can only be scheduled to zone3 to become 2/2/2; + scheduling it onto zone1(zone2) would make the ActualSkew(3-1) on zone1(zone2) + violate MaxSkew(1). + - if MaxSkew is 2, incoming pod can be scheduled onto any zone. + When `whenUnsatisfiable=ScheduleAnyway`, it is used to give higher precedence + to topologies that satisfy it. + It's a required field. Default value is 1 and 0 is not allowed. + format: int32 + type: integer + minDomains: + description: |- + MinDomains indicates a minimum number of eligible domains. + When the number of eligible domains with matching topology keys is less than minDomains, + Pod Topology Spread treats "global minimum" as 0, and then the calculation of Skew is performed. + And when the number of eligible domains with matching topology keys equals or greater than minDomains, + this value has no effect on scheduling. + As a result, when the number of eligible domains is less than minDomains, + scheduler won't schedule more than maxSkew Pods to those domains. + If value is nil, the constraint behaves as if MinDomains is equal to 1. + Valid values are integers greater than 0. + When value is not nil, WhenUnsatisfiable must be DoNotSchedule. + + + For example, in a 3-zone cluster, MaxSkew is set to 2, MinDomains is set to 5 and pods with the same + labelSelector spread as 2/2/2: + | zone1 | zone2 | zone3 | + | P P | P P | P P | + The number of domains is less than 5(MinDomains), so "global minimum" is treated as 0. + In this situation, new pod with the same labelSelector cannot be scheduled, + because computed skew will be 3(3 - 0) if new Pod is scheduled to any of the three zones, + it will violate MaxSkew. + + + This is a beta field and requires the MinDomainsInPodTopologySpread feature gate to be enabled (enabled by default). + format: int32 + type: integer + nodeAffinityPolicy: + description: |- + NodeAffinityPolicy indicates how we will treat Pod's nodeAffinity/nodeSelector + when calculating pod topology spread skew. Options are: + - Honor: only nodes matching nodeAffinity/nodeSelector are included in the calculations. + - Ignore: nodeAffinity/nodeSelector are ignored. All nodes are included in the calculations. + + + If this value is nil, the behavior is equivalent to the Honor policy. + This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag. + type: string + nodeTaintsPolicy: + description: |- + NodeTaintsPolicy indicates how we will treat node taints when calculating + pod topology spread skew. Options are: + - Honor: nodes without taints, along with tainted nodes for which the incoming pod + has a toleration, are included. + - Ignore: node taints are ignored. All nodes are included. + + + If this value is nil, the behavior is equivalent to the Ignore policy. + This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag. + type: string + topologyKey: + description: |- + TopologyKey is the key of node labels. Nodes that have a label with this key + and identical values are considered to be in the same topology. + We consider each as a "bucket", and try to put balanced number + of pods into each bucket. + We define a domain as a particular instance of a topology. + Also, we define an eligible domain as a domain whose nodes meet the requirements of + nodeAffinityPolicy and nodeTaintsPolicy. + e.g. If TopologyKey is "kubernetes.io/hostname", each Node is a domain of that topology. + And, if TopologyKey is "topology.kubernetes.io/zone", each zone is a domain of that topology. + It's a required field. + type: string + whenUnsatisfiable: + description: |- + WhenUnsatisfiable indicates how to deal with a pod if it doesn't satisfy + the spread constraint. + - DoNotSchedule (default) tells the scheduler not to schedule it. + - ScheduleAnyway tells the scheduler to schedule the pod in any location, + but giving higher precedence to topologies that would help reduce the + skew. + A constraint is considered "Unsatisfiable" for an incoming pod + if and only if every possible node assignment for that pod would violate + "MaxSkew" on some topology. + For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same + labelSelector spread as 3/1/1: + | zone1 | zone2 | zone3 | + | P P P | P | P | + If WhenUnsatisfiable is set to DoNotSchedule, incoming pod can only be scheduled + to zone2(zone3) to become 3/2/1(3/1/2) as ActualSkew(2-1) on zone2(zone3) satisfies + MaxSkew(1). In other words, the cluster can still be imbalanced, but scheduler + won't make it *more* imbalanced. + It's a required field. + type: string + required: + - maxSkew + - topologyKey + - whenUnsatisfiable + type: object + type: array + x-kubernetes-list-map-keys: + - topologyKey + - whenUnsatisfiable + x-kubernetes-list-type: map + volumes: + description: |- + List of volumes that can be mounted by containers belonging to the pod. + More info: https://kubernetes.io/docs/concepts/storage/volumes + items: + description: Volume represents a named volume in a pod + that may be accessed by any container in the pod. + properties: + awsElasticBlockStore: + description: |- + awsElasticBlockStore represents an AWS Disk resource that is attached to a + kubelet's host machine and then exposed to the pod. + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + properties: + fsType: + description: |- + fsType is the filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + partition: + description: |- + partition is the partition in the volume that you want to mount. + If omitted, the default is to mount by volume name. + Examples: For volume /dev/sda1, you specify the partition as "1". + Similarly, the volume partition for /dev/sda is "0" (or you can leave the property empty). + format: int32 + type: integer + readOnly: + description: |- + readOnly value true will force the readOnly setting in VolumeMounts. + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + type: boolean + volumeID: + description: |- + volumeID is unique ID of the persistent disk resource in AWS (Amazon EBS volume). + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + type: string + required: + - volumeID + type: object + azureDisk: + description: azureDisk represents an Azure Data Disk + mount on the host and bind mount to the pod. + properties: + cachingMode: + description: 'cachingMode is the Host Caching + mode: None, Read Only, Read Write.' + type: string + diskName: + description: diskName is the Name of the data + disk in the blob storage + type: string + diskURI: + description: diskURI is the URI of data disk in + the blob storage + type: string + fsType: + description: |- + fsType is Filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + kind: + description: 'kind expected values are Shared: + multiple blob disks per storage account Dedicated: + single blob disk per storage account Managed: + azure managed data disk (only in managed availability + set). defaults to shared' + type: string + readOnly: + description: |- + readOnly Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + description: azureFile represents an Azure File Service + mount on the host and bind mount to the pod. + properties: + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretName: + description: secretName is the name of secret + that contains Azure Storage Account Name and + Key + type: string + shareName: + description: shareName is the azure share Name + type: string + required: + - secretName + - shareName + type: object + cephfs: + description: cephFS represents a Ceph FS mount on + the host that shares a pod's lifetime + properties: + monitors: + description: |- + monitors is Required: Monitors is a collection of Ceph monitors + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + items: + type: string + type: array + path: + description: 'path is Optional: Used as the mounted + root, rather than the full Ceph tree, default + is /' + type: string + readOnly: + description: |- + readOnly is Optional: Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + type: boolean + secretFile: + description: |- + secretFile is Optional: SecretFile is the path to key ring for User, default is /etc/ceph/user.secret + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + type: string + secretRef: + description: |- + secretRef is Optional: SecretRef is reference to the authentication secret for User, default is empty. + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + 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 + user: + description: |- + user is optional: User is the rados user name, default is admin + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + type: string + required: + - monitors + type: object + cinder: + description: |- + cinder represents a cinder volume attached and mounted on kubelets host machine. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + type: string + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + type: boolean + secretRef: + description: |- + secretRef is optional: points to a secret object containing parameters used to connect + to OpenStack. + 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 + volumeID: + description: |- + volumeID used to identify the volume in cinder. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + type: string + required: + - volumeID + type: object + configMap: + description: configMap represents a configMap that + should populate this volume + properties: + defaultMode: + description: |- + defaultMode is optional: mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + items: + description: |- + items if unspecified, each key-value pair in the Data field of the referenced + ConfigMap will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the ConfigMap, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within + a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + 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 + optional: + description: optional specify whether the ConfigMap + or its keys must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + csi: + description: csi (Container Storage Interface) represents + ephemeral storage that is handled by certain external + CSI drivers (Beta feature). + properties: + driver: + description: |- + driver is the name of the CSI driver that handles this volume. + Consult with your admin for the correct name as registered in the cluster. + type: string + fsType: + description: |- + fsType to mount. Ex. "ext4", "xfs", "ntfs". + If not provided, the empty value is passed to the associated CSI driver + which will determine the default filesystem to apply. + type: string + nodePublishSecretRef: + description: |- + nodePublishSecretRef is a reference to the secret object containing + sensitive information to pass to the CSI driver to complete the CSI + NodePublishVolume and NodeUnpublishVolume calls. + This field is optional, and may be empty if no secret is required. If the + secret object contains more than one secret, all secret references are passed. + 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 + readOnly: + description: |- + readOnly specifies a read-only configuration for the volume. + Defaults to false (read/write). + type: boolean + volumeAttributes: + additionalProperties: + type: string + description: |- + volumeAttributes stores driver-specific properties that are passed to the CSI + driver. Consult your driver's documentation for supported values. + type: object + required: + - driver + type: object + downwardAPI: + description: downwardAPI represents downward API about + the pod that should populate this volume + properties: + defaultMode: + description: |- + Optional: mode bits to use on created files by default. Must be a + Optional: mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + items: + description: Items is a list of downward API volume + file + items: + description: DownwardAPIVolumeFile represents + information to create the file containing + the pod field + properties: + fieldRef: + description: 'Required: Selects a field + of the pod: only annotations, labels, + name and namespace are supported.' + properties: + apiVersion: + description: Version of the schema the + FieldPath is written in terms of, + defaults to "v1". + type: string + fieldPath: + description: Path of the field to select + in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + description: |- + Optional: mode bits used to set permissions on this file, must be an octal value + between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: 'Required: Path is the relative + path name of the file to be created. Must + not be absolute or contain the ''..'' + path. Must be utf-8 encoded. The first + item of the relative path must not start + with ''..''' + type: string + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported. + properties: + containerName: + description: 'Container name: required + for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format + of the exposed resources, defaults + to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to + select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + type: object + emptyDir: + description: |- + emptyDir represents a temporary directory that shares a pod's lifetime. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir + properties: + medium: + description: |- + medium represents what type of storage medium should back this directory. + The default is "" which means to use the node's default medium. + Must be an empty string (default) or Memory. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + description: |- + sizeLimit is the total amount of local storage required for this EmptyDir volume. + The size limit is also applicable for memory medium. + The maximum usage on memory medium EmptyDir would be the minimum value between + the SizeLimit specified here and the sum of memory limits of all containers in a pod. + The default is nil which means that the limit is undefined. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + description: |- + ephemeral represents a volume that is handled by a cluster storage driver. + The volume's lifecycle is tied to the pod that defines it - it will be created before the pod starts, + and deleted when the pod is removed. + + + Use this if: + a) the volume is only needed while the pod runs, + b) features of normal volumes like restoring from snapshot or capacity + tracking are needed, + c) the storage driver is specified through a storage class, and + d) the storage driver supports dynamic volume provisioning through + a PersistentVolumeClaim (see EphemeralVolumeSource for more + information on the connection between this volume type + and PersistentVolumeClaim). + + + Use PersistentVolumeClaim or one of the vendor-specific + APIs for volumes that persist for longer than the lifecycle + of an individual pod. + + + Use CSI for light-weight local ephemeral volumes if the CSI driver is meant to + be used that way - see the documentation of the driver for + more information. + + + A pod can use both types of ephemeral volumes and + persistent volumes at the same time. + properties: + volumeClaimTemplate: + description: |- + Will be used to create a stand-alone PVC to provision the volume. + The pod in which this EphemeralVolumeSource is embedded will be the + owner of the PVC, i.e. the PVC will be deleted together with the + pod. The name of the PVC will be `-` where + `` is the name from the `PodSpec.Volumes` array + entry. Pod validation will reject the pod if the concatenated name + is not valid for a PVC (for example, too long). + + + An existing PVC with that name that is not owned by the pod + will *not* be used for the pod to avoid using an unrelated + volume by mistake. Starting the pod is then blocked until + the unrelated PVC is removed. If such a pre-created PVC is + meant to be used by the pod, the PVC has to updated with an + owner reference to the pod once the pod exists. Normally + this should not be necessary, but it may be useful when + manually reconstructing a broken cluster. + + + This field is read-only and no changes will be made by Kubernetes + to the PVC after it has been created. + + + Required, must not be nil. + properties: + metadata: + description: |- + May contain labels and annotations that will be copied into the PVC + when creating it. No other fields are allowed and will be rejected during + validation. + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + description: |- + The specification for the PersistentVolumeClaim. The entire content is + copied unchanged into the PVC that gets created from this + template. The same fields as in a PersistentVolumeClaim + are also valid here. + properties: + accessModes: + description: |- + accessModes contains the desired access modes the volume should have. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1 + items: + type: string + type: array + dataSource: + description: |- + dataSource field can be used to specify either: + * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) + * An existing PVC (PersistentVolumeClaim) + If the provisioner or an external controller can support the specified data source, + it will create a new volume based on the contents of the specified data source. + When the AnyVolumeDataSource feature gate is enabled, dataSource contents will be copied to dataSourceRef, + and dataSourceRef contents will be copied to dataSource when dataSourceRef.namespace is not specified. + If the namespace is specified, then dataSourceRef will not be copied to dataSource. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource + being referenced + type: string + name: + description: Name is the name of resource + being referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + description: |- + dataSourceRef specifies the object from which to populate the volume with data, if a non-empty + volume is desired. This may be any object from a non-empty API group (non + core object) or a PersistentVolumeClaim object. + When this field is specified, volume binding will only succeed if the type of + the specified object matches some installed volume populator or dynamic + provisioner. + This field will replace the functionality of the dataSource field and as such + if both fields are non-empty, they must have the same value. For backwards + compatibility, when namespace isn't specified in dataSourceRef, + both fields (dataSource and dataSourceRef) will be set to the same + value automatically if one of them is empty and the other is non-empty. + When namespace is specified in dataSourceRef, + dataSource isn't set to the same value and must be empty. + There are three important differences between dataSource and dataSourceRef: + * While dataSource only allows two specific types of objects, dataSourceRef + allows any non-core object, as well as PersistentVolumeClaim objects. + * While dataSource ignores disallowed values (dropping them), dataSourceRef + preserves all values, and generates an error if a disallowed value is + specified. + * While dataSource only allows local objects, dataSourceRef allows objects + in any namespaces. + (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled. + (Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource + being referenced + type: string + name: + description: Name is the name of resource + being referenced + type: string + namespace: + description: |- + Namespace is the namespace of resource being referenced + Note that when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details. + (Alpha) This field requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + type: string + required: + - kind + - name + type: object + resources: + description: |- + resources represents the minimum resources the volume should have. + If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements + that are lower than previous value but must still be higher than capacity recorded in the + status field of the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + selector: + description: selector is a label query + over volumes to consider for binding. + properties: + matchExpressions: + description: matchExpressions is a + list of label selector requirements. + The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + description: |- + storageClassName is the name of the StorageClass required by the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1 + type: string + volumeAttributesClassName: + description: |- + volumeAttributesClassName may be used to set the VolumeAttributesClass used by this claim. + If specified, the CSI driver will create or update the volume with the attributes defined + in the corresponding VolumeAttributesClass. This has a different purpose than storageClassName, + it can be changed after the claim is created. An empty string value means that no VolumeAttributesClass + will be applied to the claim but it's not allowed to reset this field to empty string once it is set. + If unspecified and the PersistentVolumeClaim is unbound, the default VolumeAttributesClass + will be set by the persistentvolume controller if it exists. + If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be + set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource + exists. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#volumeattributesclass + (Alpha) Using this field requires the VolumeAttributesClass feature gate to be enabled. + type: string + volumeMode: + description: |- + volumeMode defines what type of volume is required by the claim. + Value of Filesystem is implied when not included in claim spec. + type: string + volumeName: + description: volumeName is the binding + reference to the PersistentVolume backing + this claim. + type: string + type: object + required: + - spec + type: object + type: object + fc: + description: fc represents a Fibre Channel resource + that is attached to a kubelet's host machine and + then exposed to the pod. + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + lun: + description: 'lun is Optional: FC target lun number' + format: int32 + type: integer + readOnly: + description: |- + readOnly is Optional: Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + targetWWNs: + description: 'targetWWNs is Optional: FC target + worldwide names (WWNs)' + items: + type: string + type: array + wwids: + description: |- + wwids Optional: FC volume world wide identifiers (wwids) + Either wwids or combination of targetWWNs and lun must be set, but not both simultaneously. + items: + type: string + type: array + type: object + flexVolume: + description: |- + flexVolume represents a generic volume resource that is + provisioned/attached using an exec based plugin. + properties: + driver: + description: driver is the name of the driver + to use for this volume. + type: string + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". The default filesystem depends on FlexVolume script. + type: string + options: + additionalProperties: + type: string + description: 'options is Optional: this field + holds extra command options if any.' + type: object + readOnly: + description: |- + readOnly is Optional: defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: |- + secretRef is Optional: secretRef is reference to the secret object containing + sensitive information to pass to the plugin scripts. This may be + empty if no secret object is specified. If the secret object + contains more than one secret, all secrets are passed to the plugin + scripts. + 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 + required: + - driver + type: object + flocker: + description: flocker represents a Flocker volume attached + to a kubelet's host machine. This depends on the + Flocker control service being running + properties: + datasetName: + description: |- + datasetName is Name of the dataset stored as metadata -> name on the dataset for Flocker + should be considered as deprecated + type: string + datasetUUID: + description: datasetUUID is the UUID of the dataset. + This is unique identifier of a Flocker dataset + type: string + type: object + gcePersistentDisk: + description: |- + gcePersistentDisk represents a GCE Disk resource that is attached to a + kubelet's host machine and then exposed to the pod. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + properties: + fsType: + description: |- + fsType is filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + partition: + description: |- + partition is the partition in the volume that you want to mount. + If omitted, the default is to mount by volume name. + Examples: For volume /dev/sda1, you specify the partition as "1". + Similarly, the volume partition for /dev/sda is "0" (or you can leave the property empty). + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + format: int32 + type: integer + pdName: + description: |- + pdName is unique name of the PD resource in GCE. Used to identify the disk in GCE. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + type: string + readOnly: + description: |- + readOnly here will force the ReadOnly setting in VolumeMounts. + Defaults to false. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + type: boolean + required: + - pdName + type: object + gitRepo: + description: |- + gitRepo represents a git repository at a particular revision. + DEPRECATED: GitRepo is deprecated. To provision a container with a git repo, mount an + EmptyDir into an InitContainer that clones the repo using git, then mount the EmptyDir + into the Pod's container. + properties: + directory: + description: |- + directory is the target directory name. + Must not contain or start with '..'. If '.' is supplied, the volume directory will be the + git repository. Otherwise, if specified, the volume will contain the git repository in + the subdirectory with the given name. + type: string + repository: + description: repository is the URL + type: string + revision: + description: revision is the commit hash for the + specified revision. + type: string + required: + - repository + type: object + glusterfs: + description: |- + glusterfs represents a Glusterfs mount on the host that shares a pod's lifetime. + More info: https://examples.k8s.io/volumes/glusterfs/README.md + properties: + endpoints: + description: |- + endpoints is the endpoint name that details Glusterfs topology. + More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod + type: string + path: + description: |- + path is the Glusterfs volume path. + More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod + type: string + readOnly: + description: |- + readOnly here will force the Glusterfs volume to be mounted with read-only permissions. + Defaults to false. + More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod + type: boolean + required: + - endpoints + - path + type: object + hostPath: + description: |- + hostPath represents a pre-existing file or directory on the host + machine that is directly exposed to the container. This is generally + used for system agents or other privileged things that are allowed + to see the host machine. Most containers will NOT need this. + More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + --- + TODO(jonesdl) We need to restrict who can use host directory mounts and who can/can not + mount host directories as read/write. + properties: + path: + description: |- + path of the directory on the host. + If the path is a symlink, it will follow the link to the real path. + More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + type: string + type: + description: |- + type for HostPath Volume + Defaults to "" + More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + type: string + required: + - path + type: object + iscsi: + description: |- + iscsi represents an ISCSI Disk resource that is attached to a + kubelet's host machine and then exposed to the pod. + More info: https://examples.k8s.io/volumes/iscsi/README.md + properties: + chapAuthDiscovery: + description: chapAuthDiscovery defines whether + support iSCSI Discovery CHAP authentication + type: boolean + chapAuthSession: + description: chapAuthSession defines whether support + iSCSI Session CHAP authentication + type: boolean + fsType: + description: |- + fsType is the filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#iscsi + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + initiatorName: + description: |- + initiatorName is the custom iSCSI Initiator Name. + If initiatorName is specified with iscsiInterface simultaneously, new iSCSI interface + : will be created for the connection. + type: string + iqn: + description: iqn is the target iSCSI Qualified + Name. + type: string + iscsiInterface: + description: |- + iscsiInterface is the interface Name that uses an iSCSI transport. + Defaults to 'default' (tcp). + type: string + lun: + description: lun represents iSCSI Target Lun number. + format: int32 + type: integer + portals: + description: |- + portals is the iSCSI Target Portal List. The portal is either an IP or ip_addr:port if the port + is other than default (typically TCP ports 860 and 3260). + items: + type: string + type: array + readOnly: + description: |- + readOnly here will force the ReadOnly setting in VolumeMounts. + Defaults to false. + type: boolean + secretRef: + description: secretRef is the CHAP Secret for + iSCSI target and initiator authentication + 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 + targetPortal: + description: |- + targetPortal is iSCSI Target Portal. The Portal is either an IP or ip_addr:port if the port + is other than default (typically TCP ports 860 and 3260). + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + description: |- + name of the volume. + Must be a DNS_LABEL and unique within the pod. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + nfs: + description: |- + nfs represents an NFS mount on the host that shares a pod's lifetime + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + properties: + path: + description: |- + path that is exported by the NFS server. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + type: string + readOnly: + description: |- + readOnly here will force the NFS export to be mounted with read-only permissions. + Defaults to false. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + type: boolean + server: + description: |- + server is the hostname or IP address of the NFS server. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + description: |- + persistentVolumeClaimVolumeSource represents a reference to a + PersistentVolumeClaim in the same namespace. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims + properties: + claimName: + description: |- + claimName is the name of a PersistentVolumeClaim in the same namespace as the pod using this volume. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims + type: string + readOnly: + description: |- + readOnly Will force the ReadOnly setting in VolumeMounts. + Default false. + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + description: photonPersistentDisk represents a PhotonController + persistent disk attached and mounted on kubelets + host machine + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + pdID: + description: pdID is the ID that identifies Photon + Controller persistent disk + type: string + required: + - pdID + type: object + portworxVolume: + description: portworxVolume represents a portworx + volume attached and mounted on kubelets host machine + properties: + fsType: + description: |- + fSType represents the filesystem type to mount + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs". Implicitly inferred to be "ext4" if unspecified. + type: string + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + volumeID: + description: volumeID uniquely identifies a Portworx + volume + type: string + required: + - volumeID + type: object + projected: + description: projected items for all in one resources + secrets, configmaps, and downward API + properties: + defaultMode: + description: |- + defaultMode are the mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + sources: + description: sources is the list of volume projections + items: + description: Projection that may be projected + along with other supported volume types + properties: + clusterTrustBundle: + description: |- + ClusterTrustBundle allows a pod to access the `.spec.trustBundle` field + of ClusterTrustBundle objects in an auto-updating file. + + + Alpha, gated by the ClusterTrustBundleProjection feature gate. + + + ClusterTrustBundle objects can either be selected by name, or by the + combination of signer name and a label selector. + + + Kubelet performs aggressive normalization of the PEM contents written + into the pod filesystem. Esoteric PEM features such as inter-block + comments and block headers are stripped. Certificates are deduplicated. + The ordering of certificates within the file is arbitrary, and Kubelet + may change the order over time. + properties: + labelSelector: + description: |- + Select all ClusterTrustBundles that match this label selector. Only has + effect if signerName is set. Mutually-exclusive with name. If unset, + interpreted as "match nothing". If set but empty, interpreted as "match + everything". + properties: + matchExpressions: + description: matchExpressions is + a list of label selector requirements. + The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + name: + description: |- + Select a single ClusterTrustBundle by object name. Mutually-exclusive + with signerName and labelSelector. + type: string + optional: + description: |- + If true, don't block pod startup if the referenced ClusterTrustBundle(s) + aren't available. If using name, then the named ClusterTrustBundle is + allowed not to exist. If using signerName, then the combination of + signerName and labelSelector is allowed to match zero + ClusterTrustBundles. + type: boolean + path: + description: Relative path from the + volume root to write the bundle. + type: string + signerName: + description: |- + Select all ClusterTrustBundles that match this signer name. + Mutually-exclusive with name. The contents of all selected + ClusterTrustBundles will be unified and deduplicated. + type: string + required: + - path + type: object + configMap: + description: configMap information about + the configMap data to project + properties: + items: + description: |- + items if unspecified, each key-value pair in the Data field of the referenced + ConfigMap will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the ConfigMap, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to + a path within a volume. + properties: + key: + description: key is the key to + project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + 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 + optional: + description: optional specify whether + the ConfigMap or its keys must be + defined + type: boolean + type: object + x-kubernetes-map-type: atomic + downwardAPI: + description: downwardAPI information about + the downwardAPI data to project + properties: + items: + description: Items is a list of DownwardAPIVolume + file + items: + description: DownwardAPIVolumeFile + represents information to create + the file containing the pod field + properties: + fieldRef: + description: 'Required: Selects + a field of the pod: only annotations, + labels, name and namespace are + supported.' + properties: + apiVersion: + description: Version of the + schema the FieldPath is + written in terms of, defaults + to "v1". + type: string + fieldPath: + description: Path of the field + to select in the specified + API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + description: |- + Optional: mode bits used to set permissions on this file, must be an octal value + between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: 'Required: Path is the + relative path name of the file + to be created. Must not be absolute + or contain the ''..'' path. + Must be utf-8 encoded. The first + item of the relative path must + not start with ''..''' + type: string + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported. + properties: + containerName: + description: 'Container name: + required for volumes, optional + for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the + output format of the exposed + resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource + to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + type: object + secret: + description: secret information about the + secret data to project + properties: + items: + description: |- + items if unspecified, each key-value pair in the Data field of the referenced + Secret will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the Secret, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to + a path within a volume. + properties: + key: + description: key is the key to + project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + 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 + optional: + description: optional field specify + whether the Secret or its key must + be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + serviceAccountToken: + description: serviceAccountToken is information + about the serviceAccountToken data to + project + properties: + audience: + description: |- + audience is the intended audience of the token. A recipient of a token + must identify itself with an identifier specified in the audience of the + token, and otherwise should reject the token. The audience defaults to the + identifier of the apiserver. + type: string + expirationSeconds: + description: |- + expirationSeconds is the requested duration of validity of the service + account token. As the token approaches expiration, the kubelet volume + plugin will proactively rotate the service account token. The kubelet will + start trying to rotate the token if the token is older than 80 percent of + its time to live or if the token is older than 24 hours.Defaults to 1 hour + and must be at least 10 minutes. + format: int64 + type: integer + path: + description: |- + path is the path relative to the mount point of the file to project the + token into. + type: string + required: + - path + type: object + type: object + type: array + type: object + quobyte: + description: quobyte represents a Quobyte mount on + the host that shares a pod's lifetime + properties: + group: + description: |- + group to map volume access to + Default is no group + type: string + readOnly: + description: |- + readOnly here will force the Quobyte volume to be mounted with read-only permissions. + Defaults to false. + type: boolean + registry: + description: |- + registry represents a single or multiple Quobyte Registry services + specified as a string as host:port pair (multiple entries are separated with commas) + which acts as the central registry for volumes + type: string + tenant: + description: |- + tenant owning the given Quobyte volume in the Backend + Used with dynamically provisioned Quobyte volumes, value is set by the plugin + type: string + user: + description: |- + user to map volume access to + Defaults to serivceaccount user + type: string + volume: + description: volume is a string that references + an already created Quobyte volume by name. + type: string + required: + - registry + - volume + type: object + rbd: + description: |- + rbd represents a Rados Block Device mount on the host that shares a pod's lifetime. + More info: https://examples.k8s.io/volumes/rbd/README.md + properties: + fsType: + description: |- + fsType is the filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#rbd + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + image: + description: |- + image is the rados image name. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + keyring: + description: |- + keyring is the path to key ring for RBDUser. + Default is /etc/ceph/keyring. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + monitors: + description: |- + monitors is a collection of Ceph monitors. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + items: + type: string + type: array + pool: + description: |- + pool is the rados pool name. + Default is rbd. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + readOnly: + description: |- + readOnly here will force the ReadOnly setting in VolumeMounts. + Defaults to false. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: boolean + secretRef: + description: |- + secretRef is name of the authentication secret for RBDUser. If provided + overrides keyring. + Default is nil. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + 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 + user: + description: |- + user is the rados user name. + Default is admin. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + required: + - image + - monitors + type: object + scaleIO: + description: scaleIO represents a ScaleIO persistent + volume attached and mounted on Kubernetes nodes. + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". + Default is "xfs". + type: string + gateway: + description: gateway is the host address of the + ScaleIO API Gateway. + type: string + protectionDomain: + description: protectionDomain is the name of the + ScaleIO Protection Domain for the configured + storage. + type: string + readOnly: + description: |- + readOnly Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: |- + secretRef references to the secret for ScaleIO user and other + sensitive information. If this is not provided, Login operation will fail. + 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 + sslEnabled: + description: sslEnabled Flag enable/disable SSL + communication with Gateway, default false + type: boolean + storageMode: + description: |- + storageMode indicates whether the storage for a volume should be ThickProvisioned or ThinProvisioned. + Default is ThinProvisioned. + type: string + storagePool: + description: storagePool is the ScaleIO Storage + Pool associated with the protection domain. + type: string + system: + description: system is the name of the storage + system as configured in ScaleIO. + type: string + volumeName: + description: |- + volumeName is the name of a volume already created in the ScaleIO system + that is associated with this volume source. + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + description: |- + secret represents a secret that should populate this volume. + More info: https://kubernetes.io/docs/concepts/storage/volumes#secret + properties: + defaultMode: + description: |- + defaultMode is Optional: mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values + for mode bits. Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + items: + description: |- + items If unspecified, each key-value pair in the Data field of the referenced + Secret will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the Secret, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within + a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + optional: + description: optional field specify whether the + Secret or its keys must be defined + type: boolean + secretName: + description: |- + secretName is the name of the secret in the pod's namespace to use. + More info: https://kubernetes.io/docs/concepts/storage/volumes#secret + type: string + type: object + storageos: + description: storageOS represents a StorageOS volume + attached and mounted on Kubernetes nodes. + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: |- + secretRef specifies the secret to use for obtaining the StorageOS API + credentials. If not specified, default values will be attempted. + 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 + volumeName: + description: |- + volumeName is the human-readable name of the StorageOS volume. Volume + names are only unique within a namespace. + type: string + volumeNamespace: + description: |- + volumeNamespace specifies the scope of the volume within StorageOS. If no + namespace is specified then the Pod's namespace will be used. This allows the + Kubernetes name scoping to be mirrored within StorageOS for tighter integration. + Set VolumeName to any name to override the default behaviour. + Set to "default" if you are not using namespaces within StorageOS. + Namespaces that do not pre-exist within StorageOS will be created. + type: string + type: object + vsphereVolume: + description: vsphereVolume represents a vSphere volume + attached and mounted on kubelets host machine + properties: + fsType: + description: |- + fsType is filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + storagePolicyID: + description: storagePolicyID is the storage Policy + Based Management (SPBM) profile ID associated + with the StoragePolicyName. + type: string + storagePolicyName: + description: storagePolicyName is the storage + Policy Based Management (SPBM) profile name. + type: string + volumePath: + description: volumePath is the path that identifies + vSphere volume vmdk + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + required: + - containers + type: object + x-kubernetes-preserve-unknown-fields: true + postStartSpec: + description: |- + Defines the command to be executed when the component is ready, and the command will only be executed once after + the component becomes ready. + properties: + cmdExecutorConfig: + description: Specifies the post-start command to be executed. + properties: + args: + description: Additional parameters used in the execution + of the command. + items: + type: string + type: array + command: + description: The command to be executed. + items: + type: string + minItems: 1 + type: array + env: + description: A list of environment variables that will + be injected into the command execution context. + items: + description: EnvVar represents an environment variable + present in a Container. + properties: + name: + description: Name of the environment variable. + Must be a C_IDENTIFIER. + type: string + value: + description: |- + Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in the container and + any service environment variables. If a variable cannot be resolved, + the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless of whether the variable + exists or not. + Defaults to "". + type: string + valueFrom: + description: Source for the environment variable's + value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the + FieldPath is written in terms of, defaults + to "v1". + type: string + fieldPath: + description: Path of the field to select + in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required + for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format + of the exposed resources, defaults to + "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in + the pod's namespace + properties: + key: + description: The key of the secret to + select from. Must be a valid secret + key. + type: string + 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 + optional: + description: Specify whether the Secret + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + x-kubernetes-preserve-unknown-fields: true + image: + description: Specifies the image used to execute the + command. + type: string + required: + - command + - image + type: object + scriptSpecSelectors: + description: |- + Used to select the script that need to be referenced. + When defined, the scripts defined in scriptSpecs can be referenced within the CmdExecutorConfig. + items: + properties: + name: + description: Represents the name of the ScriptSpec + referent. + maxLength: 63 + pattern: ^[a-z0-9]([a-z0-9\.\-]*[a-z0-9])?$ + type: string + required: + - name + type: object + type: array + required: + - cmdExecutorConfig + type: object + probes: + description: Settings for health checks. + properties: + roleProbe: + description: Specifies the probe used for checking the role + of the component. + properties: + commands: + description: Commands used to execute for probe. + properties: + queries: + description: Defines read checks that are executed + on the probe sidecar. + items: + type: string + type: array + writes: + description: Defines write checks that are executed + on the probe sidecar. + items: + type: string + type: array + type: object + failureThreshold: + default: 3 + description: Minimum consecutive failures for the probe + to be considered failed after having succeeded. + format: int32 + minimum: 2 + type: integer + periodSeconds: + default: 1 + description: How often (in seconds) to perform the probe. + format: int32 + minimum: 1 + type: integer + timeoutSeconds: + default: 1 + description: Number of seconds after which the probe + times out. Defaults to 1 second. + format: int32 + minimum: 1 + type: integer + type: object + roleProbeTimeoutAfterPodsReady: + description: |- + Defines the timeout (in seconds) for the role probe after all pods of the component are ready. + The system will check if the application is available in the pod. + If pods exceed the InitializationTimeoutSeconds time without a role label, this component will enter the + Failed/Abnormal phase. + + + Note that this configuration will only take effect if the component supports RoleProbe + and will not affect the life cycle of the pod. default values are 60 seconds. + format: int32 + minimum: 30 + type: integer + runningProbe: + description: Specifies the probe used for checking the running + status of the component. + properties: + commands: + description: Commands used to execute for probe. + properties: + queries: + description: Defines read checks that are executed + on the probe sidecar. + items: + type: string + type: array + writes: + description: Defines write checks that are executed + on the probe sidecar. + items: + type: string + type: array + type: object + failureThreshold: + default: 3 + description: Minimum consecutive failures for the probe + to be considered failed after having succeeded. + format: int32 + minimum: 2 + type: integer + periodSeconds: + default: 1 + description: How often (in seconds) to perform the probe. + format: int32 + minimum: 1 + type: integer + timeoutSeconds: + default: 1 + description: Number of seconds after which the probe + times out. Defaults to 1 second. + format: int32 + minimum: 1 + type: integer + type: object + statusProbe: + description: Specifies the probe used for checking the status + of the component. + properties: + commands: + description: Commands used to execute for probe. + properties: + queries: + description: Defines read checks that are executed + on the probe sidecar. + items: + type: string + type: array + writes: + description: Defines write checks that are executed + on the probe sidecar. + items: + type: string + type: array + type: object + failureThreshold: + default: 3 + description: Minimum consecutive failures for the probe + to be considered failed after having succeeded. + format: int32 + minimum: 2 + type: integer + periodSeconds: + default: 1 + description: How often (in seconds) to perform the probe. + format: int32 + minimum: 1 + type: integer + timeoutSeconds: + default: 1 + description: Number of seconds after which the probe + times out. Defaults to 1 second. + format: int32 + minimum: 1 + type: integer + type: object + type: object + replicationSpec: + description: Defines spec for `Replication` workloads. + properties: + llPodManagementPolicy: + description: |- + Controls the creation of pods during initial scale up, replacement of pods on nodes, and scaling down. + + + - `OrderedReady`: Creates pods in increasing order (pod-0, then pod-1, etc). The controller waits until each pod + is ready before continuing. Pods are removed in reverse order when scaling down. + - `Parallel`: Creates pods in parallel to match the desired scale without waiting. All pods are deleted at once + when scaling down. + type: string + llUpdateStrategy: + description: |- + Specifies the low-level StatefulSetUpdateStrategy to be used when updating Pods in the StatefulSet upon a + revision to the Template. + `UpdateStrategy` will be ignored if this is provided. + properties: + rollingUpdate: + description: RollingUpdate is used to communicate parameters + when Type is RollingUpdateStatefulSetStrategyType. + properties: + maxUnavailable: + anyOf: + - type: integer + - type: string + description: |- + The maximum number of pods that can be unavailable during the update. + Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). + Absolute number is calculated from percentage by rounding up. This can not be 0. + Defaults to 1. This field is alpha-level and is only honored by servers that enable the + MaxUnavailableStatefulSet feature. The field applies to all pods in the range 0 to + Replicas-1. That means if there is any unavailable pod in the range 0 to Replicas-1, it + will be counted towards MaxUnavailable. + x-kubernetes-int-or-string: true + partition: + description: |- + Partition indicates the ordinal at which the StatefulSet should be partitioned + for updates. During a rolling update, all pods from ordinal Replicas-1 to + Partition are updated. All pods from ordinal Partition-1 to 0 remain untouched. + This is helpful in being able to do a canary based deployment. The default value is 0. + format: int32 + type: integer + type: object + type: + description: |- + Type indicates the type of the StatefulSetUpdateStrategy. + Default is RollingUpdate. + type: string + type: object + updateStrategy: + default: Serial + description: |- + Specifies the strategy for updating Pods. + For workloadType=`Consensus`, the update strategy can be one of the following: + + + - `Serial`: Updates Members sequentially to minimize component downtime. + - `BestEffortParallel`: Updates Members in parallel to minimize component write downtime. Majority remains online + at all times. + - `Parallel`: Forces parallel updates. + enum: + - Serial + - BestEffortParallel + - Parallel + type: string + type: object + rsmSpec: + description: |- + Defines workload spec of this component. + From KB 0.7.0, RSM(InstanceSetSpec) will be the underlying CR which powers all kinds of workload in KB. + RSM is an enhanced stateful workload extension dedicated for heavy-state workloads like databases. + properties: + memberUpdateStrategy: + description: |- + Describes the strategy for updating Members (Pods). + + + - `Serial`: Updates Members sequentially to ensure minimum component downtime. + - `BestEffortParallel`: Updates Members in parallel to ensure minimum component write downtime. + - `Parallel`: Forces parallel updates. + enum: + - Serial + - BestEffortParallel + - Parallel + type: string + membershipReconfiguration: + description: Indicates the actions required for dynamic + membership reconfiguration. + properties: + logSyncAction: + description: |- + Defines the action to trigger the new member to start log syncing. + If the Image is not configured, the Image from the previous non-nil action will be used. + properties: + args: + description: Additional parameters used to perform + specific statements. This field is optional. + items: + type: string + type: array + command: + description: A set of instructions that will be + executed within the Container to retrieve or process + role information. This field is required. + items: + type: string + type: array + image: + description: Refers to the utility image that contains + the command which can be utilized to retrieve + or process role information. + type: string + required: + - command + type: object + memberJoinAction: + description: |- + Defines the action to add a member. + If the Image is not configured, the Image from the previous non-nil action will be used. + properties: + args: + description: Additional parameters used to perform + specific statements. This field is optional. + items: + type: string + type: array + command: + description: A set of instructions that will be + executed within the Container to retrieve or process + role information. This field is required. + items: + type: string + type: array + image: + description: Refers to the utility image that contains + the command which can be utilized to retrieve + or process role information. + type: string + required: + - command + type: object + memberLeaveAction: + description: |- + Defines the action to remove a member. + If the Image is not configured, the Image from the previous non-nil action will be used. + properties: + args: + description: Additional parameters used to perform + specific statements. This field is optional. + items: + type: string + type: array + command: + description: A set of instructions that will be + executed within the Container to retrieve or process + role information. This field is required. + items: + type: string + type: array + image: + description: Refers to the utility image that contains + the command which can be utilized to retrieve + or process role information. + type: string + required: + - command + type: object + promoteAction: + description: |- + Defines the action to inform the cluster that the new member can join voting now. + If the Image is not configured, the Image from the previous non-nil action will be used. + properties: + args: + description: Additional parameters used to perform + specific statements. This field is optional. + items: + type: string + type: array + command: + description: A set of instructions that will be + executed within the Container to retrieve or process + role information. This field is required. + items: + type: string + type: array + image: + description: Refers to the utility image that contains + the command which can be utilized to retrieve + or process role information. + type: string + required: + - command + type: object + switchoverAction: + description: |- + Specifies the environment variables that can be used in all following Actions: + - KB_ITS_USERNAME: Represents the username part of the credential + - KB_ITS_PASSWORD: Represents the password part of the credential + - KB_ITS_LEADER_HOST: Represents the leader host + - KB_ITS_TARGET_HOST: Represents the target host + - KB_ITS_SERVICE_PORT: Represents the service port + + + Defines the action to perform a switchover. + If the Image is not configured, the latest [BusyBox](https://busybox.net/) image will be used. + properties: + args: + description: Additional parameters used to perform + specific statements. This field is optional. + items: + type: string + type: array + command: + description: A set of instructions that will be + executed within the Container to retrieve or process + role information. This field is required. + items: + type: string + type: array + image: + description: Refers to the utility image that contains + the command which can be utilized to retrieve + or process role information. + type: string + required: + - command + type: object + type: object + roleProbe: + description: Defines the method used to probe a role. + properties: + customHandler: + description: |- + Defines a custom method for role probing. + Actions defined here are executed in series. + Upon completion of all actions, the final output should be a single string representing the role name defined in spec.Roles. + The latest [BusyBox](https://busybox.net/) image will be used if Image is not configured. + Environment variables can be used in Command: + - v_KB_ITS_LAST_STDOUT: stdout from the last action, watch for 'v_' prefix + - KB_ITS_USERNAME: username part of the credential + - KB_ITS_PASSWORD: password part of the credential + items: + properties: + args: + description: Additional parameters used to perform + specific statements. This field is optional. + items: + type: string + type: array + command: + description: A set of instructions that will be + executed within the Container to retrieve or + process role information. This field is required. + items: + type: string + type: array + image: + description: Refers to the utility image that + contains the command which can be utilized to + retrieve or process role information. + type: string + required: + - command + type: object + type: array + failureThreshold: + default: 3 + description: Specifies the minimum number of consecutive + failures for the probe to be considered failed after + having succeeded. + format: int32 + minimum: 1 + type: integer + initialDelaySeconds: + default: 0 + description: Specifies the number of seconds to wait + after the container has started before initiating + role probing. + format: int32 + minimum: 0 + type: integer + periodSeconds: + default: 2 + description: Specifies the frequency (in seconds) of + probe execution. + format: int32 + minimum: 1 + type: integer + roleUpdateMechanism: + default: ReadinessProbeEventUpdate + description: Specifies the method for updating the pod + role label. + enum: + - ReadinessProbeEventUpdate + - DirectAPIServerEventUpdate + type: string + successThreshold: + default: 1 + description: Specifies the minimum number of consecutive + successes for the probe to be considered successful + after having failed. + format: int32 + minimum: 1 + type: integer + timeoutSeconds: + default: 1 + description: Specifies the number of seconds after which + the probe times out. + format: int32 + minimum: 1 + type: integer + type: object + roles: + description: Specifies a list of roles defined within the + system. + items: + properties: + accessMode: + default: ReadWrite + description: Specifies the service capabilities of + this member. + enum: + - None + - Readonly + - ReadWrite + type: string + canVote: + default: true + description: Indicates if this member has voting rights. + type: boolean + isLeader: + default: false + description: Determines if this member is the leader. + type: boolean + name: + default: leader + description: Defines the role name of the replica. + type: string + required: + - accessMode + - name + type: object + type: array + type: object + scriptSpecs: + description: Defines the template of scripts. + items: + properties: + defaultMode: + description: |- + The operator attempts to set default file permissions for scripts (0555) and configurations (0444). + However, certain database engines may require different file permissions. + You can specify the desired file permissions here. + + + Must be specified as an octal value between 0000 and 0777 (inclusive), + or as a decimal value between 0 and 511 (inclusive). + YAML supports both octal and decimal values for file permissions. + + + Please note that this setting only affects the permissions of the files themselves. + Directories within the specified path are not impacted by this setting. + It's important to be aware that this setting might conflict with other options + that influence the file mode, such as fsGroup. + In such cases, the resulting file mode may have additional bits set. + Refers to documents of k8s.ConfigMapVolumeSource.defaultMode for more information. + format: int32 + type: integer + name: + description: Specifies the name of the configuration template. + maxLength: 63 + pattern: ^[a-z0-9]([a-z0-9\.\-]*[a-z0-9])?$ + type: string + namespace: + default: default + description: |- + Specifies the namespace of the referenced configuration template ConfigMap object. + An empty namespace is equivalent to the "default" namespace. + maxLength: 63 + pattern: ^[a-z0-9]([a-z0-9\-]*[a-z0-9])?$ + type: string + templateRef: + description: Specifies the name of the referenced configuration + template ConfigMap object. + maxLength: 63 + pattern: ^[a-z0-9]([a-z0-9\.\-]*[a-z0-9])?$ + type: string + volumeName: + description: |- + Refers to the volume name of PodTemplate. The configuration file produced through the configuration + template will be mounted to the corresponding volume. Must be a DNS_LABEL name. + The volume name must be defined in podSpec.containers[*].volumeMounts. + maxLength: 63 + pattern: ^[a-z]([a-z0-9\-]*[a-z0-9])?$ + type: string + required: + - name + - volumeName + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + service: + description: Defines the service spec. + properties: + ports: + description: |- + The list of ports that are exposed by this service. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + items: + description: ServicePort is deprecated since v0.8. + properties: + appProtocol: + description: |- + The application protocol for this port. + This field follows standard Kubernetes label syntax. + Un-prefixed names are reserved for IANA standard service names (as per + RFC-6335 and https://www.iana.org/assignments/service-names). + Non-standard protocols should use prefixed names such as + mycompany.com/my-custom-protocol. + type: string + name: + description: |- + The name of this port within the service. This must be a DNS_LABEL. + All ports within a ServiceSpec must have unique names. When considering + the endpoints for a Service, this must match the 'name' field in the + EndpointPort. + type: string + port: + description: The port that will be exposed by this + service. + format: int32 + type: integer + protocol: + default: TCP + description: |- + The IP protocol for this port. Supports "TCP", "UDP", and "SCTP". + Default is TCP. + enum: + - TCP + - UDP + - SCTP + type: string + targetPort: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the pods targeted by the service. + + + Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + + + - If this is a string, it will be looked up as a named port in the target Pod's container ports. + - If this is not specified, the value of the `port` field is used (an identity map). + + + This field is ignored for services with clusterIP=None, and should be + omitted or set equal to the `port` field. + + + More info: https://kubernetes.io/docs/concepts/services-networking/service/#defining-a-service + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-map-keys: + - port + - protocol + x-kubernetes-list-type: map + type: object + serviceRefDeclarations: + description: Used to declare the service reference of the current + component. + items: + description: |- + ServiceRefDeclaration represents a reference to a service that can be either provided by a KubeBlocks Cluster + or an external service. + It acts as a placeholder for the actual service reference, which is determined later when a Cluster is created. + + + The purpose of ServiceRefDeclaration is to declare a service dependency without specifying the concrete details + of the service. + It allows for flexibility and abstraction in defining service references within a Component. + By using ServiceRefDeclaration, you can define service dependencies in a declarative manner, enabling loose coupling + and easier management of service references across different components and clusters. + + + Upon Cluster creation, the ServiceRefDeclaration is bound to an actual service through the ServiceRef field, + effectively resolving and connecting to the specified service. + properties: + name: + description: Specifies the name of the ServiceRefDeclaration. + type: string + optional: + description: |- + Specifies whether the service reference can be optional. + + + For an optional service-ref, the component can still be created even if the service-ref is not provided. + type: boolean + serviceRefDeclarationSpecs: + description: |- + Defines a list of constraints and requirements for services that can be bound to this ServiceRefDeclaration + upon Cluster creation. + Each ServiceRefDeclarationSpec defines a ServiceKind and ServiceVersion, + outlining the acceptable service types and versions that are compatible. + + + This flexibility allows a ServiceRefDeclaration to be fulfilled by any one of the provided specs. + For example, if it requires an OLTP database, specs for both MySQL and PostgreSQL are listed, + either MySQL or PostgreSQL services can be used when binding. + items: + properties: + serviceKind: + description: |- + Specifies the type or nature of the service. This should be a well-known application cluster type, such as + {mysql, redis, mongodb}. + The field is case-insensitive and supports abbreviations for some well-known databases. + For instance, both `zk` and `zookeeper` are considered as a ZooKeeper cluster, while `pg`, `postgres`, `postgresql` + are all recognized as a PostgreSQL cluster. + type: string + serviceVersion: + description: |- + Defines the service version of the service reference. This is a regular expression that matches a version number pattern. + For instance, `^8.0.8$`, `8.0.\d{1,2}$`, `^[v\-]*?(\d{1,2}\.){0,3}\d{1,2}$` are all valid patterns. + type: string + required: + - serviceKind + - serviceVersion + type: object + type: array + required: + - name + - serviceRefDeclarationSpecs + type: object + type: array + statefulSpec: + description: Defines spec for `Stateful` workloads. + properties: + llPodManagementPolicy: + description: |- + Controls the creation of pods during initial scale up, replacement of pods on nodes, and scaling down. + + + - `OrderedReady`: Creates pods in increasing order (pod-0, then pod-1, etc). The controller waits until each pod + is ready before continuing. Pods are removed in reverse order when scaling down. + - `Parallel`: Creates pods in parallel to match the desired scale without waiting. All pods are deleted at once + when scaling down. + type: string + llUpdateStrategy: + description: |- + Specifies the low-level StatefulSetUpdateStrategy to be used when updating Pods in the StatefulSet upon a + revision to the Template. + `UpdateStrategy` will be ignored if this is provided. + properties: + rollingUpdate: + description: RollingUpdate is used to communicate parameters + when Type is RollingUpdateStatefulSetStrategyType. + properties: + maxUnavailable: + anyOf: + - type: integer + - type: string + description: |- + The maximum number of pods that can be unavailable during the update. + Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). + Absolute number is calculated from percentage by rounding up. This can not be 0. + Defaults to 1. This field is alpha-level and is only honored by servers that enable the + MaxUnavailableStatefulSet feature. The field applies to all pods in the range 0 to + Replicas-1. That means if there is any unavailable pod in the range 0 to Replicas-1, it + will be counted towards MaxUnavailable. + x-kubernetes-int-or-string: true + partition: + description: |- + Partition indicates the ordinal at which the StatefulSet should be partitioned + for updates. During a rolling update, all pods from ordinal Replicas-1 to + Partition are updated. All pods from ordinal Partition-1 to 0 remain untouched. + This is helpful in being able to do a canary based deployment. The default value is 0. + format: int32 + type: integer + type: object + type: + description: |- + Type indicates the type of the StatefulSetUpdateStrategy. + Default is RollingUpdate. + type: string + type: object + updateStrategy: + default: Serial + description: |- + Specifies the strategy for updating Pods. + For workloadType=`Consensus`, the update strategy can be one of the following: + + + - `Serial`: Updates Members sequentially to minimize component downtime. + - `BestEffortParallel`: Updates Members in parallel to minimize component write downtime. Majority remains online + at all times. + - `Parallel`: Forces parallel updates. + enum: + - Serial + - BestEffortParallel + - Parallel + type: string + type: object + statelessSpec: + description: Defines spec for `Stateless` workloads. + properties: + updateStrategy: + description: Specifies the deployment strategy that will + be used to replace existing pods with new ones. + properties: + rollingUpdate: + description: |- + Rolling update config params. Present only if DeploymentStrategyType = + RollingUpdate. + --- + TODO: Update this to follow our convention for oneOf, whatever we decide it + to be. + properties: + maxSurge: + anyOf: + - type: integer + - type: string + description: |- + The maximum number of pods that can be scheduled above the desired number of + pods. + Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). + This can not be 0 if MaxUnavailable is 0. + Absolute number is calculated from percentage by rounding up. + Defaults to 25%. + Example: when this is set to 30%, the new ReplicaSet can be scaled up immediately when + the rolling update starts, such that the total number of old and new pods do not exceed + 130% of desired pods. Once old pods have been killed, + new ReplicaSet can be scaled up further, ensuring that total number of pods running + at any time during the update is at most 130% of desired pods. + x-kubernetes-int-or-string: true + maxUnavailable: + anyOf: + - type: integer + - type: string + description: |- + The maximum number of pods that can be unavailable during the update. + Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). + Absolute number is calculated from percentage by rounding down. + This can not be 0 if MaxSurge is 0. + Defaults to 25%. + Example: when this is set to 30%, the old ReplicaSet can be scaled down to 70% of desired pods + immediately when the rolling update starts. Once new pods are ready, old ReplicaSet + can be scaled down further, followed by scaling up the new ReplicaSet, ensuring + that the total number of pods available at all times during the update is at + least 70% of desired pods. + x-kubernetes-int-or-string: true + type: object + type: + description: Type of deployment. Can be "Recreate" or + "RollingUpdate". Default is RollingUpdate. + type: string + type: object + type: object + switchoverSpec: + description: |- + Defines command to do switchover. + In particular, when workloadType=Replication, the command defined in switchoverSpec will only be executed under + the condition of cluster.componentSpecs[x].SwitchPolicy.type=Noop. + properties: + withCandidate: + description: Represents the action of switching over to + a specified candidate primary or leader instance. + properties: + cmdExecutorConfig: + description: Specifies the switchover command. + properties: + args: + description: Additional parameters used in the execution + of the command. + items: + type: string + type: array + command: + description: The command to be executed. + items: + type: string + minItems: 1 + type: array + env: + description: A list of environment variables that + will be injected into the command execution context. + items: + description: EnvVar represents an environment + variable present in a Container. + properties: + name: + description: Name of the environment variable. + Must be a C_IDENTIFIER. + type: string + value: + description: |- + Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in the container and + any service environment variables. If a variable cannot be resolved, + the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless of whether the variable + exists or not. + Defaults to "". + type: string + valueFrom: + description: Source for the environment variable's + value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema + the FieldPath is written in terms + of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to + select in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required + for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output + format of the exposed resources, + defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to + select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret + in the pod's namespace + properties: + key: + description: The key of the secret + to select from. Must be a valid + secret key. + type: string + 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 + optional: + description: Specify whether the Secret + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + x-kubernetes-preserve-unknown-fields: true + image: + description: Specifies the image used to execute + the command. + type: string + required: + - command + - image + type: object + scriptSpecSelectors: + description: |- + Used to select the script that need to be referenced. + When defined, the scripts defined in scriptSpecs can be referenced within the SwitchoverAction.CmdExecutorConfig. + items: + properties: + name: + description: Represents the name of the ScriptSpec + referent. + maxLength: 63 + pattern: ^[a-z0-9]([a-z0-9\.\-]*[a-z0-9])?$ + type: string + required: + - name + type: object + type: array + required: + - cmdExecutorConfig + type: object + withoutCandidate: + description: Represents the action of switching over without + specifying a candidate primary or leader instance. + properties: + cmdExecutorConfig: + description: Specifies the switchover command. + properties: + args: + description: Additional parameters used in the execution + of the command. + items: + type: string + type: array + command: + description: The command to be executed. + items: + type: string + minItems: 1 + type: array + env: + description: A list of environment variables that + will be injected into the command execution context. + items: + description: EnvVar represents an environment + variable present in a Container. + properties: + name: + description: Name of the environment variable. + Must be a C_IDENTIFIER. + type: string + value: + description: |- + Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in the container and + any service environment variables. If a variable cannot be resolved, + the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless of whether the variable + exists or not. + Defaults to "". + type: string + valueFrom: + description: Source for the environment variable's + value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema + the FieldPath is written in terms + of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to + select in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required + for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output + format of the exposed resources, + defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to + select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret + in the pod's namespace + properties: + key: + description: The key of the secret + to select from. Must be a valid + secret key. + type: string + 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 + optional: + description: Specify whether the Secret + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + x-kubernetes-preserve-unknown-fields: true + image: + description: Specifies the image used to execute + the command. + type: string + required: + - command + - image + type: object + scriptSpecSelectors: + description: |- + Used to select the script that need to be referenced. + When defined, the scripts defined in scriptSpecs can be referenced within the SwitchoverAction.CmdExecutorConfig. + items: + properties: + name: + description: Represents the name of the ScriptSpec + referent. + maxLength: 63 + pattern: ^[a-z0-9]([a-z0-9\.\-]*[a-z0-9])?$ + type: string + required: + - name + type: object + type: array + required: + - cmdExecutorConfig + type: object + type: object + systemAccounts: + description: Defines system accounts needed to manage the component, + and the statement to create them. + properties: + accounts: + description: Defines the configuration settings for system + accounts. + items: + description: |- + SystemAccountConfig specifies how to create and delete system accounts. + + + Deprecated since v0.9. + properties: + name: + description: The unique identifier of a system account. + enum: + - kbadmin + - kbdataprotection + - kbprobe + - kbmonitoring + - kbreplicator + type: string + provisionPolicy: + description: Outlines the strategy for creating the + account. + properties: + scope: + default: AnyPods + description: Defines the scope within which the + account is provisioned. + type: string + secretRef: + description: The external secret to refer. + properties: + name: + description: The unique identifier of the + secret. + type: string + namespace: + description: The namespace where the secret + is located. + type: string + required: + - name + - namespace + type: object + statements: + description: The statement to provision an account. + properties: + creation: + description: Specifies the statement required + to create a new account with the necessary + privileges. + type: string + deletion: + description: |- + Defines the statement required to delete an existing account. + Typically used in conjunction with the creation statement to delete an account before recreating it. + For example, one might use a `drop user if exists` statement followed by a `create user` statement to ensure a fresh account. + + + Deprecated: This field is deprecated and the update statement should be used instead. + type: string + update: + description: Defines the statement required + to update the password of an existing account. + type: string + required: + - creation + type: object + type: + description: Specifies the method to provision + an account. + enum: + - CreateByStmt + - ReferToExisting + type: string + required: + - scope + - type + type: object + required: + - name + - provisionPolicy + type: object + minItems: 1 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + cmdExecutorConfig: + description: Configures how to obtain the client SDK and + execute statements. + properties: + args: + description: Additional parameters used in the execution + of the command. + items: + type: string + type: array + command: + description: The command to be executed. + items: + type: string + minItems: 1 + type: array + env: + description: A list of environment variables that will + be injected into the command execution context. + items: + description: EnvVar represents an environment variable + present in a Container. + properties: + name: + description: Name of the environment variable. + Must be a C_IDENTIFIER. + type: string + value: + description: |- + Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in the container and + any service environment variables. If a variable cannot be resolved, + the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless of whether the variable + exists or not. + Defaults to "". + type: string + valueFrom: + description: Source for the environment variable's + value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the + FieldPath is written in terms of, defaults + to "v1". + type: string + fieldPath: + description: Path of the field to select + in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required + for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format + of the exposed resources, defaults to + "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in + the pod's namespace + properties: + key: + description: The key of the secret to + select from. Must be a valid secret + key. + type: string + 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 + optional: + description: Specify whether the Secret + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + x-kubernetes-preserve-unknown-fields: true + image: + description: Specifies the image used to execute the + command. + type: string + required: + - command + - image + type: object + passwordConfig: + description: Defines the pattern used to generate passwords + for system accounts. + properties: + length: + default: 16 + description: The length of the password. + format: int32 + maximum: 32 + minimum: 8 + type: integer + letterCase: + default: MixedCases + description: The case of the letters in the password. + enum: + - LowerCases + - UpperCases + - MixedCases + type: string + numDigits: + default: 4 + description: The number of digits in the password. + format: int32 + maximum: 8 + minimum: 0 + type: integer + numSymbols: + default: 0 + description: The number of symbols in the password. + format: int32 + maximum: 8 + minimum: 0 + type: integer + seed: + description: |- + Seed to generate the account's password. + Cannot be updated. + type: string + type: object + required: + - accounts + - cmdExecutorConfig + - passwordConfig + type: object + volumeProtectionSpec: + description: Defines settings to do volume protect. + properties: + highWatermark: + default: 90 + description: |- + The high watermark threshold for volume space usage. + If there is any specified volumes who's space usage is over the threshold, the pre-defined "LOCK" action + will be triggered to degrade the service to protect volume from space exhaustion, such as to set the instance + as read-only. And after that, if all volumes' space usage drops under the threshold later, the pre-defined + "UNLOCK" action will be performed to recover the service normally. + maximum: 100 + minimum: 0 + type: integer + volumes: + description: The Volumes to be protected. + items: + properties: + highWatermark: + description: |- + Defines the high watermark threshold for the volume, it will override the component level threshold. + If the value is invalid, it will be ignored and the component level threshold will be used. + maximum: 100 + minimum: 0 + type: integer + name: + description: The Name of the volume to protect. + type: string + type: object + type: array + type: object + volumeTypes: + description: |- + Used to describe the purpose of the volumes mapping the name of the VolumeMounts in the PodSpec.Container field, + such as data volume, log volume, etc. When backing up the volume, the volume can be correctly backed up according + to the volumeType. + + + For example: + + + - `name: data, type: data` means that the volume named `data` is used to store `data`. + - `name: binlog, type: log` means that the volume named `binlog` is used to store `log`. + + + NOTE: When volumeTypes is not defined, the backup function will not be supported, even if a persistent volume has + been specified. + items: + description: VolumeTypeSpec is deprecated since v0.9, replaced + with ComponentVolume. + properties: + name: + description: Corresponds to the name of the VolumeMounts + field in PodSpec.Container. + pattern: ^[a-z0-9]([a-z0-9\.\-]*[a-z0-9])?$ + type: string + type: + description: Type of data the volume will persistent. + enum: + - data + - log + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + workloadType: + description: |- + Defines the type of the workload. + + + - `Stateless` describes stateless applications. + - `Stateful` describes common stateful applications. + - `Consensus` describes applications based on consensus protocols, such as raft and paxos. + - `Replication` describes applications based on the primary-secondary data replication protocol. + enum: + - Stateless + - Stateful + - Consensus + - Replication + type: string + required: + - name + - workloadType + type: object + x-kubernetes-validations: + - message: componentDefs.consensusSpec(deprecated) or componentDefs.rsmSpec(recommended) + is required when componentDefs.workloadType is Consensus, and + forbidden otherwise + rule: 'has(self.workloadType) && self.workloadType == ''Consensus'' + ? (has(self.consensusSpec) || has(self.rsmSpec)) : !has(self.consensusSpec)' + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + connectionCredential: + additionalProperties: + type: string + description: |- + Connection credential template used for creating a connection credential secret for cluster objects. + + + Built-in objects are: + + + - `$(RANDOM_PASSWD)` random 8 characters. + - `$(STRONG_RANDOM_PASSWD)` random 16 characters, with mixed cases, digits and symbols. + - `$(UUID)` generate a random UUID v4 string. + - `$(UUID_B64)` generate a random UUID v4 BASE64 encoded string. + - `$(UUID_STR_B64)` generate a random UUID v4 string then BASE64 encoded. + - `$(UUID_HEX)` generate a random UUID v4 HEX representation. + - `$(HEADLESS_SVC_FQDN)` headless service FQDN placeholder, value pattern is `$(CLUSTER_NAME)-$(1ST_COMP_NAME)-headless.$(NAMESPACE).svc`, + where 1ST_COMP_NAME is the 1st component that provide `ClusterDefinition.spec.componentDefs[].service` attribute; + - `$(SVC_FQDN)` service FQDN placeholder, value pattern is `$(CLUSTER_NAME)-$(1ST_COMP_NAME).$(NAMESPACE).svc`, + where 1ST_COMP_NAME is the 1st component that provide `ClusterDefinition.spec.componentDefs[].service` attribute; + - `$(SVC_PORT_{PORT-NAME})` is ServicePort's port value with specified port name, i.e, a servicePort JSON struct: + `{"name": "mysql", "targetPort": "mysqlContainerPort", "port": 3306}`, and `$(SVC_PORT_mysql)` in the + connection credential value is 3306. + + + Deprecated since v0.9. + This field is maintained for backward compatibility and its use is discouraged. + Existing usage should be updated to the current preferred approach to avoid compatibility issues in future releases. + type: object topologies: description: Topologies defines all possible topologies within the cluster. @@ -362,6 +10232,17 @@ spec: maxItems: 128 minItems: 1 type: array + type: + description: |- + Specifies the well-known database type, such as mysql, redis, or mongodb. + + + Deprecated since v0.9. + This field is maintained for backward compatibility and its use is discouraged. + Existing usage should be updated to the current preferred approach to avoid compatibility issues in future releases. + maxLength: 24 + pattern: ^[a-z0-9]([a-z0-9\-]*[a-z0-9])?$ + type: string type: object status: description: ClusterDefinitionStatus defines the observed state of ClusterDefinition diff --git a/deploy/helm/crds/apps.kubeblocks.io_clusters.yaml b/deploy/helm/crds/apps.kubeblocks.io_clusters.yaml index 8eb9ec1959a..476972cd760 100644 --- a/deploy/helm/crds/apps.kubeblocks.io_clusters.yaml +++ b/deploy/helm/crds/apps.kubeblocks.io_clusters.yaml @@ -16991,6 +16991,27 @@ spec: description: Specifies Annotations to override or add for underlying Pods. type: object + classDefRef: + description: |- + References the class defined in ComponentClassDefinition. + + + Deprecated since v0.9. + This field is maintained for backward compatibility and its use is discouraged. + Existing usage should be updated to the current preferred approach to avoid compatibility issues in future releases. + properties: + class: + description: Defines the name of the class that is defined + in the ComponentClassDefinition. + type: string + name: + description: Specifies the name of the ComponentClassDefinition. + maxLength: 63 + pattern: ^[a-z0-9]([a-z0-9\.\-]*[a-z0-9])?$ + type: string + required: + - class + type: object componentDef: description: |- References the name of a ComponentDefinition object. @@ -26111,6 +26132,27 @@ spec: description: Specifies Annotations to override or add for underlying Pods. type: object + classDefRef: + description: |- + References the class defined in ComponentClassDefinition. + + + Deprecated since v0.9. + This field is maintained for backward compatibility and its use is discouraged. + Existing usage should be updated to the current preferred approach to avoid compatibility issues in future releases. + properties: + class: + description: Defines the name of the class that is defined + in the ComponentClassDefinition. + type: string + name: + description: Specifies the name of the ComponentClassDefinition. + maxLength: 63 + pattern: ^[a-z0-9]([a-z0-9\.\-]*[a-z0-9])?$ + type: string + required: + - class + type: object componentDef: description: |- References the name of a ComponentDefinition object. diff --git a/deploy/helm/crds/apps.kubeblocks.io_componentdefinitions.yaml b/deploy/helm/crds/apps.kubeblocks.io_componentdefinitions.yaml index 4360700ec17..58591693ee5 100644 --- a/deploy/helm/crds/apps.kubeblocks.io_componentdefinitions.yaml +++ b/deploy/helm/crds/apps.kubeblocks.io_componentdefinitions.yaml @@ -13527,57 +13527,80 @@ spec: and other administrative tasks. - The container executing this action has access to following variables: + Note: This field is immutable once it has been set. + properties: + builtinHandler: + description: |- + Specifies the name of the predefined action handler to be invoked for lifecycle actions. - - KB_ACCOUNT_NAME: The name of the system account to be created. - - KB_ACCOUNT_PASSWORD: The password for the system account. // TODO: how to pass the password securely? - - KB_ACCOUNT_STATEMENT: The statement used to create the system account. + Lorry, as a sidecar agent co-located with the database container in the same Pod, + includes a suite of built-in action implementations that are tailored to different database engines. + These are known as "builtin" handlers, includes: `mysql`, `redis`, `mongodb`, `etcd`, + `postgresql`, `official-postgresql`, `apecloud-postgresql`, `wesql`, `oceanbase`, `polardbx`. - Note: This field is immutable once it has been set. - properties: - exec: - description: |- - Defines the command to run. + If the `builtinHandler` field is specified, it instructs Lorry to utilize its internal built-in action handler + to execute the specified lifecycle actions. - This field cannot be updated. - properties: - args: - description: Args represents the arguments that are passed - to the `command` for execution. - items: - type: string - type: array - command: - description: |- - Specifies the command to be executed inside the container. - The working directory for this command is the container's root directory('/'). - Commands are executed directly without a shell environment, meaning shell-specific syntax ('|', etc.) is not supported. - If the shell is required, it must be explicitly invoked in the command. + The `builtinHandler` field is of type `BuiltinActionHandlerType`, + which represents the name of the built-in handler. + The `builtinHandler` specified within the same `ComponentLifecycleActions` should be consistent across all + actions. + This means that if you specify a built-in handler for one action, you should use the same handler + for all other actions throughout the entire `ComponentLifecycleActions` collection. - A successful execution is indicated by an exit status of 0; any non-zero status signifies a failure. - items: - type: string - type: array - container: - description: |- - Specifies the name of the container within the same pod whose resources will be shared with the action. - This allows the action to utilize the specified container's resources without executing within it. + If you need to define lifecycle actions for database engines not covered by the existing built-in support, + or when the pre-existing built-in handlers do not meet your specific needs, + you can use the `customHandler` field to define your own action implementation. - The name must match one of the containers defined in `componentDefinition.spec.runtime`. + Deprecation Notice: - The resources that can be shared are included: + - In the future, the `builtinHandler` field will be deprecated in favor of using the `customHandler` field + for configuring all lifecycle actions. + - Instead of using a name to indicate the built-in action implementations in Lorry, + the recommended approach will be to explicitly invoke the desired action implementation through + a gRPC interface exposed by the sidecar agent. + - Developers will have the flexibility to either use the built-in action implementations provided by Lorry + or develop their own sidecar agent to implement custom actions and expose them via gRPC interfaces. + - This change will allow for greater customization and extensibility of lifecycle actions, + as developers can create their own "builtin" implementations tailored to their specific requirements. + type: string + customHandler: + description: |- + Specifies a user-defined hook or procedure that is called to perform the specific lifecycle action. + It offers a flexible and expandable approach for customizing the behavior of a Component by leveraging + tailored actions. - - volume mounts + An Action can be implemented as either an ExecAction or an HTTPAction, with future versions planning + to support GRPCAction, + thereby accommodating unique logic for different database systems within the Action's framework. + + + In future iterations, all built-in handlers are expected to transition to GRPCAction. + This change means that Lorry or other sidecar agents will expose the implementation of actions + through a GRPC interface for external invocation. + Then the controller will interact with these actions via GRPCAction calls. + properties: + container: + description: |- + Defines the name of the container within the target Pod where the action will be executed. + + + This name must correspond to one of the containers defined in `componentDefinition.spec.runtime`. + If this field is not specified, the default behavior is to use the first container listed in + `componentDefinition.spec.runtime`. This field cannot be updated. + + + Note: This field is reserved for future use and is not currently active. type: string env: description: |- @@ -13699,13 +13722,101 @@ spec: - name type: object type: array + exec: + description: |- + Defines the command to run. + + + This field cannot be updated. + properties: + args: + description: Args represents the arguments that are + passed to the `command` for execution. + items: + type: string + type: array + command: + description: |- + Specifies the command to be executed inside the container. + The working directory for this command is the container's root directory('/'). + Commands are executed directly without a shell environment, meaning shell-specific syntax ('|', etc.) is not supported. + If the shell is required, it must be explicitly invoked in the command. + + + A successful execution is indicated by an exit status of 0; any non-zero status signifies a failure. + items: + type: string + type: array + type: object + http: + description: |- + Specifies the HTTP request to perform. + + + This field cannot be updated. + + + Note: HTTPAction is to be implemented in future version. + properties: + host: + description: |- + Indicates the server's domain name or IP address. Defaults to the Pod's IP. + Prefer setting the "Host" header in httpHeaders when needed. + type: string + httpHeaders: + description: |- + Allows for the inclusion of custom headers in the request. + HTTP permits the use of repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + method: + description: |- + Represents the type of HTTP request to be made, such as "GET," "POST," "PUT," etc. + If not specified, "GET" is the default method. + type: string + path: + description: Specifies the endpoint to be requested + on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Specifies the target port for the HTTP request. + It can be specified either as a numeric value in the range of 1 to 65535, + or as a named port that meets the IANA_SVC_NAME specification. + x-kubernetes-int-or-string: true + scheme: + description: |- + Designates the protocol used to make the request, such as HTTP or HTTPS. + If not specified, HTTP is used by default. + type: string + required: + - port + type: object image: description: |- Specifies the container image to be used for running the Action. When specified, a dedicated container will be created using this image to execute the Action. - All actions with same image will share the same container. + This field is mutually exclusive with the `container` field; only one of them should be provided. This field cannot be updated. @@ -13722,85 +13833,86 @@ spec: This field cannot be updated. + + + Note: This field is reserved for future use and is not currently active. type: string - targetPodSelector: + preCondition: description: |- - Defines the criteria used to select the target Pod(s) for executing the Action. - This is useful when there is no default target replica identified. - It allows for precise control over which Pod(s) the Action should run in. + Specifies the state that the cluster must reach before the Action is executed. + Currently, this is only applicable to the `postProvision` action. - If not specified, the Action will be executed in the pod where the Action is triggered, such as the pod - to be removed or added; or a random pod if the Action is triggered at the component level, such as - post-provision or pre-terminate of the component. + The conditions are as follows: - This field cannot be updated. - enum: - - Any - - All - - Role - - Ordinal - type: string - type: object - preCondition: - description: |- - Specifies the state that the cluster must reach before the Action is executed. - Currently, this is only applicable to the `postProvision` action. + - `Immediately`: Executed right after the Component object is created. + The readiness of the Component and its resources is not guaranteed at this stage. + - `RuntimeReady`: The Action is triggered after the Component object has been created and all associated + runtime resources (e.g. Pods) are in a ready state. + - `ComponentReady`: The Action is triggered after the Component itself is in a ready state. + This process does not affect the readiness state of the Component or the Cluster. + - `ClusterReady`: The Action is executed after the Cluster is in a ready state. + This execution does not alter the Component or the Cluster's state of readiness. - The conditions are as follows: + This field cannot be updated. + type: string + retryPolicy: + description: |- + Defines the strategy to be taken when retrying the Action after a failure. - - `Immediately`: Executed right after the Component object is created. - The readiness of the Component and its resources is not guaranteed at this stage. - - `RuntimeReady`: The Action is triggered after the Component object has been created and all associated - runtime resources (e.g. Pods) are in a ready state. - - `ComponentReady`: The Action is triggered after the Component itself is in a ready state. - This process does not affect the readiness state of the Component or the Cluster. - - `ClusterReady`: The Action is executed after the Cluster is in a ready state. - This execution does not alter the Component or the Cluster's state of readiness. + It specifies the conditions under which the Action should be retried and the limits to apply, + such as the maximum number of retries and backoff strategy. - This field cannot be updated. - type: string - retryPolicy: - description: |- - Defines the strategy to be taken when retrying the Action after a failure. + This field cannot be updated. + properties: + maxRetries: + default: 0 + description: |- + Defines the maximum number of retry attempts that should be made for a given Action. + This value is set to 0 by default, indicating that no retries will be made. + type: integer + retryInterval: + default: 0 + description: |- + Indicates the duration of time to wait between each retry attempt. + This value is set to 0 by default, indicating that there will be no delay between retry attempts. + format: int64 + type: integer + type: object + targetPodSelector: + description: |- + Defines the criteria used to select the target Pod(s) for executing the Action. + This is useful when there is no default target replica identified. + It allows for precise control over which Pod(s) the Action should run in. - It specifies the conditions under which the Action should be retried and the limits to apply, - such as the maximum number of retries and backoff strategy. + This field cannot be updated. - This field cannot be updated. - properties: - maxRetries: - default: 0 - description: |- - Defines the maximum number of retry attempts that should be made for a given Action. - This value is set to 0 by default, indicating that no retries will be made. - type: integer - retryInterval: + Note: This field is reserved for future use and is not currently active. + enum: + - Any + - All + - Role + - Ordinal + type: string + timeoutSeconds: default: 0 description: |- - Indicates the duration of time to wait between each retry attempt. - This value is set to 0 by default, indicating that there will be no delay between retry attempts. - format: int64 - type: integer - type: object - timeoutSeconds: - default: 0 - description: |- - Specifies the maximum duration in seconds that the Action is allowed to run. + Specifies the maximum duration in seconds that the Action is allowed to run. - If the Action does not complete within this time frame, it will be terminated. + If the Action does not complete within this time frame, it will be terminated. - This field cannot be updated. - format: int32 - type: integer + This field cannot be updated. + format: int32 + type: integer + type: object type: object dataDump: description: |- @@ -13824,47 +13936,78 @@ spec: Note: This field is immutable once it has been set. properties: - exec: + builtinHandler: description: |- - Defines the command to run. + Specifies the name of the predefined action handler to be invoked for lifecycle actions. - This field cannot be updated. - properties: - args: - description: Args represents the arguments that are passed - to the `command` for execution. - items: - type: string - type: array - command: - description: |- - Specifies the command to be executed inside the container. - The working directory for this command is the container's root directory('/'). - Commands are executed directly without a shell environment, meaning shell-specific syntax ('|', etc.) is not supported. - If the shell is required, it must be explicitly invoked in the command. + Lorry, as a sidecar agent co-located with the database container in the same Pod, + includes a suite of built-in action implementations that are tailored to different database engines. + These are known as "builtin" handlers, includes: `mysql`, `redis`, `mongodb`, `etcd`, + `postgresql`, `official-postgresql`, `apecloud-postgresql`, `wesql`, `oceanbase`, `polardbx`. - A successful execution is indicated by an exit status of 0; any non-zero status signifies a failure. - items: - type: string - type: array - container: - description: |- - Specifies the name of the container within the same pod whose resources will be shared with the action. - This allows the action to utilize the specified container's resources without executing within it. + If the `builtinHandler` field is specified, it instructs Lorry to utilize its internal built-in action handler + to execute the specified lifecycle actions. - The name must match one of the containers defined in `componentDefinition.spec.runtime`. + The `builtinHandler` field is of type `BuiltinActionHandlerType`, + which represents the name of the built-in handler. + The `builtinHandler` specified within the same `ComponentLifecycleActions` should be consistent across all + actions. + This means that if you specify a built-in handler for one action, you should use the same handler + for all other actions throughout the entire `ComponentLifecycleActions` collection. - The resources that can be shared are included: + If you need to define lifecycle actions for database engines not covered by the existing built-in support, + or when the pre-existing built-in handlers do not meet your specific needs, + you can use the `customHandler` field to define your own action implementation. - - volume mounts + Deprecation Notice: + + + - In the future, the `builtinHandler` field will be deprecated in favor of using the `customHandler` field + for configuring all lifecycle actions. + - Instead of using a name to indicate the built-in action implementations in Lorry, + the recommended approach will be to explicitly invoke the desired action implementation through + a gRPC interface exposed by the sidecar agent. + - Developers will have the flexibility to either use the built-in action implementations provided by Lorry + or develop their own sidecar agent to implement custom actions and expose them via gRPC interfaces. + - This change will allow for greater customization and extensibility of lifecycle actions, + as developers can create their own "builtin" implementations tailored to their specific requirements. + type: string + customHandler: + description: |- + Specifies a user-defined hook or procedure that is called to perform the specific lifecycle action. + It offers a flexible and expandable approach for customizing the behavior of a Component by leveraging + tailored actions. + + + An Action can be implemented as either an ExecAction or an HTTPAction, with future versions planning + to support GRPCAction, + thereby accommodating unique logic for different database systems within the Action's framework. + + + In future iterations, all built-in handlers are expected to transition to GRPCAction. + This change means that Lorry or other sidecar agents will expose the implementation of actions + through a GRPC interface for external invocation. + Then the controller will interact with these actions via GRPCAction calls. + properties: + container: + description: |- + Defines the name of the container within the target Pod where the action will be executed. + + + This name must correspond to one of the containers defined in `componentDefinition.spec.runtime`. + If this field is not specified, the default behavior is to use the first container listed in + `componentDefinition.spec.runtime`. This field cannot be updated. + + + Note: This field is reserved for future use and is not currently active. type: string env: description: |- @@ -13986,108 +14129,197 @@ spec: - name type: object type: array - image: + exec: description: |- - Specifies the container image to be used for running the Action. - - - When specified, a dedicated container will be created using this image to execute the Action. - All actions with same image will share the same container. + Defines the command to run. This field cannot be updated. - type: string - matchingKey: - description: |- - Used in conjunction with the `targetPodSelector` field to refine the selection of target pod(s) for Action execution. - The impact of this field depends on the `targetPodSelector` value: + properties: + args: + description: Args represents the arguments that are + passed to the `command` for execution. + items: + type: string + type: array + command: + description: |- + Specifies the command to be executed inside the container. + The working directory for this command is the container's root directory('/'). + Commands are executed directly without a shell environment, meaning shell-specific syntax ('|', etc.) is not supported. + If the shell is required, it must be explicitly invoked in the command. - - When `targetPodSelector` is set to `Any` or `All`, this field will be ignored. - - When `targetPodSelector` is set to `Role`, only those replicas whose role matches the `matchingKey` - will be selected for the Action. + A successful execution is indicated by an exit status of 0; any non-zero status signifies a failure. + items: + type: string + type: array + type: object + http: + description: |- + Specifies the HTTP request to perform. This field cannot be updated. - type: string - targetPodSelector: - description: |- - Defines the criteria used to select the target Pod(s) for executing the Action. - This is useful when there is no default target replica identified. - It allows for precise control over which Pod(s) the Action should run in. - If not specified, the Action will be executed in the pod where the Action is triggered, such as the pod - to be removed or added; or a random pod if the Action is triggered at the component level, such as - post-provision or pre-terminate of the component. + Note: HTTPAction is to be implemented in future version. + properties: + host: + description: |- + Indicates the server's domain name or IP address. Defaults to the Pod's IP. + Prefer setting the "Host" header in httpHeaders when needed. + type: string + httpHeaders: + description: |- + Allows for the inclusion of custom headers in the request. + HTTP permits the use of repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + method: + description: |- + Represents the type of HTTP request to be made, such as "GET," "POST," "PUT," etc. + If not specified, "GET" is the default method. + type: string + path: + description: Specifies the endpoint to be requested + on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Specifies the target port for the HTTP request. + It can be specified either as a numeric value in the range of 1 to 65535, + or as a named port that meets the IANA_SVC_NAME specification. + x-kubernetes-int-or-string: true + scheme: + description: |- + Designates the protocol used to make the request, such as HTTP or HTTPS. + If not specified, HTTP is used by default. + type: string + required: + - port + type: object + image: + description: |- + Specifies the container image to be used for running the Action. + + + When specified, a dedicated container will be created using this image to execute the Action. + This field is mutually exclusive with the `container` field; only one of them should be provided. This field cannot be updated. - enum: - - Any - - All - - Role - - Ordinal type: string - type: object - preCondition: - description: |- - Specifies the state that the cluster must reach before the Action is executed. - Currently, this is only applicable to the `postProvision` action. + matchingKey: + description: |- + Used in conjunction with the `targetPodSelector` field to refine the selection of target pod(s) for Action execution. + The impact of this field depends on the `targetPodSelector` value: - The conditions are as follows: + - When `targetPodSelector` is set to `Any` or `All`, this field will be ignored. + - When `targetPodSelector` is set to `Role`, only those replicas whose role matches the `matchingKey` + will be selected for the Action. - - `Immediately`: Executed right after the Component object is created. - The readiness of the Component and its resources is not guaranteed at this stage. - - `RuntimeReady`: The Action is triggered after the Component object has been created and all associated - runtime resources (e.g. Pods) are in a ready state. - - `ComponentReady`: The Action is triggered after the Component itself is in a ready state. - This process does not affect the readiness state of the Component or the Cluster. - - `ClusterReady`: The Action is executed after the Cluster is in a ready state. - This execution does not alter the Component or the Cluster's state of readiness. + This field cannot be updated. - This field cannot be updated. - type: string - retryPolicy: - description: |- - Defines the strategy to be taken when retrying the Action after a failure. + Note: This field is reserved for future use and is not currently active. + type: string + preCondition: + description: |- + Specifies the state that the cluster must reach before the Action is executed. + Currently, this is only applicable to the `postProvision` action. - It specifies the conditions under which the Action should be retried and the limits to apply, - such as the maximum number of retries and backoff strategy. + The conditions are as follows: - This field cannot be updated. - properties: - maxRetries: - default: 0 + - `Immediately`: Executed right after the Component object is created. + The readiness of the Component and its resources is not guaranteed at this stage. + - `RuntimeReady`: The Action is triggered after the Component object has been created and all associated + runtime resources (e.g. Pods) are in a ready state. + - `ComponentReady`: The Action is triggered after the Component itself is in a ready state. + This process does not affect the readiness state of the Component or the Cluster. + - `ClusterReady`: The Action is executed after the Cluster is in a ready state. + This execution does not alter the Component or the Cluster's state of readiness. + + + This field cannot be updated. + type: string + retryPolicy: description: |- - Defines the maximum number of retry attempts that should be made for a given Action. - This value is set to 0 by default, indicating that no retries will be made. - type: integer - retryInterval: + Defines the strategy to be taken when retrying the Action after a failure. + + + It specifies the conditions under which the Action should be retried and the limits to apply, + such as the maximum number of retries and backoff strategy. + + + This field cannot be updated. + properties: + maxRetries: + default: 0 + description: |- + Defines the maximum number of retry attempts that should be made for a given Action. + This value is set to 0 by default, indicating that no retries will be made. + type: integer + retryInterval: + default: 0 + description: |- + Indicates the duration of time to wait between each retry attempt. + This value is set to 0 by default, indicating that there will be no delay between retry attempts. + format: int64 + type: integer + type: object + targetPodSelector: + description: |- + Defines the criteria used to select the target Pod(s) for executing the Action. + This is useful when there is no default target replica identified. + It allows for precise control over which Pod(s) the Action should run in. + + + This field cannot be updated. + + + Note: This field is reserved for future use and is not currently active. + enum: + - Any + - All + - Role + - Ordinal + type: string + timeoutSeconds: default: 0 description: |- - Indicates the duration of time to wait between each retry attempt. - This value is set to 0 by default, indicating that there will be no delay between retry attempts. - format: int64 - type: integer - type: object - timeoutSeconds: - default: 0 - description: |- - Specifies the maximum duration in seconds that the Action is allowed to run. + Specifies the maximum duration in seconds that the Action is allowed to run. - If the Action does not complete within this time frame, it will be terminated. + If the Action does not complete within this time frame, it will be terminated. - This field cannot be updated. - format: int32 - type: integer + This field cannot be updated. + format: int32 + type: integer + type: object type: object dataLoad: description: |- @@ -14110,47 +14342,78 @@ spec: Note: This field is immutable once it has been set. properties: - exec: + builtinHandler: description: |- - Defines the command to run. + Specifies the name of the predefined action handler to be invoked for lifecycle actions. - This field cannot be updated. - properties: - args: - description: Args represents the arguments that are passed - to the `command` for execution. - items: - type: string - type: array - command: - description: |- - Specifies the command to be executed inside the container. - The working directory for this command is the container's root directory('/'). - Commands are executed directly without a shell environment, meaning shell-specific syntax ('|', etc.) is not supported. - If the shell is required, it must be explicitly invoked in the command. + Lorry, as a sidecar agent co-located with the database container in the same Pod, + includes a suite of built-in action implementations that are tailored to different database engines. + These are known as "builtin" handlers, includes: `mysql`, `redis`, `mongodb`, `etcd`, + `postgresql`, `official-postgresql`, `apecloud-postgresql`, `wesql`, `oceanbase`, `polardbx`. - A successful execution is indicated by an exit status of 0; any non-zero status signifies a failure. - items: - type: string - type: array - container: - description: |- - Specifies the name of the container within the same pod whose resources will be shared with the action. - This allows the action to utilize the specified container's resources without executing within it. + If the `builtinHandler` field is specified, it instructs Lorry to utilize its internal built-in action handler + to execute the specified lifecycle actions. - The name must match one of the containers defined in `componentDefinition.spec.runtime`. + The `builtinHandler` field is of type `BuiltinActionHandlerType`, + which represents the name of the built-in handler. + The `builtinHandler` specified within the same `ComponentLifecycleActions` should be consistent across all + actions. + This means that if you specify a built-in handler for one action, you should use the same handler + for all other actions throughout the entire `ComponentLifecycleActions` collection. - The resources that can be shared are included: + If you need to define lifecycle actions for database engines not covered by the existing built-in support, + or when the pre-existing built-in handlers do not meet your specific needs, + you can use the `customHandler` field to define your own action implementation. - - volume mounts + Deprecation Notice: + + + - In the future, the `builtinHandler` field will be deprecated in favor of using the `customHandler` field + for configuring all lifecycle actions. + - Instead of using a name to indicate the built-in action implementations in Lorry, + the recommended approach will be to explicitly invoke the desired action implementation through + a gRPC interface exposed by the sidecar agent. + - Developers will have the flexibility to either use the built-in action implementations provided by Lorry + or develop their own sidecar agent to implement custom actions and expose them via gRPC interfaces. + - This change will allow for greater customization and extensibility of lifecycle actions, + as developers can create their own "builtin" implementations tailored to their specific requirements. + type: string + customHandler: + description: |- + Specifies a user-defined hook or procedure that is called to perform the specific lifecycle action. + It offers a flexible and expandable approach for customizing the behavior of a Component by leveraging + tailored actions. + + + An Action can be implemented as either an ExecAction or an HTTPAction, with future versions planning + to support GRPCAction, + thereby accommodating unique logic for different database systems within the Action's framework. + + + In future iterations, all built-in handlers are expected to transition to GRPCAction. + This change means that Lorry or other sidecar agents will expose the implementation of actions + through a GRPC interface for external invocation. + Then the controller will interact with these actions via GRPCAction calls. + properties: + container: + description: |- + Defines the name of the container within the target Pod where the action will be executed. + + + This name must correspond to one of the containers defined in `componentDefinition.spec.runtime`. + If this field is not specified, the default behavior is to use the first container listed in + `componentDefinition.spec.runtime`. This field cannot be updated. + + + Note: This field is reserved for future use and is not currently active. type: string env: description: |- @@ -14272,13 +14535,101 @@ spec: - name type: object type: array + exec: + description: |- + Defines the command to run. + + + This field cannot be updated. + properties: + args: + description: Args represents the arguments that are + passed to the `command` for execution. + items: + type: string + type: array + command: + description: |- + Specifies the command to be executed inside the container. + The working directory for this command is the container's root directory('/'). + Commands are executed directly without a shell environment, meaning shell-specific syntax ('|', etc.) is not supported. + If the shell is required, it must be explicitly invoked in the command. + + + A successful execution is indicated by an exit status of 0; any non-zero status signifies a failure. + items: + type: string + type: array + type: object + http: + description: |- + Specifies the HTTP request to perform. + + + This field cannot be updated. + + + Note: HTTPAction is to be implemented in future version. + properties: + host: + description: |- + Indicates the server's domain name or IP address. Defaults to the Pod's IP. + Prefer setting the "Host" header in httpHeaders when needed. + type: string + httpHeaders: + description: |- + Allows for the inclusion of custom headers in the request. + HTTP permits the use of repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + method: + description: |- + Represents the type of HTTP request to be made, such as "GET," "POST," "PUT," etc. + If not specified, "GET" is the default method. + type: string + path: + description: Specifies the endpoint to be requested + on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Specifies the target port for the HTTP request. + It can be specified either as a numeric value in the range of 1 to 65535, + or as a named port that meets the IANA_SVC_NAME specification. + x-kubernetes-int-or-string: true + scheme: + description: |- + Designates the protocol used to make the request, such as HTTP or HTTPS. + If not specified, HTTP is used by default. + type: string + required: + - port + type: object image: description: |- Specifies the container image to be used for running the Action. When specified, a dedicated container will be created using this image to execute the Action. - All actions with same image will share the same container. + This field is mutually exclusive with the `container` field; only one of them should be provided. This field cannot be updated. @@ -14294,8 +14645,57 @@ spec: will be selected for the Action. + This field cannot be updated. + + + Note: This field is reserved for future use and is not currently active. + type: string + preCondition: + description: |- + Specifies the state that the cluster must reach before the Action is executed. + Currently, this is only applicable to the `postProvision` action. + + + The conditions are as follows: + + + - `Immediately`: Executed right after the Component object is created. + The readiness of the Component and its resources is not guaranteed at this stage. + - `RuntimeReady`: The Action is triggered after the Component object has been created and all associated + runtime resources (e.g. Pods) are in a ready state. + - `ComponentReady`: The Action is triggered after the Component itself is in a ready state. + This process does not affect the readiness state of the Component or the Cluster. + - `ClusterReady`: The Action is executed after the Cluster is in a ready state. + This execution does not alter the Component or the Cluster's state of readiness. + + This field cannot be updated. type: string + retryPolicy: + description: |- + Defines the strategy to be taken when retrying the Action after a failure. + + + It specifies the conditions under which the Action should be retried and the limits to apply, + such as the maximum number of retries and backoff strategy. + + + This field cannot be updated. + properties: + maxRetries: + default: 0 + description: |- + Defines the maximum number of retry attempts that should be made for a given Action. + This value is set to 0 by default, indicating that no retries will be made. + type: integer + retryInterval: + default: 0 + description: |- + Indicates the duration of time to wait between each retry attempt. + This value is set to 0 by default, indicating that there will be no delay between retry attempts. + format: int64 + type: integer + type: object targetPodSelector: description: |- Defines the criteria used to select the target Pod(s) for executing the Action. @@ -14303,139 +14703,150 @@ spec: It allows for precise control over which Pod(s) the Action should run in. - If not specified, the Action will be executed in the pod where the Action is triggered, such as the pod - to be removed or added; or a random pod if the Action is triggered at the component level, such as - post-provision or pre-terminate of the component. + This field cannot be updated. - This field cannot be updated. + Note: This field is reserved for future use and is not currently active. enum: - Any - All - Role - Ordinal type: string - type: object - preCondition: - description: |- - Specifies the state that the cluster must reach before the Action is executed. - Currently, this is only applicable to the `postProvision` action. + timeoutSeconds: + default: 0 + description: |- + Specifies the maximum duration in seconds that the Action is allowed to run. - The conditions are as follows: + If the Action does not complete within this time frame, it will be terminated. - - `Immediately`: Executed right after the Component object is created. - The readiness of the Component and its resources is not guaranteed at this stage. - - `RuntimeReady`: The Action is triggered after the Component object has been created and all associated - runtime resources (e.g. Pods) are in a ready state. - - `ComponentReady`: The Action is triggered after the Component itself is in a ready state. - This process does not affect the readiness state of the Component or the Cluster. - - `ClusterReady`: The Action is executed after the Cluster is in a ready state. - This execution does not alter the Component or the Cluster's state of readiness. + This field cannot be updated. + format: int32 + type: integer + type: object + type: object + memberJoin: + description: |- + Defines the procedure to add a new replica to the replication group. - This field cannot be updated. - type: string - retryPolicy: - description: |- - Defines the strategy to be taken when retrying the Action after a failure. + This action is initiated after a replica pod becomes ready. - It specifies the conditions under which the Action should be retried and the limits to apply, - such as the maximum number of retries and backoff strategy. + The role of the replica (e.g., primary, secondary) will be determined and assigned as part of the action command + implementation, or automatically by the database kernel or a sidecar utility like Patroni that implements + a consensus algorithm. - This field cannot be updated. - properties: - maxRetries: - default: 0 - description: |- - Defines the maximum number of retry attempts that should be made for a given Action. - This value is set to 0 by default, indicating that no retries will be made. - type: integer - retryInterval: - default: 0 - description: |- - Indicates the duration of time to wait between each retry attempt. - This value is set to 0 by default, indicating that there will be no delay between retry attempts. - format: int64 - type: integer - type: object - timeoutSeconds: - default: 0 - description: |- - Specifies the maximum duration in seconds that the Action is allowed to run. + The container executing this action has access to following environment variables: - If the Action does not complete within this time frame, it will be terminated. + - KB_SERVICE_PORT: The port used by the database service. + - KB_SERVICE_USER: The username with the necessary permissions to interact with the database service. + - KB_SERVICE_PASSWORD: The corresponding password for KB_SERVICE_USER to authenticate with the database service. + - KB_PRIMARY_POD_FQDN: The FQDN of the primary Pod within the replication group. + - KB_MEMBER_ADDRESSES: A comma-separated list of Pod addresses for all replicas in the group. + - KB_NEW_MEMBER_POD_NAME: The pod name of the replica being added to the group. + - KB_NEW_MEMBER_POD_IP: The IP address of the replica being added to the group. - This field cannot be updated. - format: int32 - type: integer - type: object - memberJoin: - description: "Defines the procedure to add a new replica to the - replication group.\n\n\nThis action is initiated after a replica - pod becomes ready.\n\n\nThe role of the replica (e.g., primary, - secondary) will be determined and assigned as part of the action - command\nimplementation, or automatically by the database kernel - or a sidecar utility like Patroni that implements\na consensus - algorithm.\n\n\nThe container executing this action has access - to following variables:\n\n\n- KB_JOIN_MEMBER_POD_FQDN: The - pod FQDN of the replica being added to the group.\n- KB_JOIN_MEMBER_POD_NAME: - The pod name of the replica being added to the group.\n\n\nExpected - action output:\n- On Failure: An error message detailing the - reason for any failure encountered\n during the addition of - the new member.\n\n\nFor example, to add a new OBServer to an - OceanBase Cluster in 'zone1', the following command may be used:\n\n\n```yaml\ncommand:\n- - bash\n- -c\n- |\n CLIENT=\"mysql -u $SERVICE_USER -p$SERVICE_PASSWORD - -P $SERVICE_PORT -h $SERVICE_HOST -e\"\n\t $CLIENT \"ALTER - SYSTEM ADD SERVER '$KB_POD_FQDN:$SERVICE_PORT' ZONE 'zone1'\"\n```\n\n\nNote: - This field is immutable once it has been set." + Expected action output: + - On Failure: An error message detailing the reason for any failure encountered + during the addition of the new member. + + + For example, to add a new OBServer to an OceanBase Cluster in 'zone1', the following command may be used: + + + ```yaml + command: + - bash + - -c + - | + ADDRESS=$(KB_MEMBER_ADDRESSES%%,*) + HOST=$(echo $ADDRESS | cut -d ':' -f 1) + PORT=$(echo $ADDRESS | cut -d ':' -f 2) + CLIENT="mysql -u $KB_SERVICE_USER -p$KB_SERVICE_PASSWORD -P $PORT -h $HOST -e" + $CLIENT "ALTER SYSTEM ADD SERVER '$KB_NEW_MEMBER_POD_IP:$KB_SERVICE_PORT' ZONE 'zone1'" + ``` + + + Note: This field is immutable once it has been set. properties: - exec: + builtinHandler: description: |- - Defines the command to run. + Specifies the name of the predefined action handler to be invoked for lifecycle actions. - This field cannot be updated. - properties: - args: - description: Args represents the arguments that are passed - to the `command` for execution. - items: - type: string - type: array - command: - description: |- - Specifies the command to be executed inside the container. - The working directory for this command is the container's root directory('/'). - Commands are executed directly without a shell environment, meaning shell-specific syntax ('|', etc.) is not supported. - If the shell is required, it must be explicitly invoked in the command. + Lorry, as a sidecar agent co-located with the database container in the same Pod, + includes a suite of built-in action implementations that are tailored to different database engines. + These are known as "builtin" handlers, includes: `mysql`, `redis`, `mongodb`, `etcd`, + `postgresql`, `official-postgresql`, `apecloud-postgresql`, `wesql`, `oceanbase`, `polardbx`. - A successful execution is indicated by an exit status of 0; any non-zero status signifies a failure. - items: - type: string - type: array - container: - description: |- - Specifies the name of the container within the same pod whose resources will be shared with the action. - This allows the action to utilize the specified container's resources without executing within it. + If the `builtinHandler` field is specified, it instructs Lorry to utilize its internal built-in action handler + to execute the specified lifecycle actions. - The name must match one of the containers defined in `componentDefinition.spec.runtime`. + The `builtinHandler` field is of type `BuiltinActionHandlerType`, + which represents the name of the built-in handler. + The `builtinHandler` specified within the same `ComponentLifecycleActions` should be consistent across all + actions. + This means that if you specify a built-in handler for one action, you should use the same handler + for all other actions throughout the entire `ComponentLifecycleActions` collection. - The resources that can be shared are included: + If you need to define lifecycle actions for database engines not covered by the existing built-in support, + or when the pre-existing built-in handlers do not meet your specific needs, + you can use the `customHandler` field to define your own action implementation. - - volume mounts + Deprecation Notice: + + + - In the future, the `builtinHandler` field will be deprecated in favor of using the `customHandler` field + for configuring all lifecycle actions. + - Instead of using a name to indicate the built-in action implementations in Lorry, + the recommended approach will be to explicitly invoke the desired action implementation through + a gRPC interface exposed by the sidecar agent. + - Developers will have the flexibility to either use the built-in action implementations provided by Lorry + or develop their own sidecar agent to implement custom actions and expose them via gRPC interfaces. + - This change will allow for greater customization and extensibility of lifecycle actions, + as developers can create their own "builtin" implementations tailored to their specific requirements. + type: string + customHandler: + description: |- + Specifies a user-defined hook or procedure that is called to perform the specific lifecycle action. + It offers a flexible and expandable approach for customizing the behavior of a Component by leveraging + tailored actions. + + + An Action can be implemented as either an ExecAction or an HTTPAction, with future versions planning + to support GRPCAction, + thereby accommodating unique logic for different database systems within the Action's framework. + + + In future iterations, all built-in handlers are expected to transition to GRPCAction. + This change means that Lorry or other sidecar agents will expose the implementation of actions + through a GRPC interface for external invocation. + Then the controller will interact with these actions via GRPCAction calls. + properties: + container: + description: |- + Defines the name of the container within the target Pod where the action will be executed. + + + This name must correspond to one of the containers defined in `componentDefinition.spec.runtime`. + If this field is not specified, the default behavior is to use the first container listed in + `componentDefinition.spec.runtime`. This field cannot be updated. + + + Note: This field is reserved for future use and is not currently active. type: string env: description: |- @@ -14557,13 +14968,101 @@ spec: - name type: object type: array + exec: + description: |- + Defines the command to run. + + + This field cannot be updated. + properties: + args: + description: Args represents the arguments that are + passed to the `command` for execution. + items: + type: string + type: array + command: + description: |- + Specifies the command to be executed inside the container. + The working directory for this command is the container's root directory('/'). + Commands are executed directly without a shell environment, meaning shell-specific syntax ('|', etc.) is not supported. + If the shell is required, it must be explicitly invoked in the command. + + + A successful execution is indicated by an exit status of 0; any non-zero status signifies a failure. + items: + type: string + type: array + type: object + http: + description: |- + Specifies the HTTP request to perform. + + + This field cannot be updated. + + + Note: HTTPAction is to be implemented in future version. + properties: + host: + description: |- + Indicates the server's domain name or IP address. Defaults to the Pod's IP. + Prefer setting the "Host" header in httpHeaders when needed. + type: string + httpHeaders: + description: |- + Allows for the inclusion of custom headers in the request. + HTTP permits the use of repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + method: + description: |- + Represents the type of HTTP request to be made, such as "GET," "POST," "PUT," etc. + If not specified, "GET" is the default method. + type: string + path: + description: Specifies the endpoint to be requested + on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Specifies the target port for the HTTP request. + It can be specified either as a numeric value in the range of 1 to 65535, + or as a named port that meets the IANA_SVC_NAME specification. + x-kubernetes-int-or-string: true + scheme: + description: |- + Designates the protocol used to make the request, such as HTTP or HTTPS. + If not specified, HTTP is used by default. + type: string + required: + - port + type: object image: description: |- Specifies the container image to be used for running the Action. When specified, a dedicated container will be created using this image to execute the Action. - All actions with same image will share the same container. + This field is mutually exclusive with the `container` field; only one of them should be provided. This field cannot be updated. @@ -14579,8 +15078,57 @@ spec: will be selected for the Action. + This field cannot be updated. + + + Note: This field is reserved for future use and is not currently active. + type: string + preCondition: + description: |- + Specifies the state that the cluster must reach before the Action is executed. + Currently, this is only applicable to the `postProvision` action. + + + The conditions are as follows: + + + - `Immediately`: Executed right after the Component object is created. + The readiness of the Component and its resources is not guaranteed at this stage. + - `RuntimeReady`: The Action is triggered after the Component object has been created and all associated + runtime resources (e.g. Pods) are in a ready state. + - `ComponentReady`: The Action is triggered after the Component itself is in a ready state. + This process does not affect the readiness state of the Component or the Cluster. + - `ClusterReady`: The Action is executed after the Cluster is in a ready state. + This execution does not alter the Component or the Cluster's state of readiness. + + This field cannot be updated. type: string + retryPolicy: + description: |- + Defines the strategy to be taken when retrying the Action after a failure. + + + It specifies the conditions under which the Action should be retried and the limits to apply, + such as the maximum number of retries and backoff strategy. + + + This field cannot be updated. + properties: + maxRetries: + default: 0 + description: |- + Defines the maximum number of retry attempts that should be made for a given Action. + This value is set to 0 by default, indicating that no retries will be made. + type: integer + retryInterval: + default: 0 + description: |- + Indicates the duration of time to wait between each retry attempt. + This value is set to 0 by default, indicating that there will be no delay between retry attempts. + format: int64 + type: integer + type: object targetPodSelector: description: |- Defines the criteria used to select the target Pod(s) for executing the Action. @@ -14588,141 +15136,150 @@ spec: It allows for precise control over which Pod(s) the Action should run in. - If not specified, the Action will be executed in the pod where the Action is triggered, such as the pod - to be removed or added; or a random pod if the Action is triggered at the component level, such as - post-provision or pre-terminate of the component. + This field cannot be updated. - This field cannot be updated. + Note: This field is reserved for future use and is not currently active. enum: - Any - All - Role - Ordinal type: string + timeoutSeconds: + default: 0 + description: |- + Specifies the maximum duration in seconds that the Action is allowed to run. + + + If the Action does not complete within this time frame, it will be terminated. + + + This field cannot be updated. + format: int32 + type: integer type: object - preCondition: - description: |- - Specifies the state that the cluster must reach before the Action is executed. - Currently, this is only applicable to the `postProvision` action. + type: object + memberLeave: + description: |- + Defines the procedure to remove a replica from the replication group. - The conditions are as follows: + This action is initiated before remove a replica from the group. + The operator will wait for MemberLeave to complete successfully before releasing the replica and cleaning up + related Kubernetes resources. - - `Immediately`: Executed right after the Component object is created. - The readiness of the Component and its resources is not guaranteed at this stage. - - `RuntimeReady`: The Action is triggered after the Component object has been created and all associated - runtime resources (e.g. Pods) are in a ready state. - - `ComponentReady`: The Action is triggered after the Component itself is in a ready state. - This process does not affect the readiness state of the Component or the Cluster. - - `ClusterReady`: The Action is executed after the Cluster is in a ready state. - This execution does not alter the Component or the Cluster's state of readiness. + The process typically includes updating configurations and informing other group members about the removal. + Data migration is generally not part of this action and should be handled separately if needed. - This field cannot be updated. - type: string - retryPolicy: - description: |- - Defines the strategy to be taken when retrying the Action after a failure. + The container executing this action has access to following environment variables: - It specifies the conditions under which the Action should be retried and the limits to apply, - such as the maximum number of retries and backoff strategy. + - KB_SERVICE_PORT: The port used by the database service. + - KB_SERVICE_USER: The username with the necessary permissions to interact with the database service. + - KB_SERVICE_PASSWORD: The corresponding password for KB_SERVICE_USER to authenticate with the database service. + - KB_PRIMARY_POD_FQDN: The FQDN of the primary Pod within the replication group. + - KB_MEMBER_ADDRESSES: A comma-separated list of Pod addresses for all replicas in the group. + - KB_LEAVE_MEMBER_POD_NAME: The pod name of the replica being removed from the group. + - KB_LEAVE_MEMBER_POD_IP: The IP address of the replica being removed from the group. - This field cannot be updated. - properties: - maxRetries: - default: 0 - description: |- - Defines the maximum number of retry attempts that should be made for a given Action. - This value is set to 0 by default, indicating that no retries will be made. - type: integer - retryInterval: - default: 0 - description: |- - Indicates the duration of time to wait between each retry attempt. - This value is set to 0 by default, indicating that there will be no delay between retry attempts. - format: int64 - type: integer - type: object - timeoutSeconds: - default: 0 + Expected action output: + - On Failure: An error message, if applicable, indicating why the action failed. + + + For example, to remove an OBServer from an OceanBase Cluster in 'zone1', the following command can be executed: + + + ```yaml + command: + - bash + - -c + - | + ADDRESS=$(KB_MEMBER_ADDRESSES%%,*) + HOST=$(echo $ADDRESS | cut -d ':' -f 1) + PORT=$(echo $ADDRESS | cut -d ':' -f 2) + CLIENT="mysql -u $KB_SERVICE_USER -p$KB_SERVICE_PASSWORD -P $PORT -h $HOST -e" + $CLIENT "ALTER SYSTEM DELETE SERVER '$KB_LEAVE_MEMBER_POD_IP:$KB_SERVICE_PORT' ZONE 'zone1'" + ``` + + + Note: This field is immutable once it has been set. + properties: + builtinHandler: description: |- - Specifies the maximum duration in seconds that the Action is allowed to run. + Specifies the name of the predefined action handler to be invoked for lifecycle actions. - If the Action does not complete within this time frame, it will be terminated. + Lorry, as a sidecar agent co-located with the database container in the same Pod, + includes a suite of built-in action implementations that are tailored to different database engines. + These are known as "builtin" handlers, includes: `mysql`, `redis`, `mongodb`, `etcd`, + `postgresql`, `official-postgresql`, `apecloud-postgresql`, `wesql`, `oceanbase`, `polardbx`. - This field cannot be updated. - format: int32 - type: integer - type: object - memberLeave: - description: "Defines the procedure to remove a replica from the - replication group.\n\n\nThis action is initiated before remove - a replica from the group.\nThe operator will wait for MemberLeave - to complete successfully before releasing the replica and cleaning - up\nrelated Kubernetes resources.\n\n\nThe process typically - includes updating configurations and informing other group members - about the removal.\nData migration is generally not part of - this action and should be handled separately if needed.\n\n\nThe - container executing this action has access to following variables:\n\n\n- - KB_LEAVE_MEMBER_POD_FQDN: The pod name of the replica being - removed from the group.\n- KB_LEAVE_MEMBER_POD_NAME: The pod - name of the replica being removed from the group.\n\n\nExpected - action output:\n- On Failure: An error message, if applicable, - indicating why the action failed.\n\n\nFor example, to remove - an OBServer from an OceanBase Cluster in 'zone1', the following - command can be executed:\n\n\n```yaml\ncommand:\n- bash\n- -c\n- - |\n CLIENT=\"mysql -u $SERVICE_USER -p$SERVICE_PASSWORD -P - $SERVICE_PORT -h $SERVICE_HOST -e\"\n\t $CLIENT \"ALTER SYSTEM - DELETE SERVER '$KB_POD_FQDN:$SERVICE_PORT' ZONE 'zone1'\"\n```\n\n\nNote: - This field is immutable once it has been set." - properties: - exec: - description: |- - Defines the command to run. + If the `builtinHandler` field is specified, it instructs Lorry to utilize its internal built-in action handler + to execute the specified lifecycle actions. - This field cannot be updated. - properties: - args: - description: Args represents the arguments that are passed - to the `command` for execution. - items: - type: string - type: array - command: - description: |- - Specifies the command to be executed inside the container. - The working directory for this command is the container's root directory('/'). - Commands are executed directly without a shell environment, meaning shell-specific syntax ('|', etc.) is not supported. - If the shell is required, it must be explicitly invoked in the command. + The `builtinHandler` field is of type `BuiltinActionHandlerType`, + which represents the name of the built-in handler. + The `builtinHandler` specified within the same `ComponentLifecycleActions` should be consistent across all + actions. + This means that if you specify a built-in handler for one action, you should use the same handler + for all other actions throughout the entire `ComponentLifecycleActions` collection. - A successful execution is indicated by an exit status of 0; any non-zero status signifies a failure. - items: - type: string - type: array - container: - description: |- - Specifies the name of the container within the same pod whose resources will be shared with the action. - This allows the action to utilize the specified container's resources without executing within it. + If you need to define lifecycle actions for database engines not covered by the existing built-in support, + or when the pre-existing built-in handlers do not meet your specific needs, + you can use the `customHandler` field to define your own action implementation. - The name must match one of the containers defined in `componentDefinition.spec.runtime`. + Deprecation Notice: - The resources that can be shared are included: + - In the future, the `builtinHandler` field will be deprecated in favor of using the `customHandler` field + for configuring all lifecycle actions. + - Instead of using a name to indicate the built-in action implementations in Lorry, + the recommended approach will be to explicitly invoke the desired action implementation through + a gRPC interface exposed by the sidecar agent. + - Developers will have the flexibility to either use the built-in action implementations provided by Lorry + or develop their own sidecar agent to implement custom actions and expose them via gRPC interfaces. + - This change will allow for greater customization and extensibility of lifecycle actions, + as developers can create their own "builtin" implementations tailored to their specific requirements. + type: string + customHandler: + description: |- + Specifies a user-defined hook or procedure that is called to perform the specific lifecycle action. + It offers a flexible and expandable approach for customizing the behavior of a Component by leveraging + tailored actions. - - volume mounts + An Action can be implemented as either an ExecAction or an HTTPAction, with future versions planning + to support GRPCAction, + thereby accommodating unique logic for different database systems within the Action's framework. + + + In future iterations, all built-in handlers are expected to transition to GRPCAction. + This change means that Lorry or other sidecar agents will expose the implementation of actions + through a GRPC interface for external invocation. + Then the controller will interact with these actions via GRPCAction calls. + properties: + container: + description: |- + Defines the name of the container within the target Pod where the action will be executed. + + + This name must correspond to one of the containers defined in `componentDefinition.spec.runtime`. + If this field is not specified, the default behavior is to use the first container listed in + `componentDefinition.spec.runtime`. This field cannot be updated. + + + Note: This field is reserved for future use and is not currently active. type: string env: description: |- @@ -14844,13 +15401,101 @@ spec: - name type: object type: array + exec: + description: |- + Defines the command to run. + + + This field cannot be updated. + properties: + args: + description: Args represents the arguments that are + passed to the `command` for execution. + items: + type: string + type: array + command: + description: |- + Specifies the command to be executed inside the container. + The working directory for this command is the container's root directory('/'). + Commands are executed directly without a shell environment, meaning shell-specific syntax ('|', etc.) is not supported. + If the shell is required, it must be explicitly invoked in the command. + + + A successful execution is indicated by an exit status of 0; any non-zero status signifies a failure. + items: + type: string + type: array + type: object + http: + description: |- + Specifies the HTTP request to perform. + + + This field cannot be updated. + + + Note: HTTPAction is to be implemented in future version. + properties: + host: + description: |- + Indicates the server's domain name or IP address. Defaults to the Pod's IP. + Prefer setting the "Host" header in httpHeaders when needed. + type: string + httpHeaders: + description: |- + Allows for the inclusion of custom headers in the request. + HTTP permits the use of repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + method: + description: |- + Represents the type of HTTP request to be made, such as "GET," "POST," "PUT," etc. + If not specified, "GET" is the default method. + type: string + path: + description: Specifies the endpoint to be requested + on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Specifies the target port for the HTTP request. + It can be specified either as a numeric value in the range of 1 to 65535, + or as a named port that meets the IANA_SVC_NAME specification. + x-kubernetes-int-or-string: true + scheme: + description: |- + Designates the protocol used to make the request, such as HTTP or HTTPS. + If not specified, HTTP is used by default. + type: string + required: + - port + type: object image: description: |- Specifies the container image to be used for running the Action. When specified, a dedicated container will be created using this image to execute the Action. - All actions with same image will share the same container. + This field is mutually exclusive with the `container` field; only one of them should be provided. This field cannot be updated. @@ -14867,85 +15512,86 @@ spec: This field cannot be updated. + + + Note: This field is reserved for future use and is not currently active. type: string - targetPodSelector: + preCondition: description: |- - Defines the criteria used to select the target Pod(s) for executing the Action. - This is useful when there is no default target replica identified. - It allows for precise control over which Pod(s) the Action should run in. + Specifies the state that the cluster must reach before the Action is executed. + Currently, this is only applicable to the `postProvision` action. - If not specified, the Action will be executed in the pod where the Action is triggered, such as the pod - to be removed or added; or a random pod if the Action is triggered at the component level, such as - post-provision or pre-terminate of the component. + The conditions are as follows: - This field cannot be updated. - enum: - - Any - - All - - Role - - Ordinal - type: string - type: object - preCondition: - description: |- - Specifies the state that the cluster must reach before the Action is executed. - Currently, this is only applicable to the `postProvision` action. + - `Immediately`: Executed right after the Component object is created. + The readiness of the Component and its resources is not guaranteed at this stage. + - `RuntimeReady`: The Action is triggered after the Component object has been created and all associated + runtime resources (e.g. Pods) are in a ready state. + - `ComponentReady`: The Action is triggered after the Component itself is in a ready state. + This process does not affect the readiness state of the Component or the Cluster. + - `ClusterReady`: The Action is executed after the Cluster is in a ready state. + This execution does not alter the Component or the Cluster's state of readiness. - The conditions are as follows: + This field cannot be updated. + type: string + retryPolicy: + description: |- + Defines the strategy to be taken when retrying the Action after a failure. - - `Immediately`: Executed right after the Component object is created. - The readiness of the Component and its resources is not guaranteed at this stage. - - `RuntimeReady`: The Action is triggered after the Component object has been created and all associated - runtime resources (e.g. Pods) are in a ready state. - - `ComponentReady`: The Action is triggered after the Component itself is in a ready state. - This process does not affect the readiness state of the Component or the Cluster. - - `ClusterReady`: The Action is executed after the Cluster is in a ready state. - This execution does not alter the Component or the Cluster's state of readiness. + It specifies the conditions under which the Action should be retried and the limits to apply, + such as the maximum number of retries and backoff strategy. - This field cannot be updated. - type: string - retryPolicy: - description: |- - Defines the strategy to be taken when retrying the Action after a failure. + This field cannot be updated. + properties: + maxRetries: + default: 0 + description: |- + Defines the maximum number of retry attempts that should be made for a given Action. + This value is set to 0 by default, indicating that no retries will be made. + type: integer + retryInterval: + default: 0 + description: |- + Indicates the duration of time to wait between each retry attempt. + This value is set to 0 by default, indicating that there will be no delay between retry attempts. + format: int64 + type: integer + type: object + targetPodSelector: + description: |- + Defines the criteria used to select the target Pod(s) for executing the Action. + This is useful when there is no default target replica identified. + It allows for precise control over which Pod(s) the Action should run in. - It specifies the conditions under which the Action should be retried and the limits to apply, - such as the maximum number of retries and backoff strategy. + This field cannot be updated. - This field cannot be updated. - properties: - maxRetries: - default: 0 - description: |- - Defines the maximum number of retry attempts that should be made for a given Action. - This value is set to 0 by default, indicating that no retries will be made. - type: integer - retryInterval: + Note: This field is reserved for future use and is not currently active. + enum: + - Any + - All + - Role + - Ordinal + type: string + timeoutSeconds: default: 0 description: |- - Indicates the duration of time to wait between each retry attempt. - This value is set to 0 by default, indicating that there will be no delay between retry attempts. - format: int64 - type: integer - type: object - timeoutSeconds: - default: 0 - description: |- - Specifies the maximum duration in seconds that the Action is allowed to run. + Specifies the maximum duration in seconds that the Action is allowed to run. - If the Action does not complete within this time frame, it will be terminated. + If the Action does not complete within this time frame, it will be terminated. - This field cannot be updated. - format: int32 - type: integer + This field cannot be updated. + format: int32 + type: integer + type: object type: object postProvision: description: |- @@ -14960,49 +15606,108 @@ spec: The PostProvision Action is intended to run only once. + The container executing this action has access to following environment variables: + + + - KB_CLUSTER_POD_IP_LIST: Comma-separated list of the cluster's pod IP addresses (e.g., "podIp1,podIp2"). + - KB_CLUSTER_POD_NAME_LIST: Comma-separated list of the cluster's pod names (e.g., "pod1,pod2"). + - KB_CLUSTER_POD_HOST_NAME_LIST: Comma-separated list of host names, each corresponding to a pod in + KB_CLUSTER_POD_NAME_LIST (e.g., "hostName1,hostName2"). + - KB_CLUSTER_POD_HOST_IP_LIST: Comma-separated list of host IP addresses, each corresponding to a pod in + KB_CLUSTER_POD_NAME_LIST (e.g., "hostIp1,hostIp2"). + + + - KB_CLUSTER_COMPONENT_POD_NAME_LIST: Comma-separated list of all pod names within the component + (e.g., "pod1,pod2"). + - KB_CLUSTER_COMPONENT_POD_IP_LIST: Comma-separated list of pod IP addresses, + matching the order of pods in KB_CLUSTER_COMPONENT_POD_NAME_LIST (e.g., "podIp1,podIp2"). + - KB_CLUSTER_COMPONENT_POD_HOST_NAME_LIST: Comma-separated list of host names for each pod, + matching the order of pods in KB_CLUSTER_COMPONENT_POD_NAME_LIST (e.g., "hostName1,hostName2"). + - KB_CLUSTER_COMPONENT_POD_HOST_IP_LIST: Comma-separated list of host IP addresses for each pod, + matching the order of pods in KB_CLUSTER_COMPONENT_POD_NAME_LIST (e.g., "hostIp1,hostIp2"). + + + - KB_CLUSTER_COMPONENT_LIST: Comma-separated list of all cluster components (e.g., "comp1,comp2"). + - KB_CLUSTER_COMPONENT_DELETING_LIST: Comma-separated list of components that are currently being deleted + (e.g., "comp1,comp2"). + - KB_CLUSTER_COMPONENT_UNDELETED_LIST: Comma-separated list of components that are not being deleted + (e.g., "comp1,comp2"). + + Note: This field is immutable once it has been set. properties: - exec: + builtinHandler: description: |- - Defines the command to run. + Specifies the name of the predefined action handler to be invoked for lifecycle actions. - This field cannot be updated. - properties: - args: - description: Args represents the arguments that are passed - to the `command` for execution. - items: - type: string - type: array - command: - description: |- - Specifies the command to be executed inside the container. - The working directory for this command is the container's root directory('/'). - Commands are executed directly without a shell environment, meaning shell-specific syntax ('|', etc.) is not supported. - If the shell is required, it must be explicitly invoked in the command. + Lorry, as a sidecar agent co-located with the database container in the same Pod, + includes a suite of built-in action implementations that are tailored to different database engines. + These are known as "builtin" handlers, includes: `mysql`, `redis`, `mongodb`, `etcd`, + `postgresql`, `official-postgresql`, `apecloud-postgresql`, `wesql`, `oceanbase`, `polardbx`. - A successful execution is indicated by an exit status of 0; any non-zero status signifies a failure. - items: - type: string - type: array - container: - description: |- - Specifies the name of the container within the same pod whose resources will be shared with the action. - This allows the action to utilize the specified container's resources without executing within it. + If the `builtinHandler` field is specified, it instructs Lorry to utilize its internal built-in action handler + to execute the specified lifecycle actions. - The name must match one of the containers defined in `componentDefinition.spec.runtime`. + The `builtinHandler` field is of type `BuiltinActionHandlerType`, + which represents the name of the built-in handler. + The `builtinHandler` specified within the same `ComponentLifecycleActions` should be consistent across all + actions. + This means that if you specify a built-in handler for one action, you should use the same handler + for all other actions throughout the entire `ComponentLifecycleActions` collection. - The resources that can be shared are included: + If you need to define lifecycle actions for database engines not covered by the existing built-in support, + or when the pre-existing built-in handlers do not meet your specific needs, + you can use the `customHandler` field to define your own action implementation. - - volume mounts + Deprecation Notice: + + + - In the future, the `builtinHandler` field will be deprecated in favor of using the `customHandler` field + for configuring all lifecycle actions. + - Instead of using a name to indicate the built-in action implementations in Lorry, + the recommended approach will be to explicitly invoke the desired action implementation through + a gRPC interface exposed by the sidecar agent. + - Developers will have the flexibility to either use the built-in action implementations provided by Lorry + or develop their own sidecar agent to implement custom actions and expose them via gRPC interfaces. + - This change will allow for greater customization and extensibility of lifecycle actions, + as developers can create their own "builtin" implementations tailored to their specific requirements. + type: string + customHandler: + description: |- + Specifies a user-defined hook or procedure that is called to perform the specific lifecycle action. + It offers a flexible and expandable approach for customizing the behavior of a Component by leveraging + tailored actions. + + + An Action can be implemented as either an ExecAction or an HTTPAction, with future versions planning + to support GRPCAction, + thereby accommodating unique logic for different database systems within the Action's framework. + + + In future iterations, all built-in handlers are expected to transition to GRPCAction. + This change means that Lorry or other sidecar agents will expose the implementation of actions + through a GRPC interface for external invocation. + Then the controller will interact with these actions via GRPCAction calls. + properties: + container: + description: |- + Defines the name of the container within the target Pod where the action will be executed. + + + This name must correspond to one of the containers defined in `componentDefinition.spec.runtime`. + If this field is not specified, the default behavior is to use the first container listed in + `componentDefinition.spec.runtime`. This field cannot be updated. + + + Note: This field is reserved for future use and is not currently active. type: string env: description: |- @@ -15124,18 +15829,106 @@ spec: - name type: object type: array - image: + exec: description: |- - Specifies the container image to be used for running the Action. + Defines the command to run. - When specified, a dedicated container will be created using this image to execute the Action. - All actions with same image will share the same container. + This field cannot be updated. + properties: + args: + description: Args represents the arguments that are + passed to the `command` for execution. + items: + type: string + type: array + command: + description: |- + Specifies the command to be executed inside the container. + The working directory for this command is the container's root directory('/'). + Commands are executed directly without a shell environment, meaning shell-specific syntax ('|', etc.) is not supported. + If the shell is required, it must be explicitly invoked in the command. - This field cannot be updated. - type: string - matchingKey: + A successful execution is indicated by an exit status of 0; any non-zero status signifies a failure. + items: + type: string + type: array + type: object + http: + description: |- + Specifies the HTTP request to perform. + + + This field cannot be updated. + + + Note: HTTPAction is to be implemented in future version. + properties: + host: + description: |- + Indicates the server's domain name or IP address. Defaults to the Pod's IP. + Prefer setting the "Host" header in httpHeaders when needed. + type: string + httpHeaders: + description: |- + Allows for the inclusion of custom headers in the request. + HTTP permits the use of repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + method: + description: |- + Represents the type of HTTP request to be made, such as "GET," "POST," "PUT," etc. + If not specified, "GET" is the default method. + type: string + path: + description: Specifies the endpoint to be requested + on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Specifies the target port for the HTTP request. + It can be specified either as a numeric value in the range of 1 to 65535, + or as a named port that meets the IANA_SVC_NAME specification. + x-kubernetes-int-or-string: true + scheme: + description: |- + Designates the protocol used to make the request, such as HTTP or HTTPS. + If not specified, HTTP is used by default. + type: string + required: + - port + type: object + image: + description: |- + Specifies the container image to be used for running the Action. + + + When specified, a dedicated container will be created using this image to execute the Action. + This field is mutually exclusive with the `container` field; only one of them should be provided. + + + This field cannot be updated. + type: string + matchingKey: description: |- Used in conjunction with the `targetPodSelector` field to refine the selection of target pod(s) for Action execution. The impact of this field depends on the `targetPodSelector` value: @@ -15147,85 +15940,86 @@ spec: This field cannot be updated. + + + Note: This field is reserved for future use and is not currently active. type: string - targetPodSelector: + preCondition: description: |- - Defines the criteria used to select the target Pod(s) for executing the Action. - This is useful when there is no default target replica identified. - It allows for precise control over which Pod(s) the Action should run in. + Specifies the state that the cluster must reach before the Action is executed. + Currently, this is only applicable to the `postProvision` action. - If not specified, the Action will be executed in the pod where the Action is triggered, such as the pod - to be removed or added; or a random pod if the Action is triggered at the component level, such as - post-provision or pre-terminate of the component. + The conditions are as follows: - This field cannot be updated. - enum: - - Any - - All - - Role - - Ordinal - type: string - type: object - preCondition: - description: |- - Specifies the state that the cluster must reach before the Action is executed. - Currently, this is only applicable to the `postProvision` action. + - `Immediately`: Executed right after the Component object is created. + The readiness of the Component and its resources is not guaranteed at this stage. + - `RuntimeReady`: The Action is triggered after the Component object has been created and all associated + runtime resources (e.g. Pods) are in a ready state. + - `ComponentReady`: The Action is triggered after the Component itself is in a ready state. + This process does not affect the readiness state of the Component or the Cluster. + - `ClusterReady`: The Action is executed after the Cluster is in a ready state. + This execution does not alter the Component or the Cluster's state of readiness. - The conditions are as follows: + This field cannot be updated. + type: string + retryPolicy: + description: |- + Defines the strategy to be taken when retrying the Action after a failure. - - `Immediately`: Executed right after the Component object is created. - The readiness of the Component and its resources is not guaranteed at this stage. - - `RuntimeReady`: The Action is triggered after the Component object has been created and all associated - runtime resources (e.g. Pods) are in a ready state. - - `ComponentReady`: The Action is triggered after the Component itself is in a ready state. - This process does not affect the readiness state of the Component or the Cluster. - - `ClusterReady`: The Action is executed after the Cluster is in a ready state. - This execution does not alter the Component or the Cluster's state of readiness. + It specifies the conditions under which the Action should be retried and the limits to apply, + such as the maximum number of retries and backoff strategy. - This field cannot be updated. - type: string - retryPolicy: - description: |- - Defines the strategy to be taken when retrying the Action after a failure. + This field cannot be updated. + properties: + maxRetries: + default: 0 + description: |- + Defines the maximum number of retry attempts that should be made for a given Action. + This value is set to 0 by default, indicating that no retries will be made. + type: integer + retryInterval: + default: 0 + description: |- + Indicates the duration of time to wait between each retry attempt. + This value is set to 0 by default, indicating that there will be no delay between retry attempts. + format: int64 + type: integer + type: object + targetPodSelector: + description: |- + Defines the criteria used to select the target Pod(s) for executing the Action. + This is useful when there is no default target replica identified. + It allows for precise control over which Pod(s) the Action should run in. - It specifies the conditions under which the Action should be retried and the limits to apply, - such as the maximum number of retries and backoff strategy. + This field cannot be updated. - This field cannot be updated. - properties: - maxRetries: - default: 0 - description: |- - Defines the maximum number of retry attempts that should be made for a given Action. - This value is set to 0 by default, indicating that no retries will be made. - type: integer - retryInterval: + Note: This field is reserved for future use and is not currently active. + enum: + - Any + - All + - Role + - Ordinal + type: string + timeoutSeconds: default: 0 description: |- - Indicates the duration of time to wait between each retry attempt. - This value is set to 0 by default, indicating that there will be no delay between retry attempts. - format: int64 - type: integer - type: object - timeoutSeconds: - default: 0 - description: |- - Specifies the maximum duration in seconds that the Action is allowed to run. + Specifies the maximum duration in seconds that the Action is allowed to run. - If the Action does not complete within this time frame, it will be terminated. + If the Action does not complete within this time frame, it will be terminated. - This field cannot be updated. - format: int32 - type: integer + This field cannot be updated. + format: int32 + type: integer + type: object type: object preTerminate: description: |- @@ -15240,49 +16034,115 @@ spec: until the PreTerminate action has completed successfully. + The container executing this action has access to following environment variables: + + + - KB_CLUSTER_POD_IP_LIST: Comma-separated list of the cluster's pod IP addresses (e.g., "podIp1,podIp2"). + - KB_CLUSTER_POD_NAME_LIST: Comma-separated list of the cluster's pod names (e.g., "pod1,pod2"). + - KB_CLUSTER_POD_HOST_NAME_LIST: Comma-separated list of host names, each corresponding to a pod in + KB_CLUSTER_POD_NAME_LIST (e.g., "hostName1,hostName2"). + - KB_CLUSTER_POD_HOST_IP_LIST: Comma-separated list of host IP addresses, each corresponding to a pod in + KB_CLUSTER_POD_NAME_LIST (e.g., "hostIp1,hostIp2"). + + + - KB_CLUSTER_COMPONENT_POD_NAME_LIST: Comma-separated list of all pod names within the component + (e.g., "pod1,pod2"). + - KB_CLUSTER_COMPONENT_POD_IP_LIST: Comma-separated list of pod IP addresses, + matching the order of pods in KB_CLUSTER_COMPONENT_POD_NAME_LIST (e.g., "podIp1,podIp2"). + - KB_CLUSTER_COMPONENT_POD_HOST_NAME_LIST: Comma-separated list of host names for each pod, + matching the order of pods in KB_CLUSTER_COMPONENT_POD_NAME_LIST (e.g., "hostName1,hostName2"). + - KB_CLUSTER_COMPONENT_POD_HOST_IP_LIST: Comma-separated list of host IP addresses for each pod, + matching the order of pods in KB_CLUSTER_COMPONENT_POD_NAME_LIST (e.g., "hostIp1,hostIp2"). + + + - KB_CLUSTER_COMPONENT_LIST: Comma-separated list of all cluster components (e.g., "comp1,comp2"). + - KB_CLUSTER_COMPONENT_DELETING_LIST: Comma-separated list of components that are currently being deleted + (e.g., "comp1,comp2"). + - KB_CLUSTER_COMPONENT_UNDELETED_LIST: Comma-separated list of components that are not being deleted + (e.g., "comp1,comp2"). + + + - KB_CLUSTER_COMPONENT_IS_SCALING_IN: Indicates whether the component is currently scaling in. + If this variable is present and set to "true", it denotes that the component is undergoing a scale-in operation. + During scale-in, data rebalancing is necessary to maintain cluster integrity. + Contrast this with a cluster deletion scenario where data rebalancing is not required as the entire cluster + is being cleaned up. + + Note: This field is immutable once it has been set. properties: - exec: + builtinHandler: description: |- - Defines the command to run. + Specifies the name of the predefined action handler to be invoked for lifecycle actions. - This field cannot be updated. - properties: - args: - description: Args represents the arguments that are passed - to the `command` for execution. - items: - type: string - type: array - command: - description: |- - Specifies the command to be executed inside the container. - The working directory for this command is the container's root directory('/'). - Commands are executed directly without a shell environment, meaning shell-specific syntax ('|', etc.) is not supported. - If the shell is required, it must be explicitly invoked in the command. + Lorry, as a sidecar agent co-located with the database container in the same Pod, + includes a suite of built-in action implementations that are tailored to different database engines. + These are known as "builtin" handlers, includes: `mysql`, `redis`, `mongodb`, `etcd`, + `postgresql`, `official-postgresql`, `apecloud-postgresql`, `wesql`, `oceanbase`, `polardbx`. - A successful execution is indicated by an exit status of 0; any non-zero status signifies a failure. - items: - type: string - type: array - container: - description: |- - Specifies the name of the container within the same pod whose resources will be shared with the action. - This allows the action to utilize the specified container's resources without executing within it. + If the `builtinHandler` field is specified, it instructs Lorry to utilize its internal built-in action handler + to execute the specified lifecycle actions. - The name must match one of the containers defined in `componentDefinition.spec.runtime`. + The `builtinHandler` field is of type `BuiltinActionHandlerType`, + which represents the name of the built-in handler. + The `builtinHandler` specified within the same `ComponentLifecycleActions` should be consistent across all + actions. + This means that if you specify a built-in handler for one action, you should use the same handler + for all other actions throughout the entire `ComponentLifecycleActions` collection. - The resources that can be shared are included: + If you need to define lifecycle actions for database engines not covered by the existing built-in support, + or when the pre-existing built-in handlers do not meet your specific needs, + you can use the `customHandler` field to define your own action implementation. - - volume mounts + Deprecation Notice: + + + - In the future, the `builtinHandler` field will be deprecated in favor of using the `customHandler` field + for configuring all lifecycle actions. + - Instead of using a name to indicate the built-in action implementations in Lorry, + the recommended approach will be to explicitly invoke the desired action implementation through + a gRPC interface exposed by the sidecar agent. + - Developers will have the flexibility to either use the built-in action implementations provided by Lorry + or develop their own sidecar agent to implement custom actions and expose them via gRPC interfaces. + - This change will allow for greater customization and extensibility of lifecycle actions, + as developers can create their own "builtin" implementations tailored to their specific requirements. + type: string + customHandler: + description: |- + Specifies a user-defined hook or procedure that is called to perform the specific lifecycle action. + It offers a flexible and expandable approach for customizing the behavior of a Component by leveraging + tailored actions. + + + An Action can be implemented as either an ExecAction or an HTTPAction, with future versions planning + to support GRPCAction, + thereby accommodating unique logic for different database systems within the Action's framework. + + + In future iterations, all built-in handlers are expected to transition to GRPCAction. + This change means that Lorry or other sidecar agents will expose the implementation of actions + through a GRPC interface for external invocation. + Then the controller will interact with these actions via GRPCAction calls. + properties: + container: + description: |- + Defines the name of the container within the target Pod where the action will be executed. + + + This name must correspond to one of the containers defined in `componentDefinition.spec.runtime`. + If this field is not specified, the default behavior is to use the first container listed in + `componentDefinition.spec.runtime`. This field cannot be updated. + + + Note: This field is reserved for future use and is not currently active. type: string env: description: |- @@ -15404,13 +16264,101 @@ spec: - name type: object type: array + exec: + description: |- + Defines the command to run. + + + This field cannot be updated. + properties: + args: + description: Args represents the arguments that are + passed to the `command` for execution. + items: + type: string + type: array + command: + description: |- + Specifies the command to be executed inside the container. + The working directory for this command is the container's root directory('/'). + Commands are executed directly without a shell environment, meaning shell-specific syntax ('|', etc.) is not supported. + If the shell is required, it must be explicitly invoked in the command. + + + A successful execution is indicated by an exit status of 0; any non-zero status signifies a failure. + items: + type: string + type: array + type: object + http: + description: |- + Specifies the HTTP request to perform. + + + This field cannot be updated. + + + Note: HTTPAction is to be implemented in future version. + properties: + host: + description: |- + Indicates the server's domain name or IP address. Defaults to the Pod's IP. + Prefer setting the "Host" header in httpHeaders when needed. + type: string + httpHeaders: + description: |- + Allows for the inclusion of custom headers in the request. + HTTP permits the use of repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + method: + description: |- + Represents the type of HTTP request to be made, such as "GET," "POST," "PUT," etc. + If not specified, "GET" is the default method. + type: string + path: + description: Specifies the endpoint to be requested + on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Specifies the target port for the HTTP request. + It can be specified either as a numeric value in the range of 1 to 65535, + or as a named port that meets the IANA_SVC_NAME specification. + x-kubernetes-int-or-string: true + scheme: + description: |- + Designates the protocol used to make the request, such as HTTP or HTTPS. + If not specified, HTTP is used by default. + type: string + required: + - port + type: object image: description: |- Specifies the container image to be used for running the Action. When specified, a dedicated container will be created using this image to execute the Action. - All actions with same image will share the same container. + This field is mutually exclusive with the `container` field; only one of them should be provided. This field cannot be updated. @@ -15427,85 +16375,86 @@ spec: This field cannot be updated. + + + Note: This field is reserved for future use and is not currently active. type: string - targetPodSelector: + preCondition: description: |- - Defines the criteria used to select the target Pod(s) for executing the Action. - This is useful when there is no default target replica identified. - It allows for precise control over which Pod(s) the Action should run in. + Specifies the state that the cluster must reach before the Action is executed. + Currently, this is only applicable to the `postProvision` action. - If not specified, the Action will be executed in the pod where the Action is triggered, such as the pod - to be removed or added; or a random pod if the Action is triggered at the component level, such as - post-provision or pre-terminate of the component. + The conditions are as follows: + + + - `Immediately`: Executed right after the Component object is created. + The readiness of the Component and its resources is not guaranteed at this stage. + - `RuntimeReady`: The Action is triggered after the Component object has been created and all associated + runtime resources (e.g. Pods) are in a ready state. + - `ComponentReady`: The Action is triggered after the Component itself is in a ready state. + This process does not affect the readiness state of the Component or the Cluster. + - `ClusterReady`: The Action is executed after the Cluster is in a ready state. + This execution does not alter the Component or the Cluster's state of readiness. This field cannot be updated. - enum: - - Any - - All - - Role - - Ordinal type: string - type: object - preCondition: - description: |- - Specifies the state that the cluster must reach before the Action is executed. - Currently, this is only applicable to the `postProvision` action. + retryPolicy: + description: |- + Defines the strategy to be taken when retrying the Action after a failure. - The conditions are as follows: - - - - `Immediately`: Executed right after the Component object is created. - The readiness of the Component and its resources is not guaranteed at this stage. - - `RuntimeReady`: The Action is triggered after the Component object has been created and all associated - runtime resources (e.g. Pods) are in a ready state. - - `ComponentReady`: The Action is triggered after the Component itself is in a ready state. - This process does not affect the readiness state of the Component or the Cluster. - - `ClusterReady`: The Action is executed after the Cluster is in a ready state. - This execution does not alter the Component or the Cluster's state of readiness. + It specifies the conditions under which the Action should be retried and the limits to apply, + such as the maximum number of retries and backoff strategy. - This field cannot be updated. - type: string - retryPolicy: - description: |- - Defines the strategy to be taken when retrying the Action after a failure. + This field cannot be updated. + properties: + maxRetries: + default: 0 + description: |- + Defines the maximum number of retry attempts that should be made for a given Action. + This value is set to 0 by default, indicating that no retries will be made. + type: integer + retryInterval: + default: 0 + description: |- + Indicates the duration of time to wait between each retry attempt. + This value is set to 0 by default, indicating that there will be no delay between retry attempts. + format: int64 + type: integer + type: object + targetPodSelector: + description: |- + Defines the criteria used to select the target Pod(s) for executing the Action. + This is useful when there is no default target replica identified. + It allows for precise control over which Pod(s) the Action should run in. - It specifies the conditions under which the Action should be retried and the limits to apply, - such as the maximum number of retries and backoff strategy. + This field cannot be updated. - This field cannot be updated. - properties: - maxRetries: - default: 0 - description: |- - Defines the maximum number of retry attempts that should be made for a given Action. - This value is set to 0 by default, indicating that no retries will be made. - type: integer - retryInterval: + Note: This field is reserved for future use and is not currently active. + enum: + - Any + - All + - Role + - Ordinal + type: string + timeoutSeconds: default: 0 description: |- - Indicates the duration of time to wait between each retry attempt. - This value is set to 0 by default, indicating that there will be no delay between retry attempts. - format: int64 - type: integer - type: object - timeoutSeconds: - default: 0 - description: |- - Specifies the maximum duration in seconds that the Action is allowed to run. + Specifies the maximum duration in seconds that the Action is allowed to run. - If the Action does not complete within this time frame, it will be terminated. + If the Action does not complete within this time frame, it will be terminated. - This field cannot be updated. - format: int32 - type: integer + This field cannot be updated. + format: int32 + type: integer + type: object type: object readonly: description: |- @@ -15520,6 +16469,9 @@ spec: - KB_POD_FQDN: The FQDN of the replica pod whose role is being checked. + - KB_SERVICE_PORT: The port used by the database service. + - KB_SERVICE_USER: The username with the necessary permissions to interact with the database service. + - KB_SERVICE_PASSWORD: The corresponding password for KB_SERVICE_USER to authenticate with the database service. Expected action output: @@ -15528,47 +16480,78 @@ spec: Note: This field is immutable once it has been set. properties: - exec: + builtinHandler: description: |- - Defines the command to run. + Specifies the name of the predefined action handler to be invoked for lifecycle actions. - This field cannot be updated. - properties: - args: - description: Args represents the arguments that are passed - to the `command` for execution. - items: - type: string - type: array - command: - description: |- - Specifies the command to be executed inside the container. - The working directory for this command is the container's root directory('/'). - Commands are executed directly without a shell environment, meaning shell-specific syntax ('|', etc.) is not supported. - If the shell is required, it must be explicitly invoked in the command. + Lorry, as a sidecar agent co-located with the database container in the same Pod, + includes a suite of built-in action implementations that are tailored to different database engines. + These are known as "builtin" handlers, includes: `mysql`, `redis`, `mongodb`, `etcd`, + `postgresql`, `official-postgresql`, `apecloud-postgresql`, `wesql`, `oceanbase`, `polardbx`. - A successful execution is indicated by an exit status of 0; any non-zero status signifies a failure. - items: - type: string - type: array - container: - description: |- - Specifies the name of the container within the same pod whose resources will be shared with the action. - This allows the action to utilize the specified container's resources without executing within it. + If the `builtinHandler` field is specified, it instructs Lorry to utilize its internal built-in action handler + to execute the specified lifecycle actions. - The name must match one of the containers defined in `componentDefinition.spec.runtime`. + The `builtinHandler` field is of type `BuiltinActionHandlerType`, + which represents the name of the built-in handler. + The `builtinHandler` specified within the same `ComponentLifecycleActions` should be consistent across all + actions. + This means that if you specify a built-in handler for one action, you should use the same handler + for all other actions throughout the entire `ComponentLifecycleActions` collection. - The resources that can be shared are included: + If you need to define lifecycle actions for database engines not covered by the existing built-in support, + or when the pre-existing built-in handlers do not meet your specific needs, + you can use the `customHandler` field to define your own action implementation. - - volume mounts + Deprecation Notice: + + + - In the future, the `builtinHandler` field will be deprecated in favor of using the `customHandler` field + for configuring all lifecycle actions. + - Instead of using a name to indicate the built-in action implementations in Lorry, + the recommended approach will be to explicitly invoke the desired action implementation through + a gRPC interface exposed by the sidecar agent. + - Developers will have the flexibility to either use the built-in action implementations provided by Lorry + or develop their own sidecar agent to implement custom actions and expose them via gRPC interfaces. + - This change will allow for greater customization and extensibility of lifecycle actions, + as developers can create their own "builtin" implementations tailored to their specific requirements. + type: string + customHandler: + description: |- + Specifies a user-defined hook or procedure that is called to perform the specific lifecycle action. + It offers a flexible and expandable approach for customizing the behavior of a Component by leveraging + tailored actions. + + + An Action can be implemented as either an ExecAction or an HTTPAction, with future versions planning + to support GRPCAction, + thereby accommodating unique logic for different database systems within the Action's framework. + + + In future iterations, all built-in handlers are expected to transition to GRPCAction. + This change means that Lorry or other sidecar agents will expose the implementation of actions + through a GRPC interface for external invocation. + Then the controller will interact with these actions via GRPCAction calls. + properties: + container: + description: |- + Defines the name of the container within the target Pod where the action will be executed. + + + This name must correspond to one of the containers defined in `componentDefinition.spec.runtime`. + If this field is not specified, the default behavior is to use the first container listed in + `componentDefinition.spec.runtime`. This field cannot be updated. + + + Note: This field is reserved for future use and is not currently active. type: string env: description: |- @@ -15690,13 +16673,101 @@ spec: - name type: object type: array + exec: + description: |- + Defines the command to run. + + + This field cannot be updated. + properties: + args: + description: Args represents the arguments that are + passed to the `command` for execution. + items: + type: string + type: array + command: + description: |- + Specifies the command to be executed inside the container. + The working directory for this command is the container's root directory('/'). + Commands are executed directly without a shell environment, meaning shell-specific syntax ('|', etc.) is not supported. + If the shell is required, it must be explicitly invoked in the command. + + + A successful execution is indicated by an exit status of 0; any non-zero status signifies a failure. + items: + type: string + type: array + type: object + http: + description: |- + Specifies the HTTP request to perform. + + + This field cannot be updated. + + + Note: HTTPAction is to be implemented in future version. + properties: + host: + description: |- + Indicates the server's domain name or IP address. Defaults to the Pod's IP. + Prefer setting the "Host" header in httpHeaders when needed. + type: string + httpHeaders: + description: |- + Allows for the inclusion of custom headers in the request. + HTTP permits the use of repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + method: + description: |- + Represents the type of HTTP request to be made, such as "GET," "POST," "PUT," etc. + If not specified, "GET" is the default method. + type: string + path: + description: Specifies the endpoint to be requested + on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Specifies the target port for the HTTP request. + It can be specified either as a numeric value in the range of 1 to 65535, + or as a named port that meets the IANA_SVC_NAME specification. + x-kubernetes-int-or-string: true + scheme: + description: |- + Designates the protocol used to make the request, such as HTTP or HTTPS. + If not specified, HTTP is used by default. + type: string + required: + - port + type: object image: description: |- Specifies the container image to be used for running the Action. When specified, a dedicated container will be created using this image to execute the Action. - All actions with same image will share the same container. + This field is mutually exclusive with the `container` field; only one of them should be provided. This field cannot be updated. @@ -15713,85 +16784,86 @@ spec: This field cannot be updated. + + + Note: This field is reserved for future use and is not currently active. type: string - targetPodSelector: + preCondition: description: |- - Defines the criteria used to select the target Pod(s) for executing the Action. - This is useful when there is no default target replica identified. - It allows for precise control over which Pod(s) the Action should run in. + Specifies the state that the cluster must reach before the Action is executed. + Currently, this is only applicable to the `postProvision` action. - If not specified, the Action will be executed in the pod where the Action is triggered, such as the pod - to be removed or added; or a random pod if the Action is triggered at the component level, such as - post-provision or pre-terminate of the component. + The conditions are as follows: - This field cannot be updated. - enum: - - Any - - All - - Role - - Ordinal - type: string - type: object - preCondition: - description: |- - Specifies the state that the cluster must reach before the Action is executed. - Currently, this is only applicable to the `postProvision` action. + - `Immediately`: Executed right after the Component object is created. + The readiness of the Component and its resources is not guaranteed at this stage. + - `RuntimeReady`: The Action is triggered after the Component object has been created and all associated + runtime resources (e.g. Pods) are in a ready state. + - `ComponentReady`: The Action is triggered after the Component itself is in a ready state. + This process does not affect the readiness state of the Component or the Cluster. + - `ClusterReady`: The Action is executed after the Cluster is in a ready state. + This execution does not alter the Component or the Cluster's state of readiness. - The conditions are as follows: + This field cannot be updated. + type: string + retryPolicy: + description: |- + Defines the strategy to be taken when retrying the Action after a failure. - - `Immediately`: Executed right after the Component object is created. - The readiness of the Component and its resources is not guaranteed at this stage. - - `RuntimeReady`: The Action is triggered after the Component object has been created and all associated - runtime resources (e.g. Pods) are in a ready state. - - `ComponentReady`: The Action is triggered after the Component itself is in a ready state. - This process does not affect the readiness state of the Component or the Cluster. - - `ClusterReady`: The Action is executed after the Cluster is in a ready state. - This execution does not alter the Component or the Cluster's state of readiness. + It specifies the conditions under which the Action should be retried and the limits to apply, + such as the maximum number of retries and backoff strategy. - This field cannot be updated. - type: string - retryPolicy: - description: |- - Defines the strategy to be taken when retrying the Action after a failure. + This field cannot be updated. + properties: + maxRetries: + default: 0 + description: |- + Defines the maximum number of retry attempts that should be made for a given Action. + This value is set to 0 by default, indicating that no retries will be made. + type: integer + retryInterval: + default: 0 + description: |- + Indicates the duration of time to wait between each retry attempt. + This value is set to 0 by default, indicating that there will be no delay between retry attempts. + format: int64 + type: integer + type: object + targetPodSelector: + description: |- + Defines the criteria used to select the target Pod(s) for executing the Action. + This is useful when there is no default target replica identified. + It allows for precise control over which Pod(s) the Action should run in. - It specifies the conditions under which the Action should be retried and the limits to apply, - such as the maximum number of retries and backoff strategy. + This field cannot be updated. - This field cannot be updated. - properties: - maxRetries: - default: 0 - description: |- - Defines the maximum number of retry attempts that should be made for a given Action. - This value is set to 0 by default, indicating that no retries will be made. - type: integer - retryInterval: + Note: This field is reserved for future use and is not currently active. + enum: + - Any + - All + - Role + - Ordinal + type: string + timeoutSeconds: default: 0 description: |- - Indicates the duration of time to wait between each retry attempt. - This value is set to 0 by default, indicating that there will be no delay between retry attempts. - format: int64 - type: integer - type: object - timeoutSeconds: - default: 0 - description: |- - Specifies the maximum duration in seconds that the Action is allowed to run. + Specifies the maximum duration in seconds that the Action is allowed to run. - If the Action does not complete within this time frame, it will be terminated. + If the Action does not complete within this time frame, it will be terminated. - This field cannot be updated. - format: int32 - type: integer + This field cannot be updated. + format: int32 + type: integer + type: object type: object readwrite: description: |- @@ -15808,6 +16880,9 @@ spec: - KB_POD_FQDN: The FQDN of the replica pod whose role is being checked. + - KB_SERVICE_PORT: The port used by the database service. + - KB_SERVICE_USER: The username with the necessary permissions to interact with the database service. + - KB_SERVICE_PASSWORD: The corresponding password for KB_SERVICE_USER to authenticate with the database service. Expected action output: @@ -15816,47 +16891,78 @@ spec: Note: This field is immutable once it has been set. properties: - exec: + builtinHandler: description: |- - Defines the command to run. + Specifies the name of the predefined action handler to be invoked for lifecycle actions. - This field cannot be updated. - properties: - args: - description: Args represents the arguments that are passed - to the `command` for execution. - items: - type: string - type: array - command: - description: |- - Specifies the command to be executed inside the container. - The working directory for this command is the container's root directory('/'). - Commands are executed directly without a shell environment, meaning shell-specific syntax ('|', etc.) is not supported. - If the shell is required, it must be explicitly invoked in the command. + Lorry, as a sidecar agent co-located with the database container in the same Pod, + includes a suite of built-in action implementations that are tailored to different database engines. + These are known as "builtin" handlers, includes: `mysql`, `redis`, `mongodb`, `etcd`, + `postgresql`, `official-postgresql`, `apecloud-postgresql`, `wesql`, `oceanbase`, `polardbx`. - A successful execution is indicated by an exit status of 0; any non-zero status signifies a failure. - items: - type: string - type: array - container: - description: |- - Specifies the name of the container within the same pod whose resources will be shared with the action. - This allows the action to utilize the specified container's resources without executing within it. + If the `builtinHandler` field is specified, it instructs Lorry to utilize its internal built-in action handler + to execute the specified lifecycle actions. - The name must match one of the containers defined in `componentDefinition.spec.runtime`. + The `builtinHandler` field is of type `BuiltinActionHandlerType`, + which represents the name of the built-in handler. + The `builtinHandler` specified within the same `ComponentLifecycleActions` should be consistent across all + actions. + This means that if you specify a built-in handler for one action, you should use the same handler + for all other actions throughout the entire `ComponentLifecycleActions` collection. - The resources that can be shared are included: + If you need to define lifecycle actions for database engines not covered by the existing built-in support, + or when the pre-existing built-in handlers do not meet your specific needs, + you can use the `customHandler` field to define your own action implementation. - - volume mounts + Deprecation Notice: + + + - In the future, the `builtinHandler` field will be deprecated in favor of using the `customHandler` field + for configuring all lifecycle actions. + - Instead of using a name to indicate the built-in action implementations in Lorry, + the recommended approach will be to explicitly invoke the desired action implementation through + a gRPC interface exposed by the sidecar agent. + - Developers will have the flexibility to either use the built-in action implementations provided by Lorry + or develop their own sidecar agent to implement custom actions and expose them via gRPC interfaces. + - This change will allow for greater customization and extensibility of lifecycle actions, + as developers can create their own "builtin" implementations tailored to their specific requirements. + type: string + customHandler: + description: |- + Specifies a user-defined hook or procedure that is called to perform the specific lifecycle action. + It offers a flexible and expandable approach for customizing the behavior of a Component by leveraging + tailored actions. + + + An Action can be implemented as either an ExecAction or an HTTPAction, with future versions planning + to support GRPCAction, + thereby accommodating unique logic for different database systems within the Action's framework. + + + In future iterations, all built-in handlers are expected to transition to GRPCAction. + This change means that Lorry or other sidecar agents will expose the implementation of actions + through a GRPC interface for external invocation. + Then the controller will interact with these actions via GRPCAction calls. + properties: + container: + description: |- + Defines the name of the container within the target Pod where the action will be executed. + + + This name must correspond to one of the containers defined in `componentDefinition.spec.runtime`. + If this field is not specified, the default behavior is to use the first container listed in + `componentDefinition.spec.runtime`. This field cannot be updated. + + + Note: This field is reserved for future use and is not currently active. type: string env: description: |- @@ -15978,13 +17084,101 @@ spec: - name type: object type: array + exec: + description: |- + Defines the command to run. + + + This field cannot be updated. + properties: + args: + description: Args represents the arguments that are + passed to the `command` for execution. + items: + type: string + type: array + command: + description: |- + Specifies the command to be executed inside the container. + The working directory for this command is the container's root directory('/'). + Commands are executed directly without a shell environment, meaning shell-specific syntax ('|', etc.) is not supported. + If the shell is required, it must be explicitly invoked in the command. + + + A successful execution is indicated by an exit status of 0; any non-zero status signifies a failure. + items: + type: string + type: array + type: object + http: + description: |- + Specifies the HTTP request to perform. + + + This field cannot be updated. + + + Note: HTTPAction is to be implemented in future version. + properties: + host: + description: |- + Indicates the server's domain name or IP address. Defaults to the Pod's IP. + Prefer setting the "Host" header in httpHeaders when needed. + type: string + httpHeaders: + description: |- + Allows for the inclusion of custom headers in the request. + HTTP permits the use of repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + method: + description: |- + Represents the type of HTTP request to be made, such as "GET," "POST," "PUT," etc. + If not specified, "GET" is the default method. + type: string + path: + description: Specifies the endpoint to be requested + on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Specifies the target port for the HTTP request. + It can be specified either as a numeric value in the range of 1 to 65535, + or as a named port that meets the IANA_SVC_NAME specification. + x-kubernetes-int-or-string: true + scheme: + description: |- + Designates the protocol used to make the request, such as HTTP or HTTPS. + If not specified, HTTP is used by default. + type: string + required: + - port + type: object image: description: |- Specifies the container image to be used for running the Action. When specified, a dedicated container will be created using this image to execute the Action. - All actions with same image will share the same container. + This field is mutually exclusive with the `container` field; only one of them should be provided. This field cannot be updated. @@ -16000,8 +17194,57 @@ spec: will be selected for the Action. + This field cannot be updated. + + + Note: This field is reserved for future use and is not currently active. + type: string + preCondition: + description: |- + Specifies the state that the cluster must reach before the Action is executed. + Currently, this is only applicable to the `postProvision` action. + + + The conditions are as follows: + + + - `Immediately`: Executed right after the Component object is created. + The readiness of the Component and its resources is not guaranteed at this stage. + - `RuntimeReady`: The Action is triggered after the Component object has been created and all associated + runtime resources (e.g. Pods) are in a ready state. + - `ComponentReady`: The Action is triggered after the Component itself is in a ready state. + This process does not affect the readiness state of the Component or the Cluster. + - `ClusterReady`: The Action is executed after the Cluster is in a ready state. + This execution does not alter the Component or the Cluster's state of readiness. + + This field cannot be updated. type: string + retryPolicy: + description: |- + Defines the strategy to be taken when retrying the Action after a failure. + + + It specifies the conditions under which the Action should be retried and the limits to apply, + such as the maximum number of retries and backoff strategy. + + + This field cannot be updated. + properties: + maxRetries: + default: 0 + description: |- + Defines the maximum number of retry attempts that should be made for a given Action. + This value is set to 0 by default, indicating that no retries will be made. + type: integer + retryInterval: + default: 0 + description: |- + Indicates the duration of time to wait between each retry attempt. + This value is set to 0 by default, indicating that there will be no delay between retry attempts. + format: int64 + type: integer + type: object targetPodSelector: description: |- Defines the criteria used to select the target Pod(s) for executing the Action. @@ -16009,129 +17252,112 @@ spec: It allows for precise control over which Pod(s) the Action should run in. - If not specified, the Action will be executed in the pod where the Action is triggered, such as the pod - to be removed or added; or a random pod if the Action is triggered at the component level, such as - post-provision or pre-terminate of the component. + This field cannot be updated. - This field cannot be updated. + Note: This field is reserved for future use and is not currently active. enum: - Any - All - Role - Ordinal type: string - type: object - preCondition: - description: |- - Specifies the state that the cluster must reach before the Action is executed. - Currently, this is only applicable to the `postProvision` action. + timeoutSeconds: + default: 0 + description: |- + Specifies the maximum duration in seconds that the Action is allowed to run. - The conditions are as follows: + If the Action does not complete within this time frame, it will be terminated. - - `Immediately`: Executed right after the Component object is created. - The readiness of the Component and its resources is not guaranteed at this stage. - - `RuntimeReady`: The Action is triggered after the Component object has been created and all associated - runtime resources (e.g. Pods) are in a ready state. - - `ComponentReady`: The Action is triggered after the Component itself is in a ready state. - This process does not affect the readiness state of the Component or the Cluster. - - `ClusterReady`: The Action is executed after the Cluster is in a ready state. - This execution does not alter the Component or the Cluster's state of readiness. + This field cannot be updated. + format: int32 + type: integer + type: object + type: object + reconfigure: + description: |- + Defines the procedure that update a replica with new configuration. - This field cannot be updated. - type: string - retryPolicy: + Note: This field is immutable once it has been set. + + + This Action is reserved for future versions. + properties: + builtinHandler: description: |- - Defines the strategy to be taken when retrying the Action after a failure. + Specifies the name of the predefined action handler to be invoked for lifecycle actions. - It specifies the conditions under which the Action should be retried and the limits to apply, - such as the maximum number of retries and backoff strategy. + Lorry, as a sidecar agent co-located with the database container in the same Pod, + includes a suite of built-in action implementations that are tailored to different database engines. + These are known as "builtin" handlers, includes: `mysql`, `redis`, `mongodb`, `etcd`, + `postgresql`, `official-postgresql`, `apecloud-postgresql`, `wesql`, `oceanbase`, `polardbx`. - This field cannot be updated. - properties: - maxRetries: - default: 0 - description: |- - Defines the maximum number of retry attempts that should be made for a given Action. - This value is set to 0 by default, indicating that no retries will be made. - type: integer - retryInterval: - default: 0 - description: |- - Indicates the duration of time to wait between each retry attempt. - This value is set to 0 by default, indicating that there will be no delay between retry attempts. - format: int64 - type: integer - type: object - timeoutSeconds: - default: 0 - description: |- - Specifies the maximum duration in seconds that the Action is allowed to run. + If the `builtinHandler` field is specified, it instructs Lorry to utilize its internal built-in action handler + to execute the specified lifecycle actions. - If the Action does not complete within this time frame, it will be terminated. + The `builtinHandler` field is of type `BuiltinActionHandlerType`, + which represents the name of the built-in handler. + The `builtinHandler` specified within the same `ComponentLifecycleActions` should be consistent across all + actions. + This means that if you specify a built-in handler for one action, you should use the same handler + for all other actions throughout the entire `ComponentLifecycleActions` collection. - This field cannot be updated. - format: int32 - type: integer - type: object - reconfigure: - description: |- - Defines the procedure that update a replica with new configuration. + If you need to define lifecycle actions for database engines not covered by the existing built-in support, + or when the pre-existing built-in handlers do not meet your specific needs, + you can use the `customHandler` field to define your own action implementation. - Note: This field is immutable once it has been set. + Deprecation Notice: - This Action is reserved for future versions. - properties: - exec: + - In the future, the `builtinHandler` field will be deprecated in favor of using the `customHandler` field + for configuring all lifecycle actions. + - Instead of using a name to indicate the built-in action implementations in Lorry, + the recommended approach will be to explicitly invoke the desired action implementation through + a gRPC interface exposed by the sidecar agent. + - Developers will have the flexibility to either use the built-in action implementations provided by Lorry + or develop their own sidecar agent to implement custom actions and expose them via gRPC interfaces. + - This change will allow for greater customization and extensibility of lifecycle actions, + as developers can create their own "builtin" implementations tailored to their specific requirements. + type: string + customHandler: description: |- - Defines the command to run. + Specifies a user-defined hook or procedure that is called to perform the specific lifecycle action. + It offers a flexible and expandable approach for customizing the behavior of a Component by leveraging + tailored actions. - This field cannot be updated. - properties: - args: - description: Args represents the arguments that are passed - to the `command` for execution. - items: - type: string - type: array - command: - description: |- - Specifies the command to be executed inside the container. - The working directory for this command is the container's root directory('/'). - Commands are executed directly without a shell environment, meaning shell-specific syntax ('|', etc.) is not supported. - If the shell is required, it must be explicitly invoked in the command. + An Action can be implemented as either an ExecAction or an HTTPAction, with future versions planning + to support GRPCAction, + thereby accommodating unique logic for different database systems within the Action's framework. - A successful execution is indicated by an exit status of 0; any non-zero status signifies a failure. - items: - type: string - type: array + In future iterations, all built-in handlers are expected to transition to GRPCAction. + This change means that Lorry or other sidecar agents will expose the implementation of actions + through a GRPC interface for external invocation. + Then the controller will interact with these actions via GRPCAction calls. + properties: container: description: |- - Specifies the name of the container within the same pod whose resources will be shared with the action. - This allows the action to utilize the specified container's resources without executing within it. - - - The name must match one of the containers defined in `componentDefinition.spec.runtime`. + Defines the name of the container within the target Pod where the action will be executed. - The resources that can be shared are included: + This name must correspond to one of the containers defined in `componentDefinition.spec.runtime`. + If this field is not specified, the default behavior is to use the first container listed in + `componentDefinition.spec.runtime`. - - volume mounts + This field cannot be updated. - This field cannot be updated. + Note: This field is reserved for future use and is not currently active. type: string env: description: |- @@ -16253,13 +17479,101 @@ spec: - name type: object type: array + exec: + description: |- + Defines the command to run. + + + This field cannot be updated. + properties: + args: + description: Args represents the arguments that are + passed to the `command` for execution. + items: + type: string + type: array + command: + description: |- + Specifies the command to be executed inside the container. + The working directory for this command is the container's root directory('/'). + Commands are executed directly without a shell environment, meaning shell-specific syntax ('|', etc.) is not supported. + If the shell is required, it must be explicitly invoked in the command. + + + A successful execution is indicated by an exit status of 0; any non-zero status signifies a failure. + items: + type: string + type: array + type: object + http: + description: |- + Specifies the HTTP request to perform. + + + This field cannot be updated. + + + Note: HTTPAction is to be implemented in future version. + properties: + host: + description: |- + Indicates the server's domain name or IP address. Defaults to the Pod's IP. + Prefer setting the "Host" header in httpHeaders when needed. + type: string + httpHeaders: + description: |- + Allows for the inclusion of custom headers in the request. + HTTP permits the use of repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + method: + description: |- + Represents the type of HTTP request to be made, such as "GET," "POST," "PUT," etc. + If not specified, "GET" is the default method. + type: string + path: + description: Specifies the endpoint to be requested + on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Specifies the target port for the HTTP request. + It can be specified either as a numeric value in the range of 1 to 65535, + or as a named port that meets the IANA_SVC_NAME specification. + x-kubernetes-int-or-string: true + scheme: + description: |- + Designates the protocol used to make the request, such as HTTP or HTTPS. + If not specified, HTTP is used by default. + type: string + required: + - port + type: object image: description: |- Specifies the container image to be used for running the Action. When specified, a dedicated container will be created using this image to execute the Action. - All actions with same image will share the same container. + This field is mutually exclusive with the `container` field; only one of them should be provided. This field cannot be updated. @@ -16276,92 +17590,93 @@ spec: This field cannot be updated. + + + Note: This field is reserved for future use and is not currently active. type: string - targetPodSelector: + preCondition: description: |- - Defines the criteria used to select the target Pod(s) for executing the Action. - This is useful when there is no default target replica identified. - It allows for precise control over which Pod(s) the Action should run in. + Specifies the state that the cluster must reach before the Action is executed. + Currently, this is only applicable to the `postProvision` action. - If not specified, the Action will be executed in the pod where the Action is triggered, such as the pod - to be removed or added; or a random pod if the Action is triggered at the component level, such as - post-provision or pre-terminate of the component. + The conditions are as follows: + + + - `Immediately`: Executed right after the Component object is created. + The readiness of the Component and its resources is not guaranteed at this stage. + - `RuntimeReady`: The Action is triggered after the Component object has been created and all associated + runtime resources (e.g. Pods) are in a ready state. + - `ComponentReady`: The Action is triggered after the Component itself is in a ready state. + This process does not affect the readiness state of the Component or the Cluster. + - `ClusterReady`: The Action is executed after the Cluster is in a ready state. + This execution does not alter the Component or the Cluster's state of readiness. This field cannot be updated. - enum: - - Any - - All - - Role - - Ordinal type: string - type: object - preCondition: - description: |- - Specifies the state that the cluster must reach before the Action is executed. - Currently, this is only applicable to the `postProvision` action. - - - The conditions are as follows: + retryPolicy: + description: |- + Defines the strategy to be taken when retrying the Action after a failure. - - `Immediately`: Executed right after the Component object is created. - The readiness of the Component and its resources is not guaranteed at this stage. - - `RuntimeReady`: The Action is triggered after the Component object has been created and all associated - runtime resources (e.g. Pods) are in a ready state. - - `ComponentReady`: The Action is triggered after the Component itself is in a ready state. - This process does not affect the readiness state of the Component or the Cluster. - - `ClusterReady`: The Action is executed after the Cluster is in a ready state. - This execution does not alter the Component or the Cluster's state of readiness. + It specifies the conditions under which the Action should be retried and the limits to apply, + such as the maximum number of retries and backoff strategy. - This field cannot be updated. - type: string - retryPolicy: - description: |- - Defines the strategy to be taken when retrying the Action after a failure. + This field cannot be updated. + properties: + maxRetries: + default: 0 + description: |- + Defines the maximum number of retry attempts that should be made for a given Action. + This value is set to 0 by default, indicating that no retries will be made. + type: integer + retryInterval: + default: 0 + description: |- + Indicates the duration of time to wait between each retry attempt. + This value is set to 0 by default, indicating that there will be no delay between retry attempts. + format: int64 + type: integer + type: object + targetPodSelector: + description: |- + Defines the criteria used to select the target Pod(s) for executing the Action. + This is useful when there is no default target replica identified. + It allows for precise control over which Pod(s) the Action should run in. - It specifies the conditions under which the Action should be retried and the limits to apply, - such as the maximum number of retries and backoff strategy. + This field cannot be updated. - This field cannot be updated. - properties: - maxRetries: - default: 0 - description: |- - Defines the maximum number of retry attempts that should be made for a given Action. - This value is set to 0 by default, indicating that no retries will be made. - type: integer - retryInterval: + Note: This field is reserved for future use and is not currently active. + enum: + - Any + - All + - Role + - Ordinal + type: string + timeoutSeconds: default: 0 description: |- - Indicates the duration of time to wait between each retry attempt. - This value is set to 0 by default, indicating that there will be no delay between retry attempts. - format: int64 - type: integer - type: object - timeoutSeconds: - default: 0 - description: |- - Specifies the maximum duration in seconds that the Action is allowed to run. + Specifies the maximum duration in seconds that the Action is allowed to run. - If the Action does not complete within this time frame, it will be terminated. + If the Action does not complete within this time frame, it will be terminated. - This field cannot be updated. - format: int32 - type: integer + This field cannot be updated. + format: int32 + type: integer + type: object type: object roleProbe: description: |- Defines the procedure which is invoked regularly to assess the role of replicas. - This action is periodically triggered at the specified interval to determine the role of each replica. + This action is periodically triggered by Lorry at the specified interval to determine the role of each replica. Upon successful execution, the action's output designates the role of the replica, which should match one of the predefined role names within `componentDefinition.spec.roles`. The output is then compared with the previous successful execution result. @@ -16374,10 +17689,13 @@ spec: Without this, services that rely on roleSelectors might improperly direct traffic to wrong replicas. - The container executing this action has access to following variables: + The container executing this action has access to following environment variables: - KB_POD_FQDN: The FQDN of the Pod whose role is being assessed. + - KB_SERVICE_PORT: The port used by the database service. + - KB_SERVICE_USER: The username with the necessary permissions to interact with the database service. + - KB_SERVICE_PASSWORD: The corresponding password for KB_SERVICE_USER to authenticate with the database service. Expected output of this action: @@ -16388,47 +17706,78 @@ spec: Note: This field is immutable once it has been set. properties: - exec: + builtinHandler: description: |- - Defines the command to run. + Specifies the name of the predefined action handler to be invoked for lifecycle actions. - This field cannot be updated. - properties: - args: - description: Args represents the arguments that are passed - to the `command` for execution. - items: - type: string - type: array - command: - description: |- - Specifies the command to be executed inside the container. - The working directory for this command is the container's root directory('/'). - Commands are executed directly without a shell environment, meaning shell-specific syntax ('|', etc.) is not supported. - If the shell is required, it must be explicitly invoked in the command. + Lorry, as a sidecar agent co-located with the database container in the same Pod, + includes a suite of built-in action implementations that are tailored to different database engines. + These are known as "builtin" handlers, includes: `mysql`, `redis`, `mongodb`, `etcd`, + `postgresql`, `official-postgresql`, `apecloud-postgresql`, `wesql`, `oceanbase`, `polardbx`. - A successful execution is indicated by an exit status of 0; any non-zero status signifies a failure. - items: - type: string - type: array - container: - description: |- - Specifies the name of the container within the same pod whose resources will be shared with the action. - This allows the action to utilize the specified container's resources without executing within it. + If the `builtinHandler` field is specified, it instructs Lorry to utilize its internal built-in action handler + to execute the specified lifecycle actions. - The name must match one of the containers defined in `componentDefinition.spec.runtime`. + The `builtinHandler` field is of type `BuiltinActionHandlerType`, + which represents the name of the built-in handler. + The `builtinHandler` specified within the same `ComponentLifecycleActions` should be consistent across all + actions. + This means that if you specify a built-in handler for one action, you should use the same handler + for all other actions throughout the entire `ComponentLifecycleActions` collection. - The resources that can be shared are included: + If you need to define lifecycle actions for database engines not covered by the existing built-in support, + or when the pre-existing built-in handlers do not meet your specific needs, + you can use the `customHandler` field to define your own action implementation. - - volume mounts + Deprecation Notice: + + + - In the future, the `builtinHandler` field will be deprecated in favor of using the `customHandler` field + for configuring all lifecycle actions. + - Instead of using a name to indicate the built-in action implementations in Lorry, + the recommended approach will be to explicitly invoke the desired action implementation through + a gRPC interface exposed by the sidecar agent. + - Developers will have the flexibility to either use the built-in action implementations provided by Lorry + or develop their own sidecar agent to implement custom actions and expose them via gRPC interfaces. + - This change will allow for greater customization and extensibility of lifecycle actions, + as developers can create their own "builtin" implementations tailored to their specific requirements. + type: string + customHandler: + description: |- + Specifies a user-defined hook or procedure that is called to perform the specific lifecycle action. + It offers a flexible and expandable approach for customizing the behavior of a Component by leveraging + tailored actions. + + + An Action can be implemented as either an ExecAction or an HTTPAction, with future versions planning + to support GRPCAction, + thereby accommodating unique logic for different database systems within the Action's framework. + + + In future iterations, all built-in handlers are expected to transition to GRPCAction. + This change means that Lorry or other sidecar agents will expose the implementation of actions + through a GRPC interface for external invocation. + Then the controller will interact with these actions via GRPCAction calls. + properties: + container: + description: |- + Defines the name of the container within the target Pod where the action will be executed. + + + This name must correspond to one of the containers defined in `componentDefinition.spec.runtime`. + If this field is not specified, the default behavior is to use the first container listed in + `componentDefinition.spec.runtime`. This field cannot be updated. + + + Note: This field is reserved for future use and is not currently active. type: string env: description: |- @@ -16550,13 +17899,101 @@ spec: - name type: object type: array + exec: + description: |- + Defines the command to run. + + + This field cannot be updated. + properties: + args: + description: Args represents the arguments that are + passed to the `command` for execution. + items: + type: string + type: array + command: + description: |- + Specifies the command to be executed inside the container. + The working directory for this command is the container's root directory('/'). + Commands are executed directly without a shell environment, meaning shell-specific syntax ('|', etc.) is not supported. + If the shell is required, it must be explicitly invoked in the command. + + + A successful execution is indicated by an exit status of 0; any non-zero status signifies a failure. + items: + type: string + type: array + type: object + http: + description: |- + Specifies the HTTP request to perform. + + + This field cannot be updated. + + + Note: HTTPAction is to be implemented in future version. + properties: + host: + description: |- + Indicates the server's domain name or IP address. Defaults to the Pod's IP. + Prefer setting the "Host" header in httpHeaders when needed. + type: string + httpHeaders: + description: |- + Allows for the inclusion of custom headers in the request. + HTTP permits the use of repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + method: + description: |- + Represents the type of HTTP request to be made, such as "GET," "POST," "PUT," etc. + If not specified, "GET" is the default method. + type: string + path: + description: Specifies the endpoint to be requested + on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Specifies the target port for the HTTP request. + It can be specified either as a numeric value in the range of 1 to 65535, + or as a named port that meets the IANA_SVC_NAME specification. + x-kubernetes-int-or-string: true + scheme: + description: |- + Designates the protocol used to make the request, such as HTTP or HTTPS. + If not specified, HTTP is used by default. + type: string + required: + - port + type: object image: description: |- Specifies the container image to be used for running the Action. When specified, a dedicated container will be created using this image to execute the Action. - All actions with same image will share the same container. + This field is mutually exclusive with the `container` field; only one of them should be provided. This field cannot be updated. @@ -16572,8 +18009,57 @@ spec: will be selected for the Action. + This field cannot be updated. + + + Note: This field is reserved for future use and is not currently active. + type: string + preCondition: + description: |- + Specifies the state that the cluster must reach before the Action is executed. + Currently, this is only applicable to the `postProvision` action. + + + The conditions are as follows: + + + - `Immediately`: Executed right after the Component object is created. + The readiness of the Component and its resources is not guaranteed at this stage. + - `RuntimeReady`: The Action is triggered after the Component object has been created and all associated + runtime resources (e.g. Pods) are in a ready state. + - `ComponentReady`: The Action is triggered after the Component itself is in a ready state. + This process does not affect the readiness state of the Component or the Cluster. + - `ClusterReady`: The Action is executed after the Cluster is in a ready state. + This execution does not alter the Component or the Cluster's state of readiness. + + This field cannot be updated. type: string + retryPolicy: + description: |- + Defines the strategy to be taken when retrying the Action after a failure. + + + It specifies the conditions under which the Action should be retried and the limits to apply, + such as the maximum number of retries and backoff strategy. + + + This field cannot be updated. + properties: + maxRetries: + default: 0 + description: |- + Defines the maximum number of retry attempts that should be made for a given Action. + This value is set to 0 by default, indicating that no retries will be made. + type: integer + retryInterval: + default: 0 + description: |- + Indicates the duration of time to wait between each retry attempt. + This value is set to 0 by default, indicating that there will be no delay between retry attempts. + format: int64 + type: integer + type: object targetPodSelector: description: |- Defines the criteria used to select the target Pod(s) for executing the Action. @@ -16581,25 +18067,29 @@ spec: It allows for precise control over which Pod(s) the Action should run in. - If not specified, the Action will be executed in the pod where the Action is triggered, such as the pod - to be removed or added; or a random pod if the Action is triggered at the component level, such as - post-provision or pre-terminate of the component. + This field cannot be updated. - This field cannot be updated. + Note: This field is reserved for future use and is not currently active. enum: - Any - All - Role - Ordinal type: string + timeoutSeconds: + default: 0 + description: |- + Specifies the maximum duration in seconds that the Action is allowed to run. + + + If the Action does not complete within this time frame, it will be terminated. + + + This field cannot be updated. + format: int32 + type: integer type: object - failureThreshold: - description: |- - Minimum consecutive failures for the probe to be considered failed after having succeeded. - Defaults to 3. Minimum value is 1. - format: int32 - type: integer initialDelaySeconds: description: |- Specifies the number of seconds to wait after the container has started before the RoleProbe @@ -16612,129 +18102,410 @@ spec: Default to 10 seconds. Minimum value is 1. format: int32 type: integer - preCondition: + timeoutSeconds: description: |- - Specifies the state that the cluster must reach before the Action is executed. - Currently, this is only applicable to the `postProvision` action. + Specifies the number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + format: int32 + type: integer + type: object + switchover: + description: |- + Defines the procedure for a controlled transition of leadership from the current leader to a new replica. + This approach aims to minimize downtime and maintain availability in systems with a leader-follower topology, + during events such as planned maintenance or when performing stop, shutdown, restart, or upgrade operations + involving the current leader node. - The conditions are as follows: + The container executing this action has access to following environment variables: - - `Immediately`: Executed right after the Component object is created. - The readiness of the Component and its resources is not guaranteed at this stage. - - `RuntimeReady`: The Action is triggered after the Component object has been created and all associated - runtime resources (e.g. Pods) are in a ready state. - - `ComponentReady`: The Action is triggered after the Component itself is in a ready state. - This process does not affect the readiness state of the Component or the Cluster. - - `ClusterReady`: The Action is executed after the Cluster is in a ready state. - This execution does not alter the Component or the Cluster's state of readiness. + - KB_SWITCHOVER_CANDIDATE_NAME: The name of the pod for the new leader candidate, which may not be specified (empty). + - KB_SWITCHOVER_CANDIDATE_FQDN: The FQDN of the new leader candidate's pod, which may not be specified (empty). + - KB_LEADER_POD_IP: The IP address of the current leader's pod prior to the switchover. + - KB_LEADER_POD_NAME: The name of the current leader's pod prior to the switchover. + - KB_LEADER_POD_FQDN: The FQDN of the current leader's pod prior to the switchover. - This field cannot be updated. - type: string - retryPolicy: - description: |- - Defines the strategy to be taken when retrying the Action after a failure. + The environment variables with the following prefixes are deprecated and will be removed in future releases: - It specifies the conditions under which the Action should be retried and the limits to apply, - such as the maximum number of retries and backoff strategy. + - KB_REPLICATION_PRIMARY_POD_ + - KB_CONSENSUS_LEADER_POD_ - This field cannot be updated. + Note: This field is immutable once it has been set. + properties: + scriptSpecSelectors: + description: |- + Used to define the selectors for the scriptSpecs that need to be referenced. + If this field is set, the scripts defined under the 'scripts' field can be invoked or referenced within an Action. + + + This field is deprecated from v0.9. + This field is maintained for backward compatibility and its use is discouraged. + Existing usage should be updated to the current preferred approach to avoid compatibility issues in future releases. + items: + properties: + name: + description: Represents the name of the ScriptSpec referent. + maxLength: 63 + pattern: ^[a-z0-9]([a-z0-9\.\-]*[a-z0-9])?$ + type: string + required: + - name + type: object + type: array + withCandidate: + description: |- + Represents the switchover process for a specified candidate primary or leader instance. + Note that only Action.Exec is currently supported, while Action.HTTP is not. properties: - maxRetries: - default: 0 + container: description: |- - Defines the maximum number of retry attempts that should be made for a given Action. - This value is set to 0 by default, indicating that no retries will be made. - type: integer - retryInterval: - default: 0 + Defines the name of the container within the target Pod where the action will be executed. + + + This name must correspond to one of the containers defined in `componentDefinition.spec.runtime`. + If this field is not specified, the default behavior is to use the first container listed in + `componentDefinition.spec.runtime`. + + + This field cannot be updated. + + + Note: This field is reserved for future use and is not currently active. + type: string + env: description: |- - Indicates the duration of time to wait between each retry attempt. - This value is set to 0 by default, indicating that there will be no delay between retry attempts. - format: int64 - type: integer - type: object - successThreshold: - description: |- - Minimum consecutive successes for the probe to be considered successful after having failed. - Defaults to 1. Minimum value is 1. - format: int32 - type: integer - timeoutSeconds: - default: 0 - description: |- - Specifies the maximum duration in seconds that the Action is allowed to run. + Represents a list of environment variables that will be injected into the container. + These variables enable the container to adapt its behavior based on the environment it's running in. - If the Action does not complete within this time frame, it will be terminated. + This field cannot be updated. + items: + description: EnvVar represents an environment variable + present in a Container. + properties: + name: + description: Name of the environment variable. Must + be a C_IDENTIFIER. + type: string + value: + description: |- + Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in the container and + any service environment variables. If a variable cannot be resolved, + the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless of whether the variable + exists or not. + Defaults to "". + type: string + valueFrom: + description: Source for the environment variable's + value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select + in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required for + volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format + of the exposed resources, defaults to + "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in the + pod's namespace + properties: + key: + description: The key of the secret to select + from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + exec: + description: |- + Defines the command to run. - This field cannot be updated. - format: int32 - type: integer - type: object - switchover: - description: |- - Defines the procedure for a controlled transition of leadership from the current leader to a new replica. - This approach aims to minimize downtime and maintain availability in systems with a leader-follower topology, - during events such as planned maintenance or when performing stop, shutdown, restart, or upgrade operations - involving the current leader node. + This field cannot be updated. + properties: + args: + description: Args represents the arguments that are + passed to the `command` for execution. + items: + type: string + type: array + command: + description: |- + Specifies the command to be executed inside the container. + The working directory for this command is the container's root directory('/'). + Commands are executed directly without a shell environment, meaning shell-specific syntax ('|', etc.) is not supported. + If the shell is required, it must be explicitly invoked in the command. - The container executing this action has access to following variables: + A successful execution is indicated by an exit status of 0; any non-zero status signifies a failure. + items: + type: string + type: array + type: object + http: + description: |- + Specifies the HTTP request to perform. - - KB_SWITCHOVER_CANDIDATE_NAME: The name of the pod for the new leader candidate, which may not be specified (empty). - - KB_SWITCHOVER_CANDIDATE_FQDN: The FQDN of the new leader candidate's pod, which may not be specified (empty). + This field cannot be updated. - Note: This field is immutable once it has been set. - properties: - exec: - description: |- - Defines the command to run. + Note: HTTPAction is to be implemented in future version. + properties: + host: + description: |- + Indicates the server's domain name or IP address. Defaults to the Pod's IP. + Prefer setting the "Host" header in httpHeaders when needed. + type: string + httpHeaders: + description: |- + Allows for the inclusion of custom headers in the request. + HTTP permits the use of repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + method: + description: |- + Represents the type of HTTP request to be made, such as "GET," "POST," "PUT," etc. + If not specified, "GET" is the default method. + type: string + path: + description: Specifies the endpoint to be requested + on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Specifies the target port for the HTTP request. + It can be specified either as a numeric value in the range of 1 to 65535, + or as a named port that meets the IANA_SVC_NAME specification. + x-kubernetes-int-or-string: true + scheme: + description: |- + Designates the protocol used to make the request, such as HTTP or HTTPS. + If not specified, HTTP is used by default. + type: string + required: + - port + type: object + image: + description: |- + Specifies the container image to be used for running the Action. - This field cannot be updated. - properties: - args: - description: Args represents the arguments that are passed - to the `command` for execution. - items: - type: string - type: array - command: + When specified, a dedicated container will be created using this image to execute the Action. + This field is mutually exclusive with the `container` field; only one of them should be provided. + + + This field cannot be updated. + type: string + matchingKey: + description: |- + Used in conjunction with the `targetPodSelector` field to refine the selection of target pod(s) for Action execution. + The impact of this field depends on the `targetPodSelector` value: + + + - When `targetPodSelector` is set to `Any` or `All`, this field will be ignored. + - When `targetPodSelector` is set to `Role`, only those replicas whose role matches the `matchingKey` + will be selected for the Action. + + + This field cannot be updated. + + + Note: This field is reserved for future use and is not currently active. + type: string + preCondition: + description: |- + Specifies the state that the cluster must reach before the Action is executed. + Currently, this is only applicable to the `postProvision` action. + + + The conditions are as follows: + + + - `Immediately`: Executed right after the Component object is created. + The readiness of the Component and its resources is not guaranteed at this stage. + - `RuntimeReady`: The Action is triggered after the Component object has been created and all associated + runtime resources (e.g. Pods) are in a ready state. + - `ComponentReady`: The Action is triggered after the Component itself is in a ready state. + This process does not affect the readiness state of the Component or the Cluster. + - `ClusterReady`: The Action is executed after the Cluster is in a ready state. + This execution does not alter the Component or the Cluster's state of readiness. + + + This field cannot be updated. + type: string + retryPolicy: + description: |- + Defines the strategy to be taken when retrying the Action after a failure. + + + It specifies the conditions under which the Action should be retried and the limits to apply, + such as the maximum number of retries and backoff strategy. + + + This field cannot be updated. + properties: + maxRetries: + default: 0 + description: |- + Defines the maximum number of retry attempts that should be made for a given Action. + This value is set to 0 by default, indicating that no retries will be made. + type: integer + retryInterval: + default: 0 + description: |- + Indicates the duration of time to wait between each retry attempt. + This value is set to 0 by default, indicating that there will be no delay between retry attempts. + format: int64 + type: integer + type: object + targetPodSelector: + description: |- + Defines the criteria used to select the target Pod(s) for executing the Action. + This is useful when there is no default target replica identified. + It allows for precise control over which Pod(s) the Action should run in. + + + This field cannot be updated. + + + Note: This field is reserved for future use and is not currently active. + enum: + - Any + - All + - Role + - Ordinal + type: string + timeoutSeconds: + default: 0 description: |- - Specifies the command to be executed inside the container. - The working directory for this command is the container's root directory('/'). - Commands are executed directly without a shell environment, meaning shell-specific syntax ('|', etc.) is not supported. - If the shell is required, it must be explicitly invoked in the command. + Specifies the maximum duration in seconds that the Action is allowed to run. - A successful execution is indicated by an exit status of 0; any non-zero status signifies a failure. - items: - type: string - type: array - container: - description: |- - Specifies the name of the container within the same pod whose resources will be shared with the action. - This allows the action to utilize the specified container's resources without executing within it. + If the Action does not complete within this time frame, it will be terminated. - The name must match one of the containers defined in `componentDefinition.spec.runtime`. + This field cannot be updated. + format: int32 + type: integer + type: object + withoutCandidate: + description: |- + Represents a switchover process that does not involve a specific candidate primary or leader instance. + As with the previous field, only Action.Exec is currently supported, not Action.HTTP. + properties: + container: + description: |- + Defines the name of the container within the target Pod where the action will be executed. - The resources that can be shared are included: + This name must correspond to one of the containers defined in `componentDefinition.spec.runtime`. + If this field is not specified, the default behavior is to use the first container listed in + `componentDefinition.spec.runtime`. - - volume mounts + This field cannot be updated. - This field cannot be updated. + Note: This field is reserved for future use and is not currently active. type: string env: description: |- @@ -16856,13 +18627,101 @@ spec: - name type: object type: array + exec: + description: |- + Defines the command to run. + + + This field cannot be updated. + properties: + args: + description: Args represents the arguments that are + passed to the `command` for execution. + items: + type: string + type: array + command: + description: |- + Specifies the command to be executed inside the container. + The working directory for this command is the container's root directory('/'). + Commands are executed directly without a shell environment, meaning shell-specific syntax ('|', etc.) is not supported. + If the shell is required, it must be explicitly invoked in the command. + + + A successful execution is indicated by an exit status of 0; any non-zero status signifies a failure. + items: + type: string + type: array + type: object + http: + description: |- + Specifies the HTTP request to perform. + + + This field cannot be updated. + + + Note: HTTPAction is to be implemented in future version. + properties: + host: + description: |- + Indicates the server's domain name or IP address. Defaults to the Pod's IP. + Prefer setting the "Host" header in httpHeaders when needed. + type: string + httpHeaders: + description: |- + Allows for the inclusion of custom headers in the request. + HTTP permits the use of repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + method: + description: |- + Represents the type of HTTP request to be made, such as "GET," "POST," "PUT," etc. + If not specified, "GET" is the default method. + type: string + path: + description: Specifies the endpoint to be requested + on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Specifies the target port for the HTTP request. + It can be specified either as a numeric value in the range of 1 to 65535, + or as a named port that meets the IANA_SVC_NAME specification. + x-kubernetes-int-or-string: true + scheme: + description: |- + Designates the protocol used to make the request, such as HTTP or HTTPS. + If not specified, HTTP is used by default. + type: string + required: + - port + type: object image: description: |- Specifies the container image to be used for running the Action. When specified, a dedicated container will be created using this image to execute the Action. - All actions with same image will share the same container. + This field is mutually exclusive with the `container` field; only one of them should be provided. This field cannot be updated. @@ -16879,85 +18738,86 @@ spec: This field cannot be updated. + + + Note: This field is reserved for future use and is not currently active. type: string - targetPodSelector: + preCondition: description: |- - Defines the criteria used to select the target Pod(s) for executing the Action. - This is useful when there is no default target replica identified. - It allows for precise control over which Pod(s) the Action should run in. + Specifies the state that the cluster must reach before the Action is executed. + Currently, this is only applicable to the `postProvision` action. - If not specified, the Action will be executed in the pod where the Action is triggered, such as the pod - to be removed or added; or a random pod if the Action is triggered at the component level, such as - post-provision or pre-terminate of the component. + The conditions are as follows: - This field cannot be updated. - enum: - - Any - - All - - Role - - Ordinal - type: string - type: object - preCondition: - description: |- - Specifies the state that the cluster must reach before the Action is executed. - Currently, this is only applicable to the `postProvision` action. + - `Immediately`: Executed right after the Component object is created. + The readiness of the Component and its resources is not guaranteed at this stage. + - `RuntimeReady`: The Action is triggered after the Component object has been created and all associated + runtime resources (e.g. Pods) are in a ready state. + - `ComponentReady`: The Action is triggered after the Component itself is in a ready state. + This process does not affect the readiness state of the Component or the Cluster. + - `ClusterReady`: The Action is executed after the Cluster is in a ready state. + This execution does not alter the Component or the Cluster's state of readiness. - The conditions are as follows: + This field cannot be updated. + type: string + retryPolicy: + description: |- + Defines the strategy to be taken when retrying the Action after a failure. - - `Immediately`: Executed right after the Component object is created. - The readiness of the Component and its resources is not guaranteed at this stage. - - `RuntimeReady`: The Action is triggered after the Component object has been created and all associated - runtime resources (e.g. Pods) are in a ready state. - - `ComponentReady`: The Action is triggered after the Component itself is in a ready state. - This process does not affect the readiness state of the Component or the Cluster. - - `ClusterReady`: The Action is executed after the Cluster is in a ready state. - This execution does not alter the Component or the Cluster's state of readiness. + It specifies the conditions under which the Action should be retried and the limits to apply, + such as the maximum number of retries and backoff strategy. - This field cannot be updated. - type: string - retryPolicy: - description: |- - Defines the strategy to be taken when retrying the Action after a failure. + This field cannot be updated. + properties: + maxRetries: + default: 0 + description: |- + Defines the maximum number of retry attempts that should be made for a given Action. + This value is set to 0 by default, indicating that no retries will be made. + type: integer + retryInterval: + default: 0 + description: |- + Indicates the duration of time to wait between each retry attempt. + This value is set to 0 by default, indicating that there will be no delay between retry attempts. + format: int64 + type: integer + type: object + targetPodSelector: + description: |- + Defines the criteria used to select the target Pod(s) for executing the Action. + This is useful when there is no default target replica identified. + It allows for precise control over which Pod(s) the Action should run in. - It specifies the conditions under which the Action should be retried and the limits to apply, - such as the maximum number of retries and backoff strategy. + This field cannot be updated. - This field cannot be updated. - properties: - maxRetries: - default: 0 - description: |- - Defines the maximum number of retry attempts that should be made for a given Action. - This value is set to 0 by default, indicating that no retries will be made. - type: integer - retryInterval: + Note: This field is reserved for future use and is not currently active. + enum: + - Any + - All + - Role + - Ordinal + type: string + timeoutSeconds: default: 0 description: |- - Indicates the duration of time to wait between each retry attempt. - This value is set to 0 by default, indicating that there will be no delay between retry attempts. - format: int64 - type: integer - type: object - timeoutSeconds: - default: 0 - description: |- - Specifies the maximum duration in seconds that the Action is allowed to run. + Specifies the maximum duration in seconds that the Action is allowed to run. - If the Action does not complete within this time frame, it will be terminated. + If the Action does not complete within this time frame, it will be terminated. - This field cannot be updated. - format: int32 - type: integer + This field cannot be updated. + format: int32 + type: integer + type: object type: object type: object logConfigs: @@ -17027,6 +18887,40 @@ spec: format: int32 minimum: 0 type: integer + monitor: + description: |- + Deprecated since v0.9 + monitor is monitoring config which provided by provider. + properties: + builtIn: + default: false + description: |- + builtIn is a switch to enable KubeBlocks builtIn monitoring. + If BuiltIn is set to true, monitor metrics will be scraped automatically. + If BuiltIn is set to false, the provider should set ExporterConfig and Sidecar container own. + type: boolean + exporterConfig: + description: |- + exporterConfig provided by provider, which specify necessary information to Time Series Database. + exporterConfig is valid when builtIn is false. + properties: + scrapePath: + default: /metrics + description: scrapePath is exporter url path for Time Series + Database to scrape metrics. + maxLength: 128 + type: string + scrapePort: + anyOf: + - type: integer + - type: string + description: scrapePort is exporter port for Time Series Database + to scrape metrics. + x-kubernetes-int-or-string: true + required: + - scrapePort + type: object + type: object podManagementPolicy: description: |- InstanceSet controls the creation of pods during initial scale up, replacement of pods on nodes, and scaling down. @@ -17144,6 +19038,19 @@ spec: - message: the minimum replicas limit should be no greater than the maximum rule: self.minReplicas <= self.maxReplicas + roleArbitrator: + default: External + description: |- + This field has been deprecated since v0.9. + This field is maintained for backward compatibility and its use is discouraged. + Existing usage should be updated to the current preferred approach to avoid compatibility issues in future releases. + + + This field is immutable. + enum: + - External + - Lorry + type: string roles: description: |- Enumerate all possible roles assigned to each replica of the Component, influencing its behavior. @@ -25572,29 +27479,6 @@ spec: description: Source for the variable's value. Cannot be used if value is not empty. properties: - clusterVarRef: - description: Selects a defined var of a Cluster. - properties: - clusterName: - description: Reference to the name of the Cluster object. - enum: - - Required - - Optional - type: string - clusterUID: - description: Reference to the UID of the Cluster object. - enum: - - Required - - Optional - type: string - namespace: - description: Reference to the namespace of the Cluster - object. - enum: - - Required - - Optional - type: string - type: object componentVarRef: description: Selects a defined var of a Component. properties: @@ -25610,6 +27494,14 @@ spec: - Required - Optional type: string + instanceNames: + description: |- + Reference to the pod name list of the component. + and the value will be presented in the following format: name1,name2,... + enum: + - Required + - Optional + type: string multipleClusterObjectOption: description: |- This option defines the behavior when multiple component objects match the specified @CompDef. @@ -25674,57 +27566,12 @@ spec: - Required - Optional type: string - podFQDNsForRole: - description: |- - Reference to the pod FQDN list of the component that have a specific role. - The value will be presented in the following format: FQDN1,FQDN2,... - properties: - option: - description: VarOption defines whether a variable - is required or optional. - enum: - - Required - - Optional - type: string - role: - type: string - type: object - podNames: - description: |- - Reference to the pod name list of the component. - and the value will be presented in the following format: name1,name2,... - enum: - - Required - - Optional - type: string - podNamesForRole: - description: |- - Reference to the pod name list of the component that have a specific role. - The value will be presented in the following format: name1,name2,... - properties: - option: - description: VarOption defines whether a variable - is required or optional. - enum: - - Required - - Optional - type: string - role: - type: string - type: object replicas: description: Reference to the replicas of the component. enum: - Required - Optional type: string - shortName: - description: Reference to the short name of the Component - object. - enum: - - Required - - Optional - type: string type: object configMapKeyRef: description: Selects a key of a ConfigMap. @@ -26133,13 +27980,6 @@ spec: - Optional type: string type: object - serviceType: - description: ServiceType references the type of the - service. - enum: - - Required - - Optional - type: string type: object type: object required: diff --git a/docs/developer_docs/api-reference/cluster.md b/docs/developer_docs/api-reference/cluster.md index 4150fd1fb98..348f06342ee 100644 --- a/docs/developer_docs/api-reference/cluster.md +++ b/docs/developer_docs/api-reference/cluster.md @@ -10647,6 +10647,71 @@ ClusterDefinitionSpec + + + + + + + + + + + + + + + + + + + +
    +type
    + +string + +
    +(Optional) +

    Specifies the well-known database type, such as mysql, redis, or mongodb.

    +

    Deprecated since v0.9. +This field is maintained for backward compatibility and its use is discouraged. +Existing usage should be updated to the current preferred approach to avoid compatibility issues in future releases.

    +
    +componentDefs
    + + +[]ClusterComponentDefinition + + +
    +(Optional) +

    Provides the definitions for the cluster components.

    +

    Deprecated since v0.9. +Components should now be individually defined using ComponentDefinition and +collectively referenced via topology.components. +This field is maintained for backward compatibility and its use is discouraged. +Existing usage should be updated to the current preferred approach to avoid compatibility issues in future releases.

    +
    +connectionCredential
    + +map[string]string + +
    +(Optional) +

    Connection credential template used for creating a connection credential secret for cluster objects.

    +

    Built-in objects are:

    +
      +
    • $(RANDOM_PASSWD) random 8 characters.
    • +
    • $(STRONG_RANDOM_PASSWD) random 16 characters, with mixed cases, digits and symbols.
    • +
    • $(UUID) generate a random UUID v4 string.
    • +
    • $(UUID_B64) generate a random UUID v4 BASE64 encoded string.
    • +
    • $(UUID_STR_B64) generate a random UUID v4 string then BASE64 encoded.
    • +
    • $(UUID_HEX) generate a random UUID v4 HEX representation.
    • +
    • $(HEADLESS_SVC_FQDN) headless service FQDN placeholder, value pattern is $(CLUSTER_NAME)-$(1ST_COMP_NAME)-headless.$(NAMESPACE).svc, +where 1ST_COMP_NAME is the 1st component that provide ClusterDefinition.spec.componentDefs[].service attribute;
    • +
    • $(SVC_FQDN) service FQDN placeholder, value pattern is $(CLUSTER_NAME)-$(1ST_COMP_NAME).$(NAMESPACE).svc, +where 1ST_COMP_NAME is the 1st component that provide ClusterDefinition.spec.componentDefs[].service attribute;
    • +
    • $(SVC_PORT_{PORT-NAME}) is ServicePort’s port value with specified port name, i.e, a servicePort JSON struct: +{"name": "mysql", "targetPort": "mysqlContainerPort", "port": 3306}, and $(SVC_PORT_mysql) in the +connection credential value is 3306.
    • +
    +

    Deprecated since v0.9. +This field is maintained for backward compatibility and its use is discouraged. +Existing usage should be updated to the current preferred approach to avoid compatibility issues in future releases.

    +
    topologies
    @@ -11416,6 +11481,21 @@ These instance-specific overrides can be specified in cluster.spec.compone
    +monitor
    + + +MonitorConfig + + +
    +(Optional) +

    Deprecated since v0.9 +monitor is monitoring config which provided by provider.

    +
    exporter
    @@ -11784,6 +11864,23 @@ role is updated last. This helps minimize the number of leader changes during th
    +roleArbitrator
    + + +RoleArbitrator + + +
    +(Optional) +

    This field has been deprecated since v0.9. +This field is maintained for backward compatibility and its use is discouraged. +Existing usage should be updated to the current preferred approach to avoid compatibility issues in future releases.

    +

    This field is immutable.

    +
    lifecycleActions
    @@ -12941,6 +13038,9 @@ ServiceDescriptorStatus

    AccessMode (string alias)

    +

    +(Appears on:ConsensusMember) +

    AccessMode defines the modes of access granted to the SVC. The modes can be None, Readonly, or ReadWrite.

    @@ -12963,10 +13063,37 @@ The modes can be None, Readonly, or ReadWrite +

    AccountName +(string alias)

    +

    +(Appears on:SystemAccountConfig) +

    +
    +

    AccountName defines system account names.

    +
    + + + + + + + + + + + + + + + + + + +
    ValueDescription

    "kbadmin"

    "kbdataprotection"

    "kbmonitoring"

    "kbprobe"

    "kbreplicator"

    Action

    -(Appears on:ComponentLifecycleActions, Probe) +(Appears on:ComponentSwitchover, LifecycleActionHandler, Probe)

    Action defines a customizable hook or procedure tailored for different database engines, @@ -12994,6 +13121,8 @@ such as during planned maintenance or upgrades on the current leader node.

    Actions can be executed in different ways:

    • ExecAction: Executes a command inside a container. +which may run as a K8s job or be executed inside the Lorry sidecar container, depending on the implementation. +Future implementations will standardize execution within Lorry. A set of predefined environment variables are available and can be leveraged within the exec.command to access context information such as details about pods, components, the overall cluster state, or database connection credentials. @@ -13025,6 +13154,21 @@ or detailed in the HTTP response with the appropriate non-200 status code.
    • +image
      + +string + + + +(Optional) +

      Specifies the container image to be used for running the Action.

      +

      When specified, a dedicated container will be created using this image to execute the Action. +This field is mutually exclusive with the container field; only one of them should be provided.

      +

      This field cannot be updated.

      + + + + exec
      @@ -13040,6 +13184,93 @@ ExecAction +http
      + +
      +HTTPAction + + + + +(Optional) +

      Specifies the HTTP request to perform.

      +

      This field cannot be updated.

      +

      Note: HTTPAction is to be implemented in future version.

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

      Represents a list of environment variables that will be injected into the container. +These variables enable the container to adapt its behavior based on the environment it’s running in.

      +

      This field cannot be updated.

      + + + + +targetPodSelector
      + + +TargetPodSelector + + + + +(Optional) +

      Defines the criteria used to select the target Pod(s) for executing the Action. +This is useful when there is no default target replica identified. +It allows for precise control over which Pod(s) the Action should run in.

      +

      This field cannot be updated.

      +

      Note: This field is reserved for future use and is not currently active.

      + + + + +matchingKey
      + +string + + + +(Optional) +

      Used in conjunction with the targetPodSelector field to refine the selection of target pod(s) for Action execution. +The impact of this field depends on the targetPodSelector value:

      +
        +
      • When targetPodSelector is set to Any or All, this field will be ignored.
      • +
      • When targetPodSelector is set to Role, only those replicas whose role matches the matchingKey +will be selected for the Action.
      • +
      +

      This field cannot be updated.

      +

      Note: This field is reserved for future use and is not currently active.

      + + + + +container
      + +string + + + +(Optional) +

      Defines the name of the container within the target Pod where the action will be executed.

      +

      This name must correspond to one of the containers defined in componentDefinition.spec.runtime. +If this field is not specified, the default behavior is to use the first container listed in +componentDefinition.spec.runtime.

      +

      This field cannot be updated.

      +

      Note: This field is reserved for future use and is not currently active.

      + + + + timeoutSeconds
      int32 @@ -13791,6 +14022,102 @@ RefNamespaceName

      BaseBackupType the base backup type, keep synchronized with the BaseBackupType of the data protection API.

      +

      BuiltinActionHandlerType +(string alias)

      +

      +(Appears on:LifecycleActionHandler) +

      +
      +

      BuiltinActionHandlerType defines build-in action handlers provided by Lorry, including:

      +
        +
      • mysql
      • +
      • wesql
      • +
      • oceanbase
      • +
      • redis
      • +
      • mongodb
      • +
      • etcd
      • +
      • postgresql
      • +
      • official-postgresql
      • +
      • apecloud-postgresql
      • +
      • polardbx
      • +
      • custom
      • +
      • unknown
      • +
      +
      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      ValueDescription

      "apecloud-postgresql"

      "custom"

      "etcd"

      "mongodb"

      "mysql"

      "oceanbase"

      "official-postgresql"

      "polardbx"

      "postgresql"

      "redis"

      "unknown"

      "wesql"

      +

      ClassDefRef +

      +

      +(Appears on:ClusterComponentSpec) +

      +
      +

      ClassDefRef is deprecated since v0.9.

      +
      + + + + + + + + + + + + + + + + + +
      FieldDescription
      +name
      + +string + +
      +(Optional) +

      Specifies the name of the ComponentClassDefinition.

      +
      +class
      + +string + +
      +

      Defines the name of the class that is defined in the ComponentClassDefinition.

      +

      ClusterBackup

      @@ -13982,469 +14309,886 @@ Kubernetes core/v1.ConfigMapVolumeSource -

      ClusterComponentPhase -(string alias)

      +

      ClusterComponentDefinition +

      -(Appears on:ClusterComponentStatus, ComponentStatus) +(Appears on:ClusterDefinitionSpec)

      -

      ClusterComponentPhase defines the phase of a cluster component as represented in cluster.status.components.phase field.

      +

      ClusterComponentDefinition defines a Component within a ClusterDefinition but is deprecated and +has been replaced by ComponentDefinition.

      +

      Deprecated: Use ComponentDefinition instead. This type is deprecated as of version 0.8.

      - + - - - - - - - - - - - - - - + + - - - -
      ValueField Description

      "Abnormal"

      AbnormalClusterCompPhase indicates the component has more than zero replicas, but there are some failed pods. -The component is functioning, but it is in a fragile state.

      -

      "Creating"

      CreatingClusterCompPhase indicates the component is being created.

      -

      "Deleting"

      DeletingClusterCompPhase indicates the component is currently being deleted.

      -

      "Failed"

      FailedClusterCompPhase indicates the component has more than zero replicas, but there are some failed pods. -The component is not functioning.

      -

      "Running"

      RunningClusterCompPhase indicates the component has more than zero replicas, and all pods are up-to-date and -in a ‘Running’ state.

      -

      "Stopped"

      StoppedClusterCompPhase indicates the component has zero replicas, and all pods have been deleted.

      -

      "Stopping"

      StoppingClusterCompPhase indicates the component has zero replicas, and there are pods that are terminating.

      +
      +name
      + +string +

      "Updating"

      UpdatingClusterCompPhase indicates the component has more than zero replicas, and there are no failed pods, -it is currently being updated.

      +
      +

      This name could be used as default name of cluster.spec.componentSpecs.name, and needs to conform with same +validation rules as cluster.spec.componentSpecs.name, currently complying with IANA Service Naming rule. +This name will apply to cluster objects as the value of label “apps.kubeblocks.io/component-name”.

      -

      ClusterComponentService -

      -

      -(Appears on:ClusterComponentSpec) -

      -
      -
      - - - - - - - - -
      FieldDescription
      -name
      +description
      string
      -

      References the ComponentService name defined in the componentDefinition.spec.services[*].name.

      +(Optional) +

      Description of the component definition.

      -serviceType
      +workloadType
      - -Kubernetes core/v1.ServiceType + +WorkloadType
      -(Optional) -

      Determines how the Service is exposed. Valid options are ClusterIP, NodePort, and LoadBalancer.

      +

      Defines the type of the workload.

        -
      • ClusterIP allocates a Cluster-internal IP address for load-balancing to endpoints. -Endpoints are determined by the selector or if that is not specified, -they are determined by manual construction of an Endpoints object or EndpointSlice objects.
      • -
      • NodePort builds on ClusterIP and allocates a port on every node which routes to the same endpoints as the ClusterIP.
      • -
      • LoadBalancer builds on NodePort and creates an external load-balancer (if supported in the current cloud) -which routes to the same endpoints as the ClusterIP.
      • +
      • Stateless describes stateless applications.
      • +
      • Stateful describes common stateful applications.
      • +
      • Consensus describes applications based on consensus protocols, such as raft and paxos.
      • +
      • Replication describes applications based on the primary-secondary data replication protocol.
      -

      Note: although K8s Service type allows the ‘ExternalName’ type, it is not a valid option for ClusterComponentService.

      -

      For more info, see: -https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types.

      -annotations
      +characterType
      -map[string]string +string
      (Optional) -

      If ServiceType is LoadBalancer, cloud provider related parameters can be put here. -More info: https://kubernetes.io/docs/concepts/services-networking/service/#loadbalancer.

      +

      Defines well-known database component name, such as mongos(mongodb), proxy(redis), mariadb(mysql).

      -podService
      +configSpecs
      -bool + +[]ComponentConfigSpec +
      (Optional) -

      Indicates whether to generate individual Services for each Pod. -If set to true, a separate Service will be created for each Pod in the Cluster.

      +

      Defines the template of configurations.

      -

      ClusterComponentSpec -

      -

      -(Appears on:ClusterSpec, ShardingSpec) -

      -
      -

      ClusterComponentSpec defines the specification of a Component within a Cluster.

      -
      - - - - - - - - + + + + + + +
      FieldDescription
      -name
      +scriptSpecs
      -string + +[]ComponentTemplateSpec +
      (Optional) -

      Specifies the Component’s name. -It’s part of the Service DNS name and must comply with the IANA service naming rule. -The name is optional when ClusterComponentSpec is used as a template (e.g., in shardingSpec), -but required otherwise.

      +

      Defines the template of scripts.

      -componentDefRef
      +probes
      -string + +ClusterDefinitionProbes +
      (Optional) -

      References a ClusterComponentDefinition defined in the clusterDefinition.spec.componentDef field. -Must comply with the IANA service naming rule.

      -

      Deprecated since v0.9, -because defining Components in clusterDefinition.spec.componentDef field has been deprecated. -This field is replaced by the componentDef field, use componentDef instead. -This field is maintained for backward compatibility and its use is discouraged. -Existing usage should be updated to the current preferred approach to avoid compatibility issues in future releases.

      +

      Settings for health checks.

      -componentDef
      +logConfigs
      -string + +[]LogConfig +
      (Optional) -

      References the name of a ComponentDefinition object. -The ComponentDefinition specifies the behavior and characteristics of the Component. -If both componentDefRef and componentDef are provided, -the componentDef will take precedence over componentDefRef.

      +

      Specify the logging files which can be observed and configured by cluster users.

      -serviceVersion
      +podSpec
      -string + +Kubernetes core/v1.PodSpec +
      (Optional) -

      ServiceVersion specifies the version of the Service expected to be provisioned by this Component. -The version should follow the syntax and semantics of the “Semantic Versioning” specification (http://semver.org/). -If no version is specified, the latest available version will be used.

      +

      Defines the pod spec template of component.

      -serviceRefs
      +service
      - -[]ServiceRef + +ServiceSpec
      (Optional) -

      Defines a list of ServiceRef for a Component, enabling access to both external services and -Services provided by other Clusters.

      -

      Types of services:

      -
        -
      • External services: Not managed by KubeBlocks or managed by a different KubeBlocks operator; -Require a ServiceDescriptor for connection details.
      • -
      • Services provided by a Cluster: Managed by the same KubeBlocks operator; -identified using Cluster, Component and Service names.
      • -
      -

      ServiceRefs with identical serviceRef.name in the same Cluster are considered the same.

      -

      Example:

      -
      serviceRefs:
      -  - name: "redis-sentinel"
      -    serviceDescriptor:
      -      name: "external-redis-sentinel"
      -  - name: "postgres-cluster"
      -    clusterServiceSelector:
      -      cluster: "my-postgres-cluster"
      -      service:
      -        component: "postgresql"
      -
      -

      The example above includes ServiceRefs to an external Redis Sentinel service and a PostgreSQL Cluster.

      +

      Defines the service spec.

      -enabledLogs
      +statelessSpec
      -[]string + +StatelessSetSpec +
      (Optional) -

      Specifies which types of logs should be collected for the Component. -The log types are defined in the componentDefinition.spec.logConfigs field with the LogConfig entries.

      -

      The elements in the enabledLogs array correspond to the names of the LogConfig entries. -For example, if the componentDefinition.spec.logConfigs defines LogConfig entries with -names “slow_query_log” and “error_log”, -you can enable the collection of these logs by including their names in the enabledLogs array:

      -
      enabledLogs:
      -- slow_query_log
      -- error_log
      -
      +

      Defines spec for Stateless workloads.

      -labels
      +statefulSpec
      -map[string]string + +StatefulSetSpec +
      (Optional) -

      Specifies Labels to override or add for underlying Pods.

      +

      Defines spec for Stateful workloads.

      -annotations
      +consensusSpec
      -map[string]string + +ConsensusSetSpec +
      (Optional) -

      Specifies Annotations to override or add for underlying Pods.

      +

      Defines spec for Consensus workloads. It’s required if the workload type is Consensus.

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

      List of environment variables to add. -These environment variables will be placed after the environment variables declared in the Pod.

      +

      Defines spec for Replication workloads.

      -replicas
      +rsmSpec
      -int32 + +RSMSpec +
      -

      Specifies the desired number of replicas in the Component for enhancing availability and durability, or load balancing.

      +(Optional) +

      Defines workload spec of this component. +From KB 0.7.0, RSM(InstanceSetSpec) will be the underlying CR which powers all kinds of workload in KB. +RSM is an enhanced stateful workload extension dedicated for heavy-state workloads like databases.

      -affinity
      +horizontalScalePolicy
      - -Affinity + +HorizontalScalePolicy
      (Optional) -

      Specifies a group of affinity scheduling rules for the Component. -It allows users to control how the Component’s Pods are scheduled onto nodes in the K8s cluster.

      -

      Deprecated since v0.10, replaced by the schedulingPolicy field.

      +

      Defines the behavior of horizontal scale.

      -tolerations
      +systemAccounts
      - -[]Kubernetes core/v1.Toleration + +SystemAccountSpec
      (Optional) -

      Allows Pods to be scheduled onto nodes with matching taints. -Each toleration in the array allows the Pod to tolerate node taints based on -specified key, value, effect, and operator.

      -
        -
      • The key, value, and effect identify the taint that the toleration matches.
      • -
      • The operator determines how the toleration matches the taint.
      • -
      -

      Pods with matching tolerations are allowed to be scheduled on tainted nodes, typically reserved for specific purposes.

      -

      Deprecated since v0.10, replaced by the schedulingPolicy field.

      +

      Defines system accounts needed to manage the component, and the statement to create them.

      -schedulingPolicy
      +volumeTypes
      - -SchedulingPolicy + +[]VolumeTypeSpec
      (Optional) -

      Specifies the scheduling policy for the Component.

      +

      Used to describe the purpose of the volumes mapping the name of the VolumeMounts in the PodSpec.Container field, +such as data volume, log volume, etc. When backing up the volume, the volume can be correctly backed up according +to the volumeType.

      +

      For example:

      +
        +
      • name: data, type: data means that the volume named data is used to store data.
      • +
      • name: binlog, type: log means that the volume named binlog is used to store log.
      • +
      +

      NOTE: When volumeTypes is not defined, the backup function will not be supported, even if a persistent volume has +been specified.

      -resources
      +customLabelSpecs
      - -Kubernetes core/v1.ResourceRequirements + +[]CustomLabelSpec
      (Optional) -

      Specifies the resources required by the Component. -It allows defining the CPU, memory requirements and limits for the Component’s containers.

      +

      Used for custom label tags which you want to add to the component resources.

      -volumeClaimTemplates
      +switchoverSpec
      - -[]ClusterComponentVolumeClaimTemplate + +SwitchoverSpec
      (Optional) -

      Specifies a list of PersistentVolumeClaim templates that represent the storage requirements for the Component. -Each template specifies the desired characteristics of a persistent volume, such as storage class, -size, and access modes. -These templates are used to dynamically provision persistent volumes for the Component.

      +

      Defines command to do switchover. +In particular, when workloadType=Replication, the command defined in switchoverSpec will only be executed under +the condition of cluster.componentSpecs[x].SwitchPolicy.type=Noop.

      -volumes
      +postStartSpec
      - -[]Kubernetes core/v1.Volume + +PostStartAction
      (Optional) -

      List of volumes to override.

      +

      Defines the command to be executed when the component is ready, and the command will only be executed once after +the component becomes ready.

      -services
      +volumeProtectionSpec
      - -[]ClusterComponentService + +VolumeProtectionSpec
      (Optional) -

      Overrides services defined in referenced ComponentDefinition and expose endpoints that can be accessed by clients.

      +

      Defines settings to do volume protect.

      -systemAccounts
      +componentDefRef
      - -[]ComponentSystemAccount + +[]ComponentDefRef
      (Optional) -

      Overrides system accounts defined in referenced ComponentDefinition.

      +

      Used to inject values from other components into the current component. Values will be saved and updated in a +configmap and mounted to the current component.

      -configs
      +serviceRefDeclarations
      - -[]ClusterComponentConfig + +[]ServiceRefDeclaration
      (Optional) -

      Specifies the configuration content of a config template.

      +

      Used to declare the service reference of the current component.

      -switchPolicy
      +exporter
      - -ClusterSwitchPolicy + +Exporter
      (Optional) -

      Defines the strategy for switchover and failover.

      -

      Deprecated since v0.9. -This field is maintained for backward compatibility and its use is discouraged. -Existing usage should be updated to the current preferred approach to avoid compatibility issues in future releases.

      +

      Defines the metrics exporter.

      +
      +monitor
      + + +MonitorConfig + + +
      +(Optional) +

      Deprecated since v0.9 +monitor is monitoring config which provided by provider.

      +
      +

      ClusterComponentPhase +(string alias)

      +

      +(Appears on:ClusterComponentStatus, ComponentStatus) +

      +
      +

      ClusterComponentPhase defines the phase of a cluster component as represented in cluster.status.components.phase field.

      +
      + + + + + + + + + + + + + + + + + + + + + + + + +
      ValueDescription

      "Abnormal"

      AbnormalClusterCompPhase indicates the component has more than zero replicas, but there are some failed pods. +The component is functioning, but it is in a fragile state.

      +

      "Creating"

      CreatingClusterCompPhase indicates the component is being created.

      +

      "Deleting"

      DeletingClusterCompPhase indicates the component is currently being deleted.

      +

      "Failed"

      FailedClusterCompPhase indicates the component has more than zero replicas, but there are some failed pods. +The component is not functioning.

      +

      "Running"

      RunningClusterCompPhase indicates the component has more than zero replicas, and all pods are up-to-date and +in a ‘Running’ state.

      +

      "Stopped"

      StoppedClusterCompPhase indicates the component has zero replicas, and all pods have been deleted.

      +

      "Stopping"

      StoppingClusterCompPhase indicates the component has zero replicas, and there are pods that are terminating.

      +

      "Updating"

      UpdatingClusterCompPhase indicates the component has more than zero replicas, and there are no failed pods, +it is currently being updated.

      +
      +

      ClusterComponentService +

      +

      +(Appears on:ClusterComponentSpec) +

      +
      +
      + + + + + + + + + + + + + + + + + + + + + + + + + +
      FieldDescription
      +name
      + +string + +
      +

      References the ComponentService name defined in the componentDefinition.spec.services[*].name.

      +
      +serviceType
      + + +Kubernetes core/v1.ServiceType + + +
      +(Optional) +

      Determines how the Service is exposed. Valid options are ClusterIP, NodePort, and LoadBalancer.

      +
        +
      • ClusterIP allocates a Cluster-internal IP address for load-balancing to endpoints. +Endpoints are determined by the selector or if that is not specified, +they are determined by manual construction of an Endpoints object or EndpointSlice objects.
      • +
      • NodePort builds on ClusterIP and allocates a port on every node which routes to the same endpoints as the ClusterIP.
      • +
      • LoadBalancer builds on NodePort and creates an external load-balancer (if supported in the current cloud) +which routes to the same endpoints as the ClusterIP.
      • +
      +

      Note: although K8s Service type allows the ‘ExternalName’ type, it is not a valid option for ClusterComponentService.

      +

      For more info, see: +https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types.

      +
      +annotations
      + +map[string]string + +
      +(Optional) +

      If ServiceType is LoadBalancer, cloud provider related parameters can be put here. +More info: https://kubernetes.io/docs/concepts/services-networking/service/#loadbalancer.

      +
      +podService
      + +bool + +
      +(Optional) +

      Indicates whether to generate individual Services for each Pod. +If set to true, a separate Service will be created for each Pod in the Cluster.

      +
      +

      ClusterComponentSpec +

      +

      +(Appears on:ClusterSpec, ShardingSpec) +

      +
      +

      ClusterComponentSpec defines the specification of a Component within a Cluster.

      +
      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -14884,6 +15628,190 @@ Kubernetes core/v1.PersistentVolumeMode
      FieldDescription
      +name
      + +string + +
      +(Optional) +

      Specifies the Component’s name. +It’s part of the Service DNS name and must comply with the IANA service naming rule. +The name is optional when ClusterComponentSpec is used as a template (e.g., in shardingSpec), +but required otherwise.

      +
      +componentDefRef
      + +string + +
      +(Optional) +

      References a ClusterComponentDefinition defined in the clusterDefinition.spec.componentDef field. +Must comply with the IANA service naming rule.

      +

      Deprecated since v0.9, +because defining Components in clusterDefinition.spec.componentDef field has been deprecated. +This field is replaced by the componentDef field, use componentDef instead. +This field is maintained for backward compatibility and its use is discouraged. +Existing usage should be updated to the current preferred approach to avoid compatibility issues in future releases.

      +
      +componentDef
      + +string + +
      +(Optional) +

      References the name of a ComponentDefinition object. +The ComponentDefinition specifies the behavior and characteristics of the Component. +If both componentDefRef and componentDef are provided, +the componentDef will take precedence over componentDefRef.

      +
      +serviceVersion
      + +string + +
      +(Optional) +

      ServiceVersion specifies the version of the Service expected to be provisioned by this Component. +The version should follow the syntax and semantics of the “Semantic Versioning” specification (http://semver.org/). +If no version is specified, the latest available version will be used.

      +
      +classDefRef
      + + +ClassDefRef + + +
      +(Optional) +

      References the class defined in ComponentClassDefinition.

      +

      Deprecated since v0.9. +This field is maintained for backward compatibility and its use is discouraged. +Existing usage should be updated to the current preferred approach to avoid compatibility issues in future releases.

      +
      +serviceRefs
      + + +[]ServiceRef + + +
      +(Optional) +

      Defines a list of ServiceRef for a Component, enabling access to both external services and +Services provided by other Clusters.

      +

      Types of services:

      +
        +
      • External services: Not managed by KubeBlocks or managed by a different KubeBlocks operator; +Require a ServiceDescriptor for connection details.
      • +
      • Services provided by a Cluster: Managed by the same KubeBlocks operator; +identified using Cluster, Component and Service names.
      • +
      +

      ServiceRefs with identical serviceRef.name in the same Cluster are considered the same.

      +

      Example:

      +
      serviceRefs:
      +  - name: "redis-sentinel"
      +    serviceDescriptor:
      +      name: "external-redis-sentinel"
      +  - name: "postgres-cluster"
      +    clusterServiceSelector:
      +      cluster: "my-postgres-cluster"
      +      service:
      +        component: "postgresql"
      +
      +

      The example above includes ServiceRefs to an external Redis Sentinel service and a PostgreSQL Cluster.

      +
      +enabledLogs
      + +[]string + +
      +(Optional) +

      Specifies which types of logs should be collected for the Component. +The log types are defined in the componentDefinition.spec.logConfigs field with the LogConfig entries.

      +

      The elements in the enabledLogs array correspond to the names of the LogConfig entries. +For example, if the componentDefinition.spec.logConfigs defines LogConfig entries with +names “slow_query_log” and “error_log”, +you can enable the collection of these logs by including their names in the enabledLogs array:

      +
      enabledLogs:
      +- slow_query_log
      +- error_log
      +
      +
      +labels
      + +map[string]string + +
      +(Optional) +

      Specifies Labels to override or add for underlying Pods.

      +
      +annotations
      + +map[string]string + +
      +(Optional) +

      Specifies Annotations to override or add for underlying Pods.

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

      List of environment variables to add. +These environment variables will be placed after the environment variables declared in the Pod.

      +
      +replicas
      + +int32 + +
      +

      Specifies the desired number of replicas in the Component for enhancing availability and durability, or load balancing.

      +
      +affinity
      + + +Affinity + + +
      +(Optional) +

      Specifies a group of affinity scheduling rules for the Component. +It allows users to control how the Component’s Pods are scheduled onto nodes in the K8s cluster.

      +

      Deprecated since v0.10, replaced by the schedulingPolicy field.

      +
      +tolerations
      + + +[]Kubernetes core/v1.Toleration + + +
      +(Optional) +

      Allows Pods to be scheduled onto nodes with matching taints. +Each toleration in the array allows the Pod to tolerate node taints based on +specified key, value, effect, and operator.

      +
        +
      • The key, value, and effect identify the taint that the toleration matches.
      • +
      • The operator determines how the toleration matches the taint.
      • +
      +

      Pods with matching tolerations are allowed to be scheduled on tainted nodes, typically reserved for specific purposes.

      +

      Deprecated since v0.10, replaced by the schedulingPolicy field.

      +
      +schedulingPolicy
      + + +SchedulingPolicy + + +
      +(Optional) +

      Specifies the scheduling policy for the Component.

      +
      +resources
      + + +Kubernetes core/v1.ResourceRequirements + + +
      +(Optional) +

      Specifies the resources required by the Component. +It allows defining the CPU, memory requirements and limits for the Component’s containers.

      +
      +volumeClaimTemplates
      + + +[]ClusterComponentVolumeClaimTemplate + + +
      +(Optional) +

      Specifies a list of PersistentVolumeClaim templates that represent the storage requirements for the Component. +Each template specifies the desired characteristics of a persistent volume, such as storage class, +size, and access modes. +These templates are used to dynamically provision persistent volumes for the Component.

      +
      +volumes
      + + +[]Kubernetes core/v1.Volume + + +
      +(Optional) +

      List of volumes to override.

      +
      +services
      + + +[]ClusterComponentService + + +
      +(Optional) +

      Overrides services defined in referenced ComponentDefinition and expose endpoints that can be accessed by clients.

      +
      +systemAccounts
      + + +[]ComponentSystemAccount + + +
      +(Optional) +

      Overrides system accounts defined in referenced ComponentDefinition.

      +
      +configs
      + + +[]ClusterComponentConfig + + +
      +(Optional) +

      Specifies the configuration content of a config template.

      +
      +switchPolicy
      + + +ClusterSwitchPolicy + + +
      +(Optional) +

      Defines the strategy for switchover and failover.

      +

      Deprecated since v0.9. +This field is maintained for backward compatibility and its use is discouraged. +Existing usage should be updated to the current preferred approach to avoid compatibility issues in future releases.

      +

      ClusterDefinitionProbe +

      +

      +(Appears on:ClusterDefinitionProbes) +

      +
      +

      ClusterDefinitionProbe is deprecated since v0.8.

      +
      + + + + + + + + + + + + + + + + + + + + + + + + + +
      FieldDescription
      +periodSeconds
      + +int32 + +
      +

      How often (in seconds) to perform the probe.

      +
      +timeoutSeconds
      + +int32 + +
      +

      Number of seconds after which the probe times out. Defaults to 1 second.

      +
      +failureThreshold
      + +int32 + +
      +

      Minimum consecutive failures for the probe to be considered failed after having succeeded.

      +
      +commands
      + + +ClusterDefinitionProbeCMDs + + +
      +(Optional) +

      Commands used to execute for probe.

      +
      +

      ClusterDefinitionProbeCMDs +

      +

      +(Appears on:ClusterDefinitionProbe) +

      +
      +

      ClusterDefinitionProbeCMDs is deprecated since v0.8.

      +
      + + + + + + + + + + + + + + + + + +
      FieldDescription
      +writes
      + +[]string + +
      +(Optional) +

      Defines write checks that are executed on the probe sidecar.

      +
      +queries
      + +[]string + +
      +(Optional) +

      Defines read checks that are executed on the probe sidecar.

      +
      +

      ClusterDefinitionProbes +

      +

      +(Appears on:ClusterComponentDefinition) +

      +
      +

      ClusterDefinitionProbes is deprecated since v0.8.

      +
      + + + + + + + + + + + + + + + + + + + + + + + + + +
      FieldDescription
      +runningProbe
      + + +ClusterDefinitionProbe + + +
      +(Optional) +

      Specifies the probe used for checking the running status of the component.

      +
      +statusProbe
      + + +ClusterDefinitionProbe + + +
      +(Optional) +

      Specifies the probe used for checking the status of the component.

      +
      +roleProbe
      + + +ClusterDefinitionProbe + + +
      +(Optional) +

      Specifies the probe used for checking the role of the component.

      +
      +roleProbeTimeoutAfterPodsReady
      + +int32 + +
      +(Optional) +

      Defines the timeout (in seconds) for the role probe after all pods of the component are ready. +The system will check if the application is available in the pod. +If pods exceed the InitializationTimeoutSeconds time without a role label, this component will enter the +Failed/Abnormal phase.

      +

      Note that this configuration will only take effect if the component supports RoleProbe +and will not affect the life cycle of the pod. default values are 60 seconds.

      +

      ClusterDefinitionSpec

      @@ -14902,6 +15830,71 @@ Kubernetes core/v1.PersistentVolumeMode +type
      + +string + + + +(Optional) +

      Specifies the well-known database type, such as mysql, redis, or mongodb.

      +

      Deprecated since v0.9. +This field is maintained for backward compatibility and its use is discouraged. +Existing usage should be updated to the current preferred approach to avoid compatibility issues in future releases.

      + + + + +componentDefs
      + + +[]ClusterComponentDefinition + + + + +(Optional) +

      Provides the definitions for the cluster components.

      +

      Deprecated since v0.9. +Components should now be individually defined using ComponentDefinition and +collectively referenced via topology.components. +This field is maintained for backward compatibility and its use is discouraged. +Existing usage should be updated to the current preferred approach to avoid compatibility issues in future releases.

      + + + + +connectionCredential
      + +map[string]string + + + +(Optional) +

      Connection credential template used for creating a connection credential secret for cluster objects.

      +

      Built-in objects are:

      +
        +
      • $(RANDOM_PASSWD) random 8 characters.
      • +
      • $(STRONG_RANDOM_PASSWD) random 16 characters, with mixed cases, digits and symbols.
      • +
      • $(UUID) generate a random UUID v4 string.
      • +
      • $(UUID_B64) generate a random UUID v4 BASE64 encoded string.
      • +
      • $(UUID_STR_B64) generate a random UUID v4 string then BASE64 encoded.
      • +
      • $(UUID_HEX) generate a random UUID v4 HEX representation.
      • +
      • $(HEADLESS_SVC_FQDN) headless service FQDN placeholder, value pattern is $(CLUSTER_NAME)-$(1ST_COMP_NAME)-headless.$(NAMESPACE).svc, +where 1ST_COMP_NAME is the 1st component that provide ClusterDefinition.spec.componentDefs[].service attribute;
      • +
      • $(SVC_FQDN) service FQDN placeholder, value pattern is $(CLUSTER_NAME)-$(1ST_COMP_NAME).$(NAMESPACE).svc, +where 1ST_COMP_NAME is the 1st component that provide ClusterDefinition.spec.componentDefs[].service attribute;
      • +
      • $(SVC_PORT_{PORT-NAME}) is ServicePort’s port value with specified port name, i.e, a servicePort JSON struct: +{"name": "mysql", "targetPort": "mysqlContainerPort", "port": 3306}, and $(SVC_PORT_mysql) in the +connection credential value is 3306.
      • +
      +

      Deprecated since v0.9. +This field is maintained for backward compatibility and its use is discouraged. +Existing usage should be updated to the current preferred approach to avoid compatibility issues in future releases.

      + + + + topologies
      @@ -15956,13 +16949,14 @@ separated by commas.

      -

      ClusterVarSelector +

      CmdExecutorConfig

      -(Appears on:VarSource) +(Appears on:PostStartAction, SwitchoverAction, SystemAccountSpec)

      -

      ClusterVarSelector selects a var from a Cluster.

      +

      CmdExecutorConfig specifies how to perform creation and deletion statements.

      +

      Deprecated since v0.8.

      @@ -15974,27 +16968,43 @@ separated by commas.

      + + + +
      -ClusterVars
      +CommandExecutorEnvItem
      - -ClusterVars + +CommandExecutorEnvItem

      -(Members of ClusterVars are embedded into this type.) +(Members of CommandExecutorEnvItem are embedded into this type.) +

      +
      +CommandExecutorItem
      + + +CommandExecutorItem + + +
      +

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

      -

      ClusterVars +

      CommandExecutorEnvItem

      -(Appears on:ClusterVarSelector) +(Appears on:CmdExecutorConfig)

      +

      CommandExecutorEnvItem is deprecated since v0.8.

      @@ -16006,44 +17016,68 @@ ClusterVars + + + + + +
      -namespace
      +image
      - -VarOption +string + +
      +

      Specifies the image used to execute the command.

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

      Reference to the namespace of the Cluster object.

      +

      A list of environment variables that will be injected into the command execution context.

      +

      CommandExecutorItem +

      +

      +(Appears on:CmdExecutorConfig) +

      +
      +

      CommandExecutorItem is deprecated since v0.8.

      +
      + + + + + + + + @@ -16120,7 +17154,7 @@ MatchExpressions

      ComponentConfigSpec

      -(Appears on:ComponentDefinitionSpec, ConfigurationItemDetail) +(Appears on:ClusterComponentDefinition, ComponentDefinitionSpec, ConfigurationItemDetail)

      @@ -16257,6 +17291,64 @@ or cluster topology. Examples:

      FieldDescription
      -clusterName
      +command
      - -VarOption - +[]string
      -(Optional) -

      Reference to the name of the Cluster object.

      +

      The command to be executed.

      -clusterUID
      +args
      - -VarOption - +[]string
      (Optional) -

      Reference to the UID of the Cluster object.

      +

      Additional parameters used in the execution of the command.

      +

      ComponentDefRef +

      +

      +(Appears on:ClusterComponentDefinition) +

      +
      +

      ComponentDefRef is used to select the component and its fields to be referenced.

      +

      Deprecated since v0.8.

      +
      + + + + + + + + + + + + + + + + + + + + + +
      FieldDescription
      +componentDefName
      + +string + +
      +

      The name of the componentDef to be selected.

      +
      +failurePolicy
      + + +FailurePolicyType + + +
      +(Optional) +

      Defines the policy to be followed in case of a failure in finding the component.

      +
      +componentRefEnv
      + + +[]ComponentRefEnv + + +
      +(Optional) +

      The values that are to be injected as environment variables into each component.

      +

      ComponentDefinitionSpec

      @@ -16411,6 +17503,21 @@ These instance-specific overrides can be specified in cluster.spec.compone +monitor
      + + +MonitorConfig + + + + +(Optional) +

      Deprecated since v0.9 +monitor is monitoring config which provided by provider.

      + + + + exporter
      @@ -16779,6 +17886,23 @@ role is updated last. This helps minimize the number of leader changes during th +roleArbitrator
      + +
      +RoleArbitrator + + + + +(Optional) +

      This field has been deprecated since v0.9. +This field is maintained for backward compatibility and its use is discouraged. +Existing usage should be updated to the current preferred approach to avoid compatibility issues in future releases.

      +

      This field is immutable.

      + + + + lifecycleActions
      @@ -16977,8 +18101,8 @@ The portName is transformed by replacing ‘-’ with &lsqu postProvision
      -
      -Action + +LifecycleActionHandler @@ -16989,6 +18113,28 @@ Action at which the action should trigger: Immediately, RuntimeReady, ComponentReady, and ClusterReady. with ComponentReady being the default.

      The PostProvision Action is intended to run only once.

      +

      The container executing this action has access to following environment variables:

      +
        +
      • KB_CLUSTER_POD_IP_LIST: Comma-separated list of the cluster’s pod IP addresses (e.g., “podIp1,podIp2”).

      • +
      • KB_CLUSTER_POD_NAME_LIST: Comma-separated list of the cluster’s pod names (e.g., “pod1,pod2”).

      • +
      • KB_CLUSTER_POD_HOST_NAME_LIST: Comma-separated list of host names, each corresponding to a pod in +KB_CLUSTER_POD_NAME_LIST (e.g., “hostName1,hostName2”).

      • +
      • KB_CLUSTER_POD_HOST_IP_LIST: Comma-separated list of host IP addresses, each corresponding to a pod in +KB_CLUSTER_POD_NAME_LIST (e.g., “hostIp1,hostIp2”).

      • +
      • KB_CLUSTER_COMPONENT_POD_NAME_LIST: Comma-separated list of all pod names within the component +(e.g., “pod1,pod2”).

      • +
      • KB_CLUSTER_COMPONENT_POD_IP_LIST: Comma-separated list of pod IP addresses, +matching the order of pods in KB_CLUSTER_COMPONENT_POD_NAME_LIST (e.g., “podIp1,podIp2”).

      • +
      • KB_CLUSTER_COMPONENT_POD_HOST_NAME_LIST: Comma-separated list of host names for each pod, +matching the order of pods in KB_CLUSTER_COMPONENT_POD_NAME_LIST (e.g., “hostName1,hostName2”).

      • +
      • KB_CLUSTER_COMPONENT_POD_HOST_IP_LIST: Comma-separated list of host IP addresses for each pod, +matching the order of pods in KB_CLUSTER_COMPONENT_POD_NAME_LIST (e.g., “hostIp1,hostIp2”).

      • +
      • KB_CLUSTER_COMPONENT_LIST: Comma-separated list of all cluster components (e.g., “comp1,comp2”).

      • +
      • KB_CLUSTER_COMPONENT_DELETING_LIST: Comma-separated list of components that are currently being deleted +(e.g., “comp1,comp2”).

      • +
      • KB_CLUSTER_COMPONENT_UNDELETED_LIST: Comma-separated list of components that are not being deleted +(e.g., “comp1,comp2”).

      • +

      Note: This field is immutable once it has been set.

      @@ -16996,8 +18142,8 @@ with ComponentReady being the default.

      preTerminate
      - -Action + +LifecycleActionHandler @@ -17008,6 +18154,33 @@ Action

      This action is executed immediately when a scale-down operation for the Component is initiated. The actual termination and cleanup of the Component and its associated resources will not proceed until the PreTerminate action has completed successfully.

      +

      The container executing this action has access to following environment variables:

      +
        +
      • KB_CLUSTER_POD_IP_LIST: Comma-separated list of the cluster’s pod IP addresses (e.g., “podIp1,podIp2”).

      • +
      • KB_CLUSTER_POD_NAME_LIST: Comma-separated list of the cluster’s pod names (e.g., “pod1,pod2”).

      • +
      • KB_CLUSTER_POD_HOST_NAME_LIST: Comma-separated list of host names, each corresponding to a pod in +KB_CLUSTER_POD_NAME_LIST (e.g., “hostName1,hostName2”).

      • +
      • KB_CLUSTER_POD_HOST_IP_LIST: Comma-separated list of host IP addresses, each corresponding to a pod in +KB_CLUSTER_POD_NAME_LIST (e.g., “hostIp1,hostIp2”).

      • +
      • KB_CLUSTER_COMPONENT_POD_NAME_LIST: Comma-separated list of all pod names within the component +(e.g., “pod1,pod2”).

      • +
      • KB_CLUSTER_COMPONENT_POD_IP_LIST: Comma-separated list of pod IP addresses, +matching the order of pods in KB_CLUSTER_COMPONENT_POD_NAME_LIST (e.g., “podIp1,podIp2”).

      • +
      • KB_CLUSTER_COMPONENT_POD_HOST_NAME_LIST: Comma-separated list of host names for each pod, +matching the order of pods in KB_CLUSTER_COMPONENT_POD_NAME_LIST (e.g., “hostName1,hostName2”).

      • +
      • KB_CLUSTER_COMPONENT_POD_HOST_IP_LIST: Comma-separated list of host IP addresses for each pod, +matching the order of pods in KB_CLUSTER_COMPONENT_POD_NAME_LIST (e.g., “hostIp1,hostIp2”).

      • +
      • KB_CLUSTER_COMPONENT_LIST: Comma-separated list of all cluster components (e.g., “comp1,comp2”).

      • +
      • KB_CLUSTER_COMPONENT_DELETING_LIST: Comma-separated list of components that are currently being deleted +(e.g., “comp1,comp2”).

      • +
      • KB_CLUSTER_COMPONENT_UNDELETED_LIST: Comma-separated list of components that are not being deleted +(e.g., “comp1,comp2”).

      • +
      • KB_CLUSTER_COMPONENT_IS_SCALING_IN: Indicates whether the component is currently scaling in. +If this variable is present and set to “true”, it denotes that the component is undergoing a scale-in operation. +During scale-in, data rebalancing is necessary to maintain cluster integrity. +Contrast this with a cluster deletion scenario where data rebalancing is not required as the entire cluster +is being cleaned up.

      • +

      Note: This field is immutable once it has been set.

      @@ -17015,15 +18188,15 @@ until the PreTerminate action has completed successfully.

      roleProbe
      - -Probe + +RoleProbe (Optional)

      Defines the procedure which is invoked regularly to assess the role of replicas.

      -

      This action is periodically triggered at the specified interval to determine the role of each replica. +

      This action is periodically triggered by Lorry at the specified interval to determine the role of each replica. Upon successful execution, the action’s output designates the role of the replica, which should match one of the predefined role names within componentDefinition.spec.roles. The output is then compared with the previous successful execution result. @@ -17032,9 +18205,12 @@ which initiates an update of the replica’s role.

      Defining a RoleProbe Action for a Component is required if roles are defined for the Component. It ensures replicas are correctly labeled with their respective roles. Without this, services that rely on roleSelectors might improperly direct traffic to wrong replicas.

      -

      The container executing this action has access to following variables:

      +

      The container executing this action has access to following environment variables:

      • KB_POD_FQDN: The FQDN of the Pod whose role is being assessed.
      • +
      • KB_SERVICE_PORT: The port used by the database service.
      • +
      • KB_SERVICE_USER: The username with the necessary permissions to interact with the database service.
      • +
      • KB_SERVICE_PASSWORD: The corresponding password for KB_SERVICE_USER to authenticate with the database service.

      Expected output of this action: - On Success: The determined role of the replica, which must align with one of the roles specified @@ -17047,8 +18223,8 @@ Without this, services that rely on roleSelectors might improperly direct traffi switchover
      - -Action + +ComponentSwitchover @@ -17058,10 +18234,18 @@ Action This approach aims to minimize downtime and maintain availability in systems with a leader-follower topology, during events such as planned maintenance or when performing stop, shutdown, restart, or upgrade operations involving the current leader node.

      -

      The container executing this action has access to following variables:

      +

      The container executing this action has access to following environment variables:

      • KB_SWITCHOVER_CANDIDATE_NAME: The name of the pod for the new leader candidate, which may not be specified (empty).
      • KB_SWITCHOVER_CANDIDATE_FQDN: The FQDN of the new leader candidate’s pod, which may not be specified (empty).
      • +
      • KB_LEADER_POD_IP: The IP address of the current leader’s pod prior to the switchover.
      • +
      • KB_LEADER_POD_NAME: The name of the current leader’s pod prior to the switchover.
      • +
      • KB_LEADER_POD_FQDN: The FQDN of the current leader’s pod prior to the switchover.
      • +
      +

      The environment variables with the following prefixes are deprecated and will be removed in future releases:

      +
        +
      • KB_REPLICATION_PRIMARYPOD
      • +
      • KB_CONSENSUS_LEADERPOD

      Note: This field is immutable once it has been set.

      @@ -17070,8 +18254,8 @@ involving the current leader node.

      memberJoin
      - -Action + +LifecycleActionHandler @@ -17082,10 +18266,15 @@ Action

      The role of the replica (e.g., primary, secondary) will be determined and assigned as part of the action command implementation, or automatically by the database kernel or a sidecar utility like Patroni that implements a consensus algorithm.

      -

      The container executing this action has access to following variables:

      +

      The container executing this action has access to following environment variables:

        -
      • KB_JOIN_MEMBER_POD_FQDN: The pod FQDN of the replica being added to the group.
      • -
      • KB_JOIN_MEMBER_POD_NAME: The pod name of the replica being added to the group.
      • +
      • KB_SERVICE_PORT: The port used by the database service.
      • +
      • KB_SERVICE_USER: The username with the necessary permissions to interact with the database service.
      • +
      • KB_SERVICE_PASSWORD: The corresponding password for KB_SERVICE_USER to authenticate with the database service.
      • +
      • KB_PRIMARY_POD_FQDN: The FQDN of the primary Pod within the replication group.
      • +
      • KB_MEMBER_ADDRESSES: A comma-separated list of Pod addresses for all replicas in the group.
      • +
      • KB_NEW_MEMBER_POD_NAME: The pod name of the replica being added to the group.
      • +
      • KB_NEW_MEMBER_POD_IP: The IP address of the replica being added to the group.

      Expected action output: - On Failure: An error message detailing the reason for any failure encountered @@ -17095,8 +18284,11 @@ during the addition of the new member.

      - bash - -c - | - CLIENT="mysql -u $SERVICE_USER -p$SERVICE_PASSWORD -P $SERVICE_PORT -h $SERVICE_HOST -e" - $CLIENT "ALTER SYSTEM ADD SERVER '$KB_POD_FQDN:$SERVICE_PORT' ZONE 'zone1'" + ADDRESS=$(KB_MEMBER_ADDRESSES%%,*) + HOST=$(echo $ADDRESS | cut -d ':' -f 1) + PORT=$(echo $ADDRESS | cut -d ':' -f 2) + CLIENT="mysql -u $KB_SERVICE_USER -p$KB_SERVICE_PASSWORD -P $PORT -h $HOST -e" + $CLIENT "ALTER SYSTEM ADD SERVER '$KB_NEW_MEMBER_POD_IP:$KB_SERVICE_PORT' ZONE 'zone1'"

      Note: This field is immutable once it has been set.

      @@ -17105,8 +18297,8 @@ during the addition of the new member.

      memberLeave
      - -Action + +LifecycleActionHandler @@ -17118,10 +18310,15 @@ The operator will wait for MemberLeave to complete successfully before releasing related Kubernetes resources.

      The process typically includes updating configurations and informing other group members about the removal. Data migration is generally not part of this action and should be handled separately if needed.

      -

      The container executing this action has access to following variables:

      +

      The container executing this action has access to following environment variables:

        -
      • KB_LEAVE_MEMBER_POD_FQDN: The pod name of the replica being removed from the group.
      • +
      • KB_SERVICE_PORT: The port used by the database service.
      • +
      • KB_SERVICE_USER: The username with the necessary permissions to interact with the database service.
      • +
      • KB_SERVICE_PASSWORD: The corresponding password for KB_SERVICE_USER to authenticate with the database service.
      • +
      • KB_PRIMARY_POD_FQDN: The FQDN of the primary Pod within the replication group.
      • +
      • KB_MEMBER_ADDRESSES: A comma-separated list of Pod addresses for all replicas in the group.
      • KB_LEAVE_MEMBER_POD_NAME: The pod name of the replica being removed from the group.
      • +
      • KB_LEAVE_MEMBER_POD_IP: The IP address of the replica being removed from the group.

      Expected action output: - On Failure: An error message, if applicable, indicating why the action failed.

      @@ -17130,8 +18327,11 @@ Data migration is generally not part of this action and should be handled separa - bash - -c - | - CLIENT="mysql -u $SERVICE_USER -p$SERVICE_PASSWORD -P $SERVICE_PORT -h $SERVICE_HOST -e" - $CLIENT "ALTER SYSTEM DELETE SERVER '$KB_POD_FQDN:$SERVICE_PORT' ZONE 'zone1'" + ADDRESS=$(KB_MEMBER_ADDRESSES%%,*) + HOST=$(echo $ADDRESS | cut -d ':' -f 1) + PORT=$(echo $ADDRESS | cut -d ':' -f 2) + CLIENT="mysql -u $KB_SERVICE_USER -p$KB_SERVICE_PASSWORD -P $PORT -h $HOST -e" + $CLIENT "ALTER SYSTEM DELETE SERVER '$KB_LEAVE_MEMBER_POD_IP:$KB_SERVICE_PORT' ZONE 'zone1'"

      Note: This field is immutable once it has been set.

      @@ -17140,8 +18340,8 @@ Data migration is generally not part of this action and should be handled separa readonly
      - -Action + +LifecycleActionHandler @@ -17153,6 +18353,9 @@ This action is invoked when the database’s volume capacity nears its upper

      The container executing this action has access to following environment variables:

      • KB_POD_FQDN: The FQDN of the replica pod whose role is being checked.
      • +
      • KB_SERVICE_PORT: The port used by the database service.
      • +
      • KB_SERVICE_USER: The username with the necessary permissions to interact with the database service.
      • +
      • KB_SERVICE_PASSWORD: The corresponding password for KB_SERVICE_USER to authenticate with the database service.

      Expected action output: - On Failure: An error message, if applicable, indicating why the action failed.

      @@ -17163,8 +18366,8 @@ This action is invoked when the database’s volume capacity nears its upper readwrite
      - -Action + +LifecycleActionHandler @@ -17178,6 +18381,9 @@ both read and write operations.

      The container executing this action has access to following environment variables:

      • KB_POD_FQDN: The FQDN of the replica pod whose role is being checked.
      • +
      • KB_SERVICE_PORT: The port used by the database service.
      • +
      • KB_SERVICE_USER: The username with the necessary permissions to interact with the database service.
      • +
      • KB_SERVICE_PASSWORD: The corresponding password for KB_SERVICE_USER to authenticate with the database service.

      Expected action output: - On Failure: An error message, if applicable, indicating why the action failed.

      @@ -17188,8 +18394,8 @@ both read and write operations.

      dataDump
      - -Action + +LifecycleActionHandler @@ -17212,8 +18418,8 @@ that only the necessary data is exported for import into the new replica.

      dataLoad
      - -Action + +LifecycleActionHandler @@ -17235,8 +18441,8 @@ the action must be able to guarantee idempotence to allow for retries from the b reconfigure
      - -Action + +LifecycleActionHandler @@ -17251,8 +18457,8 @@ Action accountProvision
      - -Action + +LifecycleActionHandler @@ -17262,11 +18468,6 @@ Action

      Use Case: This action is designed to create system accounts that are utilized for replication, monitoring, backup, and other administrative tasks.

      -

      The container executing this action has access to following variables:

      -
        -
      • KB_ACCOUNT_NAME: The name of the system account to be created.
      • -
      • KB_ACCOUNT_STATEMENT: The statement used to create the system account.
      • -

      Note: This field is immutable once it has been set.

      @@ -17308,6 +18509,62 @@ string +

      ComponentRefEnv +

      +

      +(Appears on:ComponentDefRef) +

      +
      +

      ComponentRefEnv specifies name and value of an env.

      +

      Deprecated since v0.8.

      +
      + + + + + + + + + + + + + + + + + + + + + +
      FieldDescription
      +name
      + +string + +
      +

      The name of the env, it must be a C identifier.

      +
      +value
      + +string + +
      +(Optional) +

      The value of the env.

      +
      +valueFrom
      + + +ComponentValueFrom + + +
      +(Optional) +

      The source from which the value of the env.

      +

      ComponentResourceKey (string alias)

      @@ -17902,62 +19159,127 @@ int64 -conditions
      +conditions
      + + +[]Kubernetes meta/v1.Condition + + + + +(Optional) +

      Represents a list of detailed status of the Component object. +Each condition in the list provides real-time information about certain aspect of the Component object.

      +

      This field is crucial for administrators and developers to monitor and respond to changes within the Component. +It provides a history of state transitions and a snapshot of the current state that can be used for +automated logic or direct inspection.

      + + + + +phase
      + + +ClusterComponentPhase + + + + +

      Indicates the current phase of the Component, with each phase indicating specific conditions:

      +
        +
      • Creating: The initial phase for new Components, transitioning from ‘empty’(“”).
      • +
      • Running: All Pods in a Running state.
      • +
      • Updating: The Component is currently being updated, with no failed Pods present.
      • +
      • Abnormal: Some Pods have failed, indicating a potentially unstable state. +However, the cluster remains available as long as a quorum of members is functioning.
      • +
      • Failed: A significant number of Pods or critical Pods have failed +The cluster may be non-functional or may offer only limited services (e.g, read-only).
      • +
      • Stopping: All Pods are being terminated, with current replica count at zero.
      • +
      • Stopped: All associated Pods have been successfully deleted.
      • +
      • Deleting: The Component is being deleted.
      • +
      + + + + +message
      + + +ComponentMessageMap + + + + +(Optional) +

      A map that stores detailed message about the Component. +Each entry in the map provides insights into specific elements of the Component, such as Pods or workloads.

      +

      Keys in this map are formatted as ObjectKind/Name, where ObjectKind could be a type like Pod, +and Name is the specific name of the object.

      + + + + +

      ComponentSwitchover +

      +

      +(Appears on:ComponentLifecycleActions) +

      +
      +
      + + + + + + + + + + @@ -18023,7 +19345,7 @@ ProvisionSecretRef

      ComponentTemplateSpec

      -(Appears on:ComponentConfigSpec, ComponentDefinitionSpec) +(Appears on:ClusterComponentDefinition, ComponentConfigSpec, ComponentDefinitionSpec)

      @@ -18109,6 +19431,111 @@ Refers to documents of k8s.ConfigMapVolumeSource.defaultMode for more informatio
      FieldDescription
      +withCandidate
      - -[]Kubernetes meta/v1.Condition + +Action
      (Optional) -

      Represents a list of detailed status of the Component object. -Each condition in the list provides real-time information about certain aspect of the Component object.

      -

      This field is crucial for administrators and developers to monitor and respond to changes within the Component. -It provides a history of state transitions and a snapshot of the current state that can be used for -automated logic or direct inspection.

      +

      Represents the switchover process for a specified candidate primary or leader instance. +Note that only Action.Exec is currently supported, while Action.HTTP is not.

      -phase
      +withoutCandidate
      - -ClusterComponentPhase + +Action
      -

      Indicates the current phase of the Component, with each phase indicating specific conditions:

      -
        -
      • Creating: The initial phase for new Components, transitioning from ‘empty’(“”).
      • -
      • Running: All Pods in a Running state.
      • -
      • Updating: The Component is currently being updated, with no failed Pods present.
      • -
      • Abnormal: Some Pods have failed, indicating a potentially unstable state. -However, the cluster remains available as long as a quorum of members is functioning.
      • -
      • Failed: A significant number of Pods or critical Pods have failed -The cluster may be non-functional or may offer only limited services (e.g, read-only).
      • -
      • Stopping: All Pods are being terminated, with current replica count at zero.
      • -
      • Stopped: All associated Pods have been successfully deleted.
      • -
      • Deleting: The Component is being deleted.
      • -
      +(Optional) +

      Represents a switchover process that does not involve a specific candidate primary or leader instance. +As with the previous field, only Action.Exec is currently supported, not Action.HTTP.

      -message
      +scriptSpecSelectors
      - -ComponentMessageMap + +[]ScriptSpecSelector
      (Optional) -

      A map that stores detailed message about the Component. -Each entry in the map provides insights into specific elements of the Component, such as Pods or workloads.

      -

      Keys in this map are formatted as ObjectKind/Name, where ObjectKind could be a type like Pod, -and Name is the specific name of the object.

      +

      Used to define the selectors for the scriptSpecs that need to be referenced. +If this field is set, the scripts defined under the ‘scripts’ field can be invoked or referenced within an Action.

      +

      This field is deprecated from v0.9. +This field is maintained for backward compatibility and its use is discouraged. +Existing usage should be updated to the current preferred approach to avoid compatibility issues in future releases.

      +

      ComponentValueFrom +

      +

      +(Appears on:ComponentRefEnv) +

      +
      +

      ComponentValueFrom is deprecated since v0.8.

      +
      + + + + + + + + + + + + + + + + + + + + + + + + + +
      FieldDescription
      +type
      + + +ComponentValueFromType + + +
      +

      Specifies the source to select. It can be one of three types: FieldRef, ServiceRef, HeadlessServiceRef.

      +
      +fieldPath
      + +string + +
      +(Optional) +

      The jsonpath of the source to select when the Type is FieldRef. +Two objects are registered in the jsonpath: componentDef and components:

      +
        +
      • componentDef is the component definition object specified in componentRef.componentDefName.
      • +
      • components are the component list objects referring to the component definition object.
      • +
      +
      +format
      + +string + +
      +(Optional) +

      Defines the format of each headless service address. +Three builtin variables can be used as placeholders: $POD_ORDINAL, $POD_FQDN, $POD_NAME

      +
        +
      • $POD_ORDINAL represents the ordinal of the pod.
      • +
      • $POD_FQDN represents the fully qualified domain name of the pod.
      • +
      • $POD_NAME represents the name of the pod.
      • +
      +
      +joinWith
      + +string + +
      +(Optional) +

      The string used to join the values of headless service addresses.

      +
      +

      ComponentValueFromType +(string alias)

      +

      +(Appears on:ComponentValueFrom) +

      +
      +

      ComponentValueFromType specifies the type of component value from which the data is derived.

      +

      Deprecated since v0.8.

      +
      + + + + + + + + + + + + + + +
      ValueDescription

      "FieldRef"

      FromFieldRef refers to the value of a specific field in the object.

      +

      "HeadlessServiceRef"

      FromHeadlessServiceRef refers to a headless service within the same namespace as the object.

      +

      "ServiceRef"

      FromServiceRef refers to a service within the same namespace as the object.

      +

      ComponentVarSelector

      @@ -18189,20 +19616,6 @@ VarOption -shortName
      - - -VarOption - - - - -(Optional) -

      Reference to the short name of the Component object.

      - - - - replicas
      @@ -18217,7 +19630,7 @@ VarOption -podNames
      +instanceNames
      VarOption @@ -18245,36 +19658,6 @@ VarOption The value will be presented in the following format: FQDN1,FQDN2,…

      - - -podNamesForRole
      - -
      -RoledVar - - - - -(Optional) -

      Reference to the pod name list of the component that have a specific role. -The value will be presented in the following format: name1,name2,…

      - - - - -podFQDNsForRole
      - - -RoledVar - - - - -(Optional) -

      Reference to the pod FQDN list of the component that have a specific role. -The value will be presented in the following format: FQDN1,FQDN2,…

      - -

      ComponentVersionCompatibilityRule @@ -19582,24 +20965,125 @@ updated by the API Server.

      configurationStatus
      - -[]ConfigurationItemDetailStatus - + +[]ConfigurationItemDetailStatus + + + + +

      Provides the status of each component undergoing reconfiguration.

      + + + + +

      ConnectionCredentialAuth +

      +

      +(Appears on:ServiceDescriptorSpec) +

      +
      +

      ConnectionCredentialAuth specifies the authentication credentials required for accessing an external service.

      +
      + + + + + + + + + + + + + + + + + +
      FieldDescription
      +username
      + + +CredentialVar + + +
      +(Optional) +

      Specifies the username for the external service.

      +
      +password
      + + +CredentialVar + + +
      +(Optional) +

      Specifies the password for the external service.

      +
      +

      ConsensusMember +

      +

      +(Appears on:ConsensusSetSpec) +

      +
      +

      ConsensusMember is deprecated since v0.7.

      +
      + + + + + + + + + + + + + + + + + +
      FieldDescription
      +name
      + +string + +
      +

      Specifies the name of the consensus member.

      +
      +accessMode
      + + +AccessMode + + +
      +

      Specifies the services that this member is capable of providing.

      +
      +replicas
      + +int32
      -

      Provides the status of each component undergoing reconfiguration.

      +(Optional) +

      Indicates the number of Pods that perform this role. +The default is 1 for Leader, 0 for Learner, others for Followers.

      -

      ConnectionCredentialAuth +

      ConsensusSetSpec

      -(Appears on:ServiceDescriptorSpec) +(Appears on:ClusterComponentDefinition)

      -

      ConnectionCredentialAuth specifies the authentication credentials required for accessing an external service.

      +

      ConsensusSetSpec is deprecated since v0.7.

      @@ -19611,30 +21095,58 @@ updated by the API Server.

      + + + + + + + + @@ -19832,6 +21344,59 @@ VarOption
      -username
      +StatefulSetSpec
      - -CredentialVar + +StatefulSetSpec + + +
      +

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

      +
      +leader
      + + +ConsensusMember + + +
      +

      Represents a single leader in the consensus set.

      +
      +followers
      + + +[]ConsensusMember
      (Optional) -

      Specifies the username for the external service.

      +

      Members of the consensus set that have voting rights but are not the leader.

      -password
      +learner
      - -CredentialVar + +ConsensusMember
      (Optional) -

      Specifies the password for the external service.

      +

      Represents a member of the consensus set that does not have voting rights.

      +

      CustomLabelSpec +

      +

      +(Appears on:ClusterComponentDefinition) +

      +
      +

      CustomLabelSpec is deprecated since v0.8.

      +
      + + + + + + + + + + + + + + + + + + + + + +
      FieldDescription
      +key
      + +string + +
      +

      The key of the label.

      +
      +value
      + +string + +
      +

      The value of the label.

      +
      +resources
      + + +[]GVKResource + + +
      +

      The resources that will be patched with the label.

      +

      CustomOps

      @@ -19978,37 +21543,207 @@ string (Optional) -

      Hold a string that contains a script written in CUE language that defines a list of configuration items. -Each item is detailed with its name, default value, description, type (e.g. string, integer, float), -and constraints (permissible values or the valid range of values).

      -

      CUE (Configure, Unify, Execute) is a declarative language designed for defining and validating -complex data configurations. -It is particularly useful in environments like K8s where complex configurations and validation rules are common.

      -

      This script functions as a validator for user-provided configurations, ensuring compliance with -the established specifications and constraints.

      +

      Hold a string that contains a script written in CUE language that defines a list of configuration items. +Each item is detailed with its name, default value, description, type (e.g. string, integer, float), +and constraints (permissible values or the valid range of values).

      +

      CUE (Configure, Unify, Execute) is a declarative language designed for defining and validating +complex data configurations. +It is particularly useful in environments like K8s where complex configurations and validation rules are common.

      +

      This script functions as a validator for user-provided configurations, ensuring compliance with +the established specifications and constraints.

      + + + + +schema
      + + +Kubernetes api extensions v1.JSONSchemaProps + + + + +

      Generated from the ‘cue’ field and transformed into a JSON format.

      + + + + +

      EnvMappingVar +

      +

      +(Appears on:BackupMethod) +

      +
      +
      + + + + + + + + + + + + + + + + + +
      FieldDescription
      +key
      + +string + +
      +

      Specifies the environment variable key in the mapping.

      +
      +valueFrom
      + + +ValueFrom + + +
      +

      Specifies the source used to derive the value of the environment variable, +which typically represents the tool image required for backup operation.

      +
      +

      EnvVar +

      +

      +(Appears on:ComponentDefinitionSpec) +

      +
      +

      EnvVar represents a variable present in the env of Pod/Action or the template of config/script.

      +
      + + + + + + + + + + + + + + + + + + + + + + + + + +
      FieldDescription
      +name
      + +string + +
      +

      Name of the variable. Must be a C_IDENTIFIER.

      +
      +value
      + +string + +
      +(Optional) +

      Variable references $(VAR_NAME) are expanded using the previously defined variables in the current context.

      +

      If a variable cannot be resolved, the reference in the input string will be unchanged. +Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e.

      +
        +
      • $$(VAR_NAME) will produce the string literal $(VAR_NAME).
      • +
      +

      Escaped references will never be expanded, regardless of whether the variable exists or not. +Defaults to “”.

      +
      +valueFrom
      + + +VarSource + + +
      +(Optional) +

      Source for the variable’s value. Cannot be used if value is not empty.

      +
      +expression
      + +string + +
      +(Optional) +

      A Go template expression that will be applied to the resolved value of the var.

      +

      The expression will only be evaluated if the var is successfully resolved to a non-credential value.

      +

      The resolved value can be accessed by its name within the expression, system vars and other user-defined +non-credential vars can be used within the expression in the same way. +Notice that, when accessing vars by its name, you should replace all the “-” in the name with “_”, because of +that “-” is not a valid identifier in Go.

      +

      All expressions are evaluated in the order the vars are defined. If a var depends on any vars that also +have expressions defined, be careful about the evaluation order as it may use intermediate values.

      +

      The result of evaluation will be used as the final value of the var. If the expression fails to evaluate, +the resolving of var will also be considered failed.

      +
      +

      EnvVarRef +

      +

      +(Appears on:OpsVarSource) +

      +
      +
      + + + + + + + + + + +
      FieldDescription
      +targetContainerName
      + +string + +
      +(Optional) +

      Specifies the container name in the target Pod. +If not specified, the first container will be used by default.

      -schema
      +envName
      - -Kubernetes api extensions v1.JSONSchemaProps - +string
      -

      Generated from the ‘cue’ field and transformed into a JSON format.

      +

      Defines the name of the environment variable. +This name can originate from an ‘env’ entry or be a data key from an ‘envFrom’ source.

      -

      EnvMappingVar +

      ExecAction

      -(Appears on:BackupMethod) +(Appears on:Action)

      +

      ExecAction describes an Action that executes a command inside a container. +Which may run as a K8s job or be executed inside the Lorry sidecar container, depending on the implementation. +Future implementations will standardize execution within Lorry.

      @@ -20020,38 +21755,40 @@ Kubernetes api extensions v1.JSONSchemaProps
      -key
      +command
      -string +[]string
      -

      Specifies the environment variable key in the mapping.

      +(Optional) +

      Specifies the command to be executed inside the container. +The working directory for this command is the container’s root directory(‘/’). +Commands are executed directly without a shell environment, meaning shell-specific syntax (‘|’, etc.) is not supported. +If the shell is required, it must be explicitly invoked in the command.

      +

      A successful execution is indicated by an exit status of 0; any non-zero status signifies a failure.

      -valueFrom
      +args
      - -ValueFrom - +[]string
      -

      Specifies the source used to derive the value of the environment variable, -which typically represents the tool image required for backup operation.

      +(Optional) +

      Args represents the arguments that are passed to the command for execution.

      -

      EnvVar +

      Exporter

      -(Appears on:ComponentDefinitionSpec) +(Appears on:ClusterComponentDefinition, ComponentDefinitionSpec)

      -

      EnvVar represents a variable present in the env of Pod/Action or the template of config/script.

      @@ -20063,75 +21800,63 @@ which typically represents the tool image required for backup operation.

      -name
      +containerName
      string
      -

      Name of the variable. Must be a C_IDENTIFIER.

      +(Optional) +

      Specifies the name of the built-in metrics exporter container.

      -value
      +scrapePath
      string
      (Optional) -

      Variable references $(VAR_NAME) are expanded using the previously defined variables in the current context.

      -

      If a variable cannot be resolved, the reference in the input string will be unchanged. -Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e.

      -
        -
      • $$(VAR_NAME) will produce the string literal $(VAR_NAME).
      • -
      -

      Escaped references will never be expanded, regardless of whether the variable exists or not. -Defaults to “”.

      +

      Specifies the http/https url path to scrape for metrics. +If empty, Prometheus uses the default value (e.g. /metrics).

      -valueFrom
      +scrapePort
      - -VarSource - +string
      (Optional) -

      Source for the variable’s value. Cannot be used if value is not empty.

      +

      Specifies the port name to scrape for metrics.

      -expression
      +scrapeScheme
      -string + +PrometheusScheme +
      (Optional) -

      A Go template expression that will be applied to the resolved value of the var.

      -

      The expression will only be evaluated if the var is successfully resolved to a non-credential value.

      -

      The resolved value can be accessed by its name within the expression, system vars and other user-defined -non-credential vars can be used within the expression in the same way. -Notice that, when accessing vars by its name, you should replace all the “-” in the name with “_”, because of -that “-” is not a valid identifier in Go.

      -

      All expressions are evaluated in the order the vars are defined. If a var depends on any vars that also -have expressions defined, be careful about the evaluation order as it may use intermediate values.

      -

      The result of evaluation will be used as the final value of the var. If the expression fails to evaluate, -the resolving of var will also be considered failed.

      +

      Specifies the schema to use for scraping. +http and https are the expected values unless you rewrite the __scheme__ label via relabeling. +If empty, Prometheus uses the default value http.

      -

      EnvVarRef +

      ExporterConfig

      -(Appears on:OpsVarSource) +(Appears on:MonitorConfig)

      @@ -20145,38 +21870,37 @@ the resolving of var will also be considered failed.

      -targetContainerName
      +scrapePort
      -string + +Kubernetes api utils intstr.IntOrString + -(Optional) -

      Specifies the container name in the target Pod. -If not specified, the first container will be used by default.

      +

      scrapePort is exporter port for Time Series Database to scrape metrics.

      -envName
      +scrapePath
      string -

      Defines the name of the environment variable. -This name can originate from an ‘env’ entry or be a data key from an ‘envFrom’ source.

      +(Optional) +

      scrapePath is exporter url path for Time Series Database to scrape metrics.

      -

      ExecAction +

      Expose

      -(Appears on:Action) +(Appears on:SpecificOpsRequest)

      -

      ExecAction describes an Action that executes a command inside a container.

      @@ -20188,199 +21912,273 @@ This name can originate from an ‘env’ entry or be a data key from an + + +
      -image
      +componentName
      string
      -(Optional) -

      Specifies the container image to be used for running the Action.

      -

      When specified, a dedicated container will be created using this image to execute the Action. -All actions with same image will share the same container.

      -

      This field cannot be updated.

      +

      Specifies the name of the Component.

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

      Represents a list of environment variables that will be injected into the container. -These variables enable the container to adapt its behavior based on the environment it’s running in.

      -

      This field cannot be updated.

      +

      Indicates whether the services will be exposed. +‘Enable’ exposes the services. while ‘Disable’ removes the exposed Service.

      -command
      +services
      -[]string + +[]OpsService +
      -(Optional) -

      Specifies the command to be executed inside the container. -The working directory for this command is the container’s root directory(‘/’). -Commands are executed directly without a shell environment, meaning shell-specific syntax (‘|’, etc.) is not supported. -If the shell is required, it must be explicitly invoked in the command.

      -

      A successful execution is indicated by an exit status of 0; any non-zero status signifies a failure.

      +

      Specifies a list of OpsService. +When an OpsService is exposed, a corresponding ClusterService will be added to cluster.spec.services. +On the other hand, when an OpsService is unexposed, the corresponding ClusterService will be removed +from cluster.spec.services.

      +

      Note: If componentName is not specified, the ports and selector fields must be provided +in each OpsService definition.

      +
      +

      ExposeSwitch +(string alias)

      +

      +(Appears on:Expose) +

      +
      +

      ExposeSwitch Specifies the switch for the expose operation. This switch can be used to enable or disable the expose operation.

      +
      + + + + + + + + + + + + +
      ValueDescription

      "Disable"

      "Enable"

      +

      FailurePolicyType +(string alias)

      +

      +(Appears on:ComponentDefRef, OpsAction) +

      +
      +

      FailurePolicyType specifies the type of failure policy.

      +
      + + + + + + + + + + + + +
      ValueDescription

      "Fail"

      FailurePolicyFail means that an error will be reported.

      "Ignore"

      FailurePolicyIgnore means that an error will be ignored but logged.

      +
      +

      GVKResource +

      +

      +(Appears on:CustomLabelSpec) +

      +
      +

      GVKResource is deprecated since v0.8.

      +
      + + + + + + + + + +
      FieldDescription
      -args
      +gvk
      -[]string +string
      -(Optional) -

      Args represents the arguments that are passed to the command for execution.

      +

      Represents the GVK of a resource, such as “v1/Pod”, “apps/v1/StatefulSet”, etc. +When a resource matching this is found by the selector, a custom label will be added if it doesn’t already exist, +or updated if it does.

      -targetPodSelector
      +selector
      - -TargetPodSelector - +map[string]string
      (Optional) -

      Defines the criteria used to select the target Pod(s) for executing the Action. -This is useful when there is no default target replica identified. -It allows for precise control over which Pod(s) the Action should run in.

      -

      If not specified, the Action will be executed in the pod where the Action is triggered, such as the pod -to be removed or added; or a random pod if the Action is triggered at the component level, such as -post-provision or pre-terminate of the component.

      -

      This field cannot be updated.

      +

      A label query used to filter a set of resources.

      +
      +

      HScaleDataClonePolicyType +(string alias)

      +

      +(Appears on:HorizontalScalePolicy) +

      +
      +

      HScaleDataClonePolicyType defines the data clone policy to be used during horizontal scaling. +This policy determines how data is handled when new nodes are added to the cluster. +The policy can be set to None, CloneVolume, or Snapshot.

      +
      + + + + + + + + + + + + + + +
      ValueDescription

      "CloneVolume"

      HScaleDataClonePolicyCloneVolume indicates that data will be cloned from existing volumes during horizontal scaling.

      +

      "Snapshot"

      HScaleDataClonePolicyFromSnapshot indicates that data will be cloned from a snapshot during horizontal scaling.

      "None"

      HScaleDataClonePolicyNone indicates that no data cloning will occur during horizontal scaling.

      +
      +

      HTTPAction +

      +

      +(Appears on:Action) +

      +
      +

      HTTPAction describes an Action that triggers HTTP requests. +HTTPAction is to be implemented in future version.

      +
      + + + + + + + - -
      FieldDescription
      -matchingKey
      +path
      string
      (Optional) -

      Used in conjunction with the targetPodSelector field to refine the selection of target pod(s) for Action execution. -The impact of this field depends on the targetPodSelector value:

      -
        -
      • When targetPodSelector is set to Any or All, this field will be ignored.
      • -
      • When targetPodSelector is set to Role, only those replicas whose role matches the matchingKey -will be selected for the Action.
      • -
      -

      This field cannot be updated.

      +

      Specifies the endpoint to be requested on the HTTP server.

      -container
      +port
      -string + +Kubernetes api utils intstr.IntOrString +
      -(Optional) -

      Specifies the name of the container within the same pod whose resources will be shared with the action. -This allows the action to utilize the specified container’s resources without executing within it.

      -

      The name must match one of the containers defined in componentDefinition.spec.runtime.

      -

      The resources that can be shared are included:

      -
        -
      • volume mounts
      • -
      -

      This field cannot be updated.

      +

      Specifies the target port for the HTTP request. +It can be specified either as a numeric value in the range of 1 to 65535, +or as a named port that meets the IANA_SVC_NAME specification.

      -

      Exporter -

      -

      -(Appears on:ComponentDefinitionSpec) -

      -
      -
      - - - - - - - -
      FieldDescription
      -containerName
      +host
      string
      (Optional) -

      Specifies the name of the built-in metrics exporter container.

      +

      Indicates the server’s domain name or IP address. Defaults to the Pod’s IP. +Prefer setting the “Host” header in httpHeaders when needed.

      -scrapePath
      +scheme
      -string + +Kubernetes core/v1.URIScheme +
      (Optional) -

      Specifies the http/https url path to scrape for metrics. -If empty, Prometheus uses the default value (e.g. /metrics).

      +

      Designates the protocol used to make the request, such as HTTP or HTTPS. +If not specified, HTTP is used by default.

      -scrapePort
      +method
      string
      (Optional) -

      Specifies the port name to scrape for metrics.

      +

      Represents the type of HTTP request to be made, such as “GET,” “POST,” “PUT,” etc. +If not specified, “GET” is the default method.

      -scrapeScheme
      +httpHeaders
      - -PrometheusScheme + +[]Kubernetes core/v1.HTTPHeader
      (Optional) -

      Specifies the schema to use for scraping. -http and https are the expected values unless you rewrite the __scheme__ label via relabeling. -If empty, Prometheus uses the default value http.

      +

      Allows for the inclusion of custom headers in the request. +HTTP permits the use of repeated headers.

      -

      Expose +

      HorizontalScalePolicy

      -(Appears on:SpecificOpsRequest) +(Appears on:ClusterComponentDefinition)

      +

      HorizontalScalePolicy is deprecated since v0.8.

      @@ -20392,93 +22190,52 @@ If empty, Prometheus uses the default value http.

      -componentName
      +type
      -string + +HScaleDataClonePolicyType +
      -

      Specifies the name of the Component.

      +(Optional) +

      Determines the data synchronization method when a component scales out. +The policy can be one of the following: {None, CloneVolume}. The default policy is None.

      +
        +
      • None: This is the default policy. It creates an empty volume without data cloning.
      • +
      • CloneVolume: This policy clones data to newly scaled pods. It first tries to use a volume snapshot. +If volume snapshot is not enabled, it will attempt to use a backup tool. If neither method works, it will report an error.
      • +
      • Snapshot: This policy is deprecated and is an alias for CloneVolume.
      • +
      -switch
      +backupPolicyTemplateName
      - -ExposeSwitch - +string
      -

      Indicates whether the services will be exposed. -‘Enable’ exposes the services. while ‘Disable’ removes the exposed Service.

      +(Optional) +

      Refers to the backup policy template.

      -services
      +volumeMountsName
      - -[]OpsService - +string
      -

      Specifies a list of OpsService. -When an OpsService is exposed, a corresponding ClusterService will be added to cluster.spec.services. -On the other hand, when an OpsService is unexposed, the corresponding ClusterService will be removed -from cluster.spec.services.

      -

      Note: If componentName is not specified, the ports and selector fields must be provided -in each OpsService definition.

      +(Optional) +

      Specifies the volumeMount of the container to backup. +This only works if Type is not None. If not specified, the first volumeMount will be selected.

      -

      ExposeSwitch -(string alias)

      -

      -(Appears on:Expose) -

      -
      -

      ExposeSwitch Specifies the switch for the expose operation. This switch can be used to enable or disable the expose operation.

      -
      - - - - - - - - - - - - -
      ValueDescription

      "Disable"

      "Enable"

      -

      FailurePolicyType -(string alias)

      -

      -(Appears on:OpsAction) -

      -
      -

      FailurePolicyType specifies the type of failure policy.

      -
      - - - - - - - - - - - - -
      ValueDescription

      "Fail"

      FailurePolicyFail means that an error will be reported.

      -

      "Ignore"

      FailurePolicyIgnore means that an error will be ignored but logged.

      -

      HorizontalScaling

      @@ -21419,10 +23176,95 @@ ConfigTemplateExtension +

      LifecycleActionHandler +

      +

      +(Appears on:ComponentLifecycleActions, RoleProbe) +

      +
      +

      LifecycleActionHandler describes the implementation of a specific lifecycle action.

      +

      Each action is deemed successful if it returns an exit code of 0 for command executions, +or an HTTP 200 status for HTTP(s) actions. +Any other exit code or HTTP status is considered an indication of failure.

      +
      + + + + + + + + + + + + + + + + + +
      FieldDescription
      +builtinHandler
      + + +BuiltinActionHandlerType + + +
      +(Optional) +

      Specifies the name of the predefined action handler to be invoked for lifecycle actions.

      +

      Lorry, as a sidecar agent co-located with the database container in the same Pod, +includes a suite of built-in action implementations that are tailored to different database engines. +These are known as “builtin” handlers, includes: mysql, redis, mongodb, etcd, +postgresql, official-postgresql, apecloud-postgresql, wesql, oceanbase, polardbx.

      +

      If the builtinHandler field is specified, it instructs Lorry to utilize its internal built-in action handler +to execute the specified lifecycle actions.

      +

      The builtinHandler field is of type BuiltinActionHandlerType, +which represents the name of the built-in handler. +The builtinHandler specified within the same ComponentLifecycleActions should be consistent across all +actions. +This means that if you specify a built-in handler for one action, you should use the same handler +for all other actions throughout the entire ComponentLifecycleActions collection.

      +

      If you need to define lifecycle actions for database engines not covered by the existing built-in support, +or when the pre-existing built-in handlers do not meet your specific needs, +you can use the customHandler field to define your own action implementation.

      +

      Deprecation Notice:

      +
        +
      • In the future, the builtinHandler field will be deprecated in favor of using the customHandler field +for configuring all lifecycle actions.
      • +
      • Instead of using a name to indicate the built-in action implementations in Lorry, +the recommended approach will be to explicitly invoke the desired action implementation through +a gRPC interface exposed by the sidecar agent.
      • +
      • Developers will have the flexibility to either use the built-in action implementations provided by Lorry +or develop their own sidecar agent to implement custom actions and expose them via gRPC interfaces.
      • +
      • This change will allow for greater customization and extensibility of lifecycle actions, +as developers can create their own “builtin” implementations tailored to their specific requirements.
      • +
      +
      +customHandler
      + + +Action + + +
      +(Optional) +

      Specifies a user-defined hook or procedure that is called to perform the specific lifecycle action. +It offers a flexible and expandable approach for customizing the behavior of a Component by leveraging +tailored actions.

      +

      An Action can be implemented as either an ExecAction or an HTTPAction, with future versions planning +to support GRPCAction, +thereby accommodating unique logic for different database systems within the Action’s framework.

      +

      In future iterations, all built-in handlers are expected to transition to GRPCAction. +This change means that Lorry or other sidecar agents will expose the implementation of actions +through a GRPC interface for external invocation. +Then the controller will interact with these actions via GRPCAction calls.

      +

      LogConfig

      -(Appears on:ComponentDefinitionSpec) +(Appears on:ClusterComponentDefinition, ComponentDefinitionSpec)

      @@ -21536,6 +23378,52 @@ for example, using ‘{{ eq .spec.replicas 1 }}’ +

      MonitorConfig +

      +

      +(Appears on:ClusterComponentDefinition, ComponentDefinitionSpec) +

      +
      +
      + + + + + + + + + + + + + + + + + +
      FieldDescription
      +builtIn
      + +bool + +
      +(Optional) +

      builtIn is a switch to enable KubeBlocks builtIn monitoring. +If BuiltIn is set to true, monitor metrics will be scraped automatically. +If BuiltIn is set to false, the provider should set ExporterConfig and Sidecar container own.

      +
      +exporterConfig
      + + +ExporterConfig + + +
      +(Optional) +

      exporterConfig provided by provider, which specify necessary information to Time Series Database. +exporterConfig is valid when builtIn is false.

      +

      MultipleClusterObjectCombinedOption

      @@ -23421,7 +25309,7 @@ The supported property types include:

      PasswordConfig

      -(Appears on:ComponentSystemAccount, SystemAccount) +(Appears on:ComponentSystemAccount, SystemAccount, SystemAccountSpec)

      PasswordConfig helps provide to customize complexity of password generation pattern.

      @@ -23797,24 +25685,70 @@ string -multiPodSelectionPolicy
      +multiPodSelectionPolicy
      + + +PodSelectionPolicy + + + + +

      Defines the policy for selecting the target pod when multiple pods match the podSelector. +It can be either ‘Any’ (select any one pod that matches the podSelector) +or ‘All’ (select all pods that match the podSelector).

      + + + + +

      PointInTimeRefSpec +

      +
      +
      + + + + + + + + + + + + + +
      FieldDescription
      +time
      + + +Kubernetes meta/v1.Time + + +
      +(Optional) +

      Refers to the specific time point for restoration, with UTC as the time zone.

      +
      +ref
      - -PodSelectionPolicy + +RefNamespaceName
      -

      Defines the policy for selecting the target pod when multiple pods match the podSelector. -It can be either ‘Any’ (select any one pod that matches the podSelector) -or ‘All’ (select all pods that match the podSelector).

      +(Optional) +

      Refers to a reference source cluster that needs to be restored.

      -

      PointInTimeRefSpec +

      PostStartAction

      +

      +(Appears on:ClusterComponentDefinition) +

      +

      PostStartAction is deprecated since v0.8.

      @@ -23826,30 +25760,30 @@ or ‘All’ (select all pods that match the podSelector).

      @@ -24015,9 +25949,6 @@ string
      -time
      +cmdExecutorConfig
      - -Kubernetes meta/v1.Time + +CmdExecutorConfig
      -(Optional) -

      Refers to the specific time point for restoration, with UTC as the time zone.

      +

      Specifies the post-start command to be executed.

      -ref
      +scriptSpecSelectors
      - -RefNamespaceName + +[]ScriptSpecSelector
      (Optional) -

      Refers to a reference source cluster that needs to be restored.

      +

      Used to select the script that need to be referenced. +When defined, the scripts defined in scriptSpecs can be referenced within the CmdExecutorConfig.

      Probe

      -

      -(Appears on:ComponentLifecycleActions) -

      @@ -24204,74 +26135,332 @@ ProgressStatus + + + + + + + + + + + +
      -message
      +message
      + +string + +
      +(Optional) +

      Provides a human-readable explanation of the object’s condition.

      +
      +startTime
      + + +Kubernetes meta/v1.Time + + +
      +(Optional) +

      Records the start time of object processing.

      +
      +endTime
      + + +Kubernetes meta/v1.Time + + +
      +(Optional) +

      Records the completion time of object processing.

      +
      +

      PrometheusScheme +(string alias)

      +

      +(Appears on:Exporter) +

      +
      +

      PrometheusScheme defines the protocol of prometheus scrape metrics.

      +
      + + + + + + + + + + + + +
      ValueDescription

      "http"

      "https"

      +

      ProtectedVolume +

      +

      +(Appears on:VolumeProtectionSpec) +

      +
      +
      + + + + + + + + + + + + + + + + + +
      FieldDescription
      +name
      + +string + +
      +(Optional) +

      The Name of the volume to protect.

      +
      +highWatermark
      + +int + +
      +(Optional) +

      Defines the high watermark threshold for the volume, it will override the component level threshold. +If the value is invalid, it will be ignored and the component level threshold will be used.

      +
      +

      ProvisionPolicy +

      +

      +(Appears on:SystemAccountConfig) +

      +
      +

      ProvisionPolicy defines the policy details for creating accounts.

      +

      Deprecated since v0.9.

      +
      + + + + + + + + + + + + + + + + + + + + + + + + + +
      FieldDescription
      +type
      + + +ProvisionPolicyType + + +
      +

      Specifies the method to provision an account.

      +
      +scope
      + + +ProvisionScope + + +
      +

      Defines the scope within which the account is provisioned.

      +
      +statements
      + + +ProvisionStatements + + +
      +(Optional) +

      The statement to provision an account.

      +
      +secretRef
      + + +ProvisionSecretRef + + +
      +(Optional) +

      The external secret to refer.

      +
      +

      ProvisionPolicyType +(string alias)

      +

      +(Appears on:ProvisionPolicy) +

      +
      +

      ProvisionPolicyType defines the policy for creating accounts.

      +
      + + + + + + + + + + + + +
      ValueDescription

      "CreateByStmt"

      CreateByStmt will create account w.r.t. deletion and creation statement given by provider.

      +

      "ReferToExisting"

      ReferToExisting will not create account, but create a secret by copying data from referred secret file.

      +
      +

      ProvisionScope +(string alias)

      +

      +(Appears on:ProvisionPolicy) +

      +
      +

      ProvisionScope defines the scope of provision within a component.

      +
      + + + + + + + + + + + + +
      ValueDescription

      "AllPods"

      AllPods indicates that accounts will be created for all pods within the component.

      +

      "AnyPods"

      AnyPods indicates that accounts will be created only on a single pod within the component.

      +
      +

      ProvisionSecretRef +

      +

      +(Appears on:ComponentSystemAccount, ProvisionPolicy, SystemAccount) +

      +
      +

      ProvisionSecretRef represents the reference to a secret.

      +
      + + + + + + + + + + + + + + + + + +
      FieldDescription
      +name
      + +string + +
      +

      The unique identifier of the secret.

      +
      +namespace
      + +string + +
      +

      The namespace where the secret is located.

      +
      +

      ProvisionStatements +

      +

      +(Appears on:ProvisionPolicy) +

      +
      +

      ProvisionStatements defines the statements used to create accounts.

      +

      Deprecated since v0.9.

      +
      + + + + + + + + + +
      FieldDescription
      +creation
      string
      -(Optional) -

      Provides a human-readable explanation of the object’s condition.

      +

      Specifies the statement required to create a new account with the necessary privileges.

      -startTime
      +update
      - -Kubernetes meta/v1.Time - +string
      (Optional) -

      Records the start time of object processing.

      +

      Defines the statement required to update the password of an existing account.

      -endTime
      +deletion
      - -Kubernetes meta/v1.Time - +string
      (Optional) -

      Records the completion time of object processing.

      +

      Defines the statement required to delete an existing account. +Typically used in conjunction with the creation statement to delete an account before recreating it. +For example, one might use a drop user if exists statement followed by a create user statement to ensure a fresh account.

      +

      Deprecated: This field is deprecated and the update statement should be used instead.

      -

      PrometheusScheme -(string alias)

      -

      -(Appears on:Exporter) -

      -
      -

      PrometheusScheme defines the protocol of prometheus scrape metrics.

      -
      - - - - - - - - - - - - -
      ValueDescription

      "http"

      "https"

      -

      ProvisionSecretRef +

      RSMSpec

      -(Appears on:ComponentSystemAccount, SystemAccount) +(Appears on:ClusterComponentDefinition)

      -

      ProvisionSecretRef represents the reference to a secret.

      +

      RSMSpec is deprecated since v0.8.

      @@ -24283,24 +26472,63 @@ Kubernetes meta/v1.Time + + + + + + + + @@ -24858,6 +27086,39 @@ int32
      -name
      +roles
      -string + +[]ReplicaRole +
      -

      The unique identifier of the secret.

      +(Optional) +

      Specifies a list of roles defined within the system.

      -namespace
      +roleProbe
      -string + +RoleProbe +
      -

      The namespace where the secret is located.

      +(Optional) +

      Defines the method used to probe a role.

      +
      +membershipReconfiguration
      + + +MembershipReconfiguration + + +
      +(Optional) +

      Indicates the actions required for dynamic membership reconfiguration.

      +
      +memberUpdateStrategy
      + + +MemberUpdateStrategy + + +
      +(Optional) +

      Describes the strategy for updating Members (Pods).

      +
        +
      • Serial: Updates Members sequentially to ensure minimum component downtime.
      • +
      • BestEffortParallel: Updates Members in parallel to ensure minimum component write downtime.
      • +
      • Parallel: Forces parallel updates.
      • +
      +

      ReplicationSetSpec +

      +

      +(Appears on:ClusterComponentDefinition) +

      +
      +

      ReplicationSetSpec is deprecated since v0.7.

      +
      + + + + + + + + + + + + + +
      FieldDescription
      +StatefulSetSpec
      + + +StatefulSetSpec + + +
      +

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

      +

      RerenderResourceType (string alias)

      @@ -25062,10 +27323,32 @@ This value is set to 0 by default, indicating that there will be no delay betwee -

      RoledVar +

      RoleArbitrator +(string alias)

      +

      +(Appears on:ComponentDefinitionSpec) +

      +
      +

      RoleArbitrator defines how to arbitrate the role of replicas.

      +

      Deprecated since v0.9

      +
      + + + + + + + + + + + + +
      ValueDescription

      "External"

      "Lorry"

      +

      RoleProbe

      -(Appears on:ComponentVars) +(Appears on:ComponentLifecycleActions)

      @@ -25079,26 +27362,56 @@ This value is set to 0 by default, indicating that there will be no delay betwee -role
      +LifecycleActionHandler
      -string + +LifecycleActionHandler + + + + +

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

      + + + + +initialDelaySeconds
      + +int32 (Optional) +

      Specifies the number of seconds to wait after the container has started before the RoleProbe +begins to detect the container’s role.

      -option
      +timeoutSeconds
      - -VarOption - +int32 + + + +(Optional) +

      Specifies the number of seconds after which the probe times out. +Defaults to 1 second. Minimum value is 1.

      + + + + +periodSeconds
      + +int32 (Optional) +

      Specifies the frequency at which the probe is conducted. This value is expressed in seconds. +Default to 10 seconds. Minimum value is 1.

      @@ -25440,6 +27753,34 @@ All topologySpreadConstraints are ANDed.

      +

      ScriptSpecSelector +

      +

      +(Appears on:ComponentSwitchover, PostStartAction, SwitchoverAction) +

      +
      +
      + + + + + + + + + + + + + +
      FieldDescription
      +name
      + +string + +
      +

      Represents the name of the ScriptSpec referent.

      +

      SecretRef

      @@ -26083,18 +28424,74 @@ ConnectionCredentialAuth (Optional) -

      Specifies the authentication credentials required for accessing an external service.

      +

      Specifies the authentication credentials required for accessing an external service.

      + + + + +

      ServiceDescriptorStatus +

      +

      +(Appears on:ServiceDescriptor) +

      +
      +

      ServiceDescriptorStatus defines the observed state of ServiceDescriptor

      +
      + + + + + + + + + + + + + + + + + + +
      FieldDescription
      +phase
      + + +Phase + + +
      +(Optional) +

      Indicates the current lifecycle phase of the ServiceDescriptor. This can be either ‘Available’ or ‘Unavailable’.

      +
      +message
      + +string + +
      +(Optional) +

      Provides a human-readable explanation detailing the reason for the current phase of the ServiceConnectionCredential.

      +
      +observedGeneration
      + +int64 + +
      +(Optional) +

      Represents the generation number that has been processed by the controller.

      -

      ServiceDescriptorStatus +

      ServicePort

      -(Appears on:ServiceDescriptor) +(Appears on:ServiceSpec)

      -

      ServiceDescriptorStatus defines the observed state of ServiceDescriptor

      +

      ServicePort is deprecated since v0.8.

      @@ -26106,40 +28503,81 @@ ConnectionCredentialAuth + + + + + + + + @@ -26349,7 +28787,7 @@ string

      ServiceRefDeclaration

      -(Appears on:ComponentDefinitionSpec) +(Appears on:ClusterComponentDefinition, ComponentDefinitionSpec)

      ServiceRefDeclaration represents a reference to a service that can be either provided by a KubeBlocks Cluster @@ -26640,6 +29078,39 @@ CredentialVars

      -phase
      +name
      - -Phase +string + +
      +

      The name of this port within the service. This must be a DNS_LABEL. +All ports within a ServiceSpec must have unique names. When considering +the endpoints for a Service, this must match the ‘name’ field in the +EndpointPort.

      +
      +protocol
      + + +Kubernetes core/v1.Protocol
      (Optional) -

      Indicates the current lifecycle phase of the ServiceDescriptor. This can be either ‘Available’ or ‘Unavailable’.

      +

      The IP protocol for this port. Supports “TCP”, “UDP”, and “SCTP”. +Default is TCP.

      -message
      +appProtocol
      string
      (Optional) -

      Provides a human-readable explanation detailing the reason for the current phase of the ServiceConnectionCredential.

      +

      The application protocol for this port. +This field follows standard Kubernetes label syntax. +Un-prefixed names are reserved for IANA standard service names (as per +RFC-6335 and https://www.iana.org/assignments/service-names). +Non-standard protocols should use prefixed names such as +mycompany.com/my-custom-protocol.

      -observedGeneration
      +port
      -int64 +int32 + +
      +

      The port that will be exposed by this service.

      +
      +targetPort
      + + +Kubernetes api utils intstr.IntOrString +
      (Optional) -

      Represents the generation number that has been processed by the controller.

      +

      Number or name of the port to access on the pods targeted by the service.

      +

      Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME.

      +
        +
      • If this is a string, it will be looked up as a named port in the target Pod’s container ports.
      • +
      • If this is not specified, the value of the port field is used (an identity map).
      • +
      +

      This field is ignored for services with clusterIP=None, and should be +omitted or set equal to the port field.

      +

      More info: https://kubernetes.io/docs/concepts/services-networking/service/#defining-a-service

      +

      ServiceSpec +

      +

      +(Appears on:ClusterComponentDefinition) +

      +
      +

      ServiceSpec is deprecated since v0.8.

      +
      + + + + + + + + + + + + + +
      FieldDescription
      +ports
      + + +[]ServicePort + + +
      +(Optional) +

      The list of ports that are exposed by this service. +More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies

      +

      ServiceVarSelector

      @@ -26708,20 +29179,6 @@ ServiceVars -serviceType
      - - -VarOption - - - - -(Optional) -

      ServiceType references the type of the service.

      - - - - host
      @@ -27087,11 +29544,118 @@ CustomOps +

      StatefulSetSpec +

      +

      +(Appears on:ClusterComponentDefinition, ConsensusSetSpec, ReplicationSetSpec) +

      +
      +

      StatefulSetSpec is deprecated since v0.7.

      +
      + + + + + + + + + + + + + + + + + + + + + +
      FieldDescription
      +updateStrategy
      + + +UpdateStrategy + + +
      +(Optional) +

      Specifies the strategy for updating Pods. +For workloadType=Consensus, the update strategy can be one of the following:

      +
        +
      • Serial: Updates Members sequentially to minimize component downtime.
      • +
      • BestEffortParallel: Updates Members in parallel to minimize component write downtime. Majority remains online +at all times.
      • +
      • Parallel: Forces parallel updates.
      • +
      +
      +llPodManagementPolicy
      + + +Kubernetes apps/v1.PodManagementPolicyType + + +
      +(Optional) +

      Controls the creation of pods during initial scale up, replacement of pods on nodes, and scaling down.

      +
        +
      • OrderedReady: Creates pods in increasing order (pod-0, then pod-1, etc). The controller waits until each pod +is ready before continuing. Pods are removed in reverse order when scaling down.
      • +
      • Parallel: Creates pods in parallel to match the desired scale without waiting. All pods are deleted at once +when scaling down.
      • +
      +
      +llUpdateStrategy
      + + +Kubernetes apps/v1.StatefulSetUpdateStrategy + + +
      +(Optional) +

      Specifies the low-level StatefulSetUpdateStrategy to be used when updating Pods in the StatefulSet upon a +revision to the Template. +UpdateStrategy will be ignored if this is provided.

      +

      StatefulSetWorkload

      StatefulSetWorkload interface

      +

      StatelessSetSpec +

      +

      +(Appears on:ClusterComponentDefinition) +

      +
      +

      StatelessSetSpec is deprecated since v0.7.

      +
      + + + + + + + + + + + + + +
      FieldDescription
      +updateStrategy
      + + +Kubernetes apps/v1.DeploymentStrategy + + +
      +(Optional) +

      Specifies the deployment strategy that will be used to replace existing pods with new ones.

      +

      SwitchPolicyType (string alias)

      @@ -27122,18 +29686,127 @@ logic. If the primary is down, it will switch only if it can be confirmed that t consistent. Otherwise, it will not switch. This policy is planned for future implementation.

      -

      "Noop"

      -

      Noop indicates that KubeBlocks will not perform any high-availability switching for the components. Users are -required to implement their own HA solution or integrate an existing open-source HA solution.

      +

      "Noop"

      +

      Noop indicates that KubeBlocks will not perform any high-availability switching for the components. Users are +required to implement their own HA solution or integrate an existing open-source HA solution.

      + + + +

      Switchover +

      +

      +(Appears on:SpecificOpsRequest) +

      +
      +
      + + + + + + + + + + + + + + + + + +
      FieldDescription
      +ComponentOps
      + + +ComponentOps + + +
      +

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

      +

      Specifies the name of the Component.

      +
      +instanceName
      + +string + +
      +

      Specifies the instance to become the primary or leader during a switchover operation.

      +

      The value of instanceName can be either:

      +
        +
      1. ”*” (wildcard value):
      2. +
      +
        +
      • Indicates no specific instance is designated as the primary or leader.
      • +
      • Executes the switchover action from clusterDefinition.componentDefs[*].switchoverSpec.withoutCandidate.
      • +
      • clusterDefinition.componentDefs[x].switchoverSpec.withoutCandidate must be defined when using “*”.
      • +
      +
        +
      1. A valid instance name (pod name):
      2. +
      +
        +
      • Designates a specific instance (pod) as the primary or leader.
      • +
      • The name must match one of the pods in the component. Any non-valid pod name is considered invalid.
      • +
      • Executes the switchover action from clusterDefinition.componentDefs[*].switchoverSpec.withCandidate.
      • +
      • clusterDefinition.componentDefs[*].switchoverSpec.withCandidate must be defined when specifying a valid instance name.
      • +
      +
      +

      SwitchoverAction +

      +

      +(Appears on:SwitchoverSpec) +

      +
      +

      SwitchoverAction is deprecated since v0.8.

      +
      + + + + + + + + + + + - + + + + + +
      FieldDescription
      +cmdExecutorConfig
      + + +CmdExecutorConfig + + +
      +

      Specifies the switchover command.

      +scriptSpecSelectors
      + + +[]ScriptSpecSelector + + +
      +(Optional) +

      Used to select the script that need to be referenced. +When defined, the scripts defined in scriptSpecs can be referenced within the SwitchoverAction.CmdExecutorConfig.

      +
      -

      Switchover +

      SwitchoverSpec

      -(Appears on:SpecificOpsRequest) +(Appears on:ClusterComponentDefinition)

      +

      SwitchoverSpec is deprecated since v0.8.

      @@ -27145,47 +29818,30 @@ required to implement their own HA solution or integrate an existing open-source @@ -27275,6 +29931,110 @@ ProvisionSecretRef
      -ComponentOps
      +withCandidate
      - -ComponentOps + +SwitchoverAction
      -

      -(Members of ComponentOps are embedded into this type.) -

      -

      Specifies the name of the Component.

      +(Optional) +

      Represents the action of switching over to a specified candidate primary or leader instance.

      -instanceName
      +withoutCandidate
      -string + +SwitchoverAction +
      -

      Specifies the instance to become the primary or leader during a switchover operation.

      -

      The value of instanceName can be either:

      -
        -
      1. ”*” (wildcard value):
      2. -
      -
        -
      • Indicates no specific instance is designated as the primary or leader.
      • -
      • Executes the switchover action from clusterDefinition.componentDefs[*].switchoverSpec.withoutCandidate.
      • -
      • clusterDefinition.componentDefs[x].switchoverSpec.withoutCandidate must be defined when using “*”.
      • -
      -
        -
      1. A valid instance name (pod name):
      2. -
      -
        -
      • Designates a specific instance (pod) as the primary or leader.
      • -
      • The name must match one of the pods in the component. Any non-valid pod name is considered invalid.
      • -
      • Executes the switchover action from clusterDefinition.componentDefs[*].switchoverSpec.withCandidate.
      • -
      • clusterDefinition.componentDefs[*].switchoverSpec.withCandidate must be defined when specifying a valid instance name.
      • -
      +(Optional) +

      Represents the action of switching over without specifying a candidate primary or leader instance.

      +

      SystemAccountConfig +

      +

      +(Appears on:SystemAccountSpec) +

      +
      +

      SystemAccountConfig specifies how to create and delete system accounts.

      +

      Deprecated since v0.9.

      +
      + + + + + + + + + + + + + + + + + +
      FieldDescription
      +name
      + + +AccountName + + +
      +

      The unique identifier of a system account.

      +
      +provisionPolicy
      + + +ProvisionPolicy + + +
      +

      Outlines the strategy for creating the account.

      +
      +

      SystemAccountSpec +

      +

      +(Appears on:ClusterComponentDefinition) +

      +
      +

      SystemAccountSpec specifies information to create system accounts.

      +

      Deprecated since v0.8, be replaced by componentDefinition.spec.systemAccounts and +componentDefinition.spec.lifecycleActions.accountProvision.

      +
      + + + + + + + + + + + + + + + + + + + + + +
      FieldDescription
      +cmdExecutorConfig
      + + +CmdExecutorConfig + + +
      +

      Configures how to obtain the client SDK and execute statements.

      +
      +passwordConfig
      + + +PasswordConfig + + +
      +

      Defines the pattern used to generate passwords for system accounts.

      +
      +accounts
      + + +[]SystemAccountConfig + + +
      +

      Defines the configuration settings for system accounts.

      +

      TLSConfig

      @@ -27488,7 +30248,7 @@ If not specified, the first container and its first port will be used.

      TargetPodSelector (string alias)

      -(Appears on:ExecAction) +(Appears on:Action)

      TargetPodSelector defines how to select pod(s) to execute an Action.

      @@ -27617,7 +30377,7 @@ string

      UpdateStrategy (string alias)

      -(Appears on:ClusterComponentSpec, ComponentDefinitionSpec) +(Appears on:ClusterComponentSpec, ComponentDefinitionSpec, StatefulSetSpec)

      UpdateStrategy defines the update strategy for cluster components. This strategy determines how updates are applied @@ -27989,7 +30749,7 @@ string

      VarOption (string alias)

      -(Appears on:ClusterVars, ComponentVars, CredentialVars, NamedVar, RoledVar, ServiceRefVars, ServiceVars) +(Appears on:ComponentVars, CredentialVars, NamedVar, ServiceRefVars, ServiceVars)

      VarOption defines whether a variable is required or optional.

      @@ -28108,20 +30868,6 @@ ComponentVarSelector

      Selects a defined var of a Component.

      - - -clusterVarRef
      - - -ClusterVarSelector - - - - -(Optional) -

      Selects a defined var of a Cluster.

      - -

      VerticalScaling @@ -28251,6 +30997,154 @@ that are used to expand the storage and the desired storage size for each one. +

      VolumeProtectionSpec +

      +

      +(Appears on:ClusterComponentDefinition) +

      +
      +

      VolumeProtectionSpec is deprecated since v0.9, replaced with ComponentVolume.HighWatermark.

      +
      + + + + + + + + + + + + + + + + + +
      FieldDescription
      +highWatermark
      + +int + +
      +(Optional) +

      The high watermark threshold for volume space usage. +If there is any specified volumes who’s space usage is over the threshold, the pre-defined “LOCK” action +will be triggered to degrade the service to protect volume from space exhaustion, such as to set the instance +as read-only. And after that, if all volumes’ space usage drops under the threshold later, the pre-defined +“UNLOCK” action will be performed to recover the service normally.

      +
      +volumes
      + + +[]ProtectedVolume + + +
      +(Optional) +

      The Volumes to be protected.

      +
      +

      VolumeType +(string alias)

      +

      +(Appears on:VolumeTypeSpec) +

      +
      +

      VolumeType defines the type of volume, specifically distinguishing between volumes used for backup data and those used for logs.

      +
      + + + + + + + + + + + + +
      ValueDescription

      "data"

      VolumeTypeData indicates a volume designated for storing backup data. This type of volume is optimized for the +storage and retrieval of data backups, ensuring data persistence and reliability.

      +

      "log"

      VolumeTypeLog indicates a volume designated for storing logs. This type of volume is optimized for log data, +facilitating efficient log storage, retrieval, and management.

      +
      +

      VolumeTypeSpec +

      +

      +(Appears on:ClusterComponentDefinition) +

      +
      +

      VolumeTypeSpec is deprecated since v0.9, replaced with ComponentVolume.

      +
      + + + + + + + + + + + + + + + + + +
      FieldDescription
      +name
      + +string + +
      +

      Corresponds to the name of the VolumeMounts field in PodSpec.Container.

      +
      +type
      + + +VolumeType + + +
      +(Optional) +

      Type of data the volume will persistent.

      +
      +

      WorkloadType +(string alias)

      +

      +(Appears on:ClusterComponentDefinition) +

      +
      +

      WorkloadType defines the type of workload for the components of the ClusterDefinition. +It can be one of the following: Stateless, Stateful, Consensus, or Replication.

      +

      Deprecated since v0.8.

      +
      + + + + + + + + + + + + + + + + +
      ValueDescription

      "Consensus"

      Consensus represents a workload type involving distributed consensus algorithms for coordinated decision-making.

      +

      "Replication"

      Replication represents a workload type that involves replication, typically used for achieving high availability +and fault tolerance.

      +

      "Stateful"

      Stateful represents a workload type where components maintain state, and each instance has a unique identity.

      +

      "Stateless"

      Stateless represents a workload type where components do not maintain state, and instances are interchangeable.

      +

      apps.kubeblocks.io/v1beta1

      @@ -33255,7 +36149,7 @@ ReplicaRole

      MemberUpdateStrategy (string alias)

      -(Appears on:InstanceSetSpec) +(Appears on:RSMSpec, InstanceSetSpec)

      MemberUpdateStrategy defines Cluster Component update strategy.

      @@ -33278,7 +36172,7 @@ ReplicaRole

      MembershipReconfiguration

      -(Appears on:InstanceSetSpec) +(Appears on:RSMSpec, InstanceSetSpec)

      @@ -33479,7 +36373,7 @@ int32

      ReplicaRole

      -(Appears on:InstanceSetSpec, MemberStatus) +(Appears on:RSMSpec, InstanceSetSpec, MemberStatus)

      @@ -33544,7 +36438,7 @@ bool

      RoleProbe

      -(Appears on:InstanceSetSpec) +(Appears on:RSMSpec, InstanceSetSpec)

      RoleProbe defines how to observe role

      diff --git a/go.mod b/go.mod index ba77671bf7b..9f3ec9f470f 100644 --- a/go.mod +++ b/go.mod @@ -24,6 +24,7 @@ require ( github.com/golang/mock v1.6.0 github.com/google/go-cmp v0.6.0 github.com/imdario/mergo v0.3.14 + github.com/jinzhu/copier v0.4.0 github.com/json-iterator/go v1.1.12 github.com/klauspost/compress v1.17.8 github.com/kubernetes-csi/external-snapshotter/client/v3 v3.0.0 diff --git a/go.sum b/go.sum index 6dae11c64c4..cd2c62d84e3 100644 --- a/go.sum +++ b/go.sum @@ -491,6 +491,8 @@ github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2 github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/jhump/protoreflect v1.15.1 h1:HUMERORf3I3ZdX05WaQ6MIpd/NJ434hTp5YiKgfCL6c= github.com/jhump/protoreflect v1.15.1/go.mod h1:jD/2GMKKE6OqX8qTjhADU1e6DShO+gavG9e0Q693nKo= +github.com/jinzhu/copier v0.4.0 h1:w3ciUoD19shMCRargcpm0cm91ytaBhDvuRpz1ODO/U8= +github.com/jinzhu/copier v0.4.0/go.mod h1:DfbEm0FYsaqBcKcFuvmOZb218JkPGtvSHsKg8S8hyyg= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= From 3356da390e8dffb9424edc71f8c71b2b693d627b Mon Sep 17 00:00:00 2001 From: Leon Date: Mon, 9 Sep 2024 13:20:31 +0800 Subject: [PATCH 11/15] udpate --- apis/apps/v1alpha1/cluster_conversion.go | 8 +--- .../v1alpha1/clusterdefinition_conversion.go | 8 +--- apis/apps/v1alpha1/component_conversion.go | 48 +------------------ .../componentdefinition_conversion.go | 6 ++- 4 files changed, 10 insertions(+), 60 deletions(-) diff --git a/apis/apps/v1alpha1/cluster_conversion.go b/apis/apps/v1alpha1/cluster_conversion.go index 8849725995a..05a6d0bdda6 100644 --- a/apis/apps/v1alpha1/cluster_conversion.go +++ b/apis/apps/v1alpha1/cluster_conversion.go @@ -35,9 +35,7 @@ func (r *Cluster) ConvertTo(dstRaw conversion.Hub) error { // spec copier.Copy(&dst.Spec, &r.Spec) - // TODO(v1.0): - // 1. add original Cluster definition back - // 2. changed fields + // TODO(v1.0): changed fields // status copier.Copy(&dst.Status, &r.Status) @@ -54,9 +52,7 @@ func (r *Cluster) ConvertFrom(srcRaw conversion.Hub) error { // spec copier.Copy(&r.Spec, &src.Spec) - // TODO(v1.0): - // 1. add original Cluster definition back - // 2. changed fields + // TODO(v1.0): changed fields // status copier.Copy(&r.Status, &src.Status) diff --git a/apis/apps/v1alpha1/clusterdefinition_conversion.go b/apis/apps/v1alpha1/clusterdefinition_conversion.go index d87ea9ba4b4..e1068be381e 100644 --- a/apis/apps/v1alpha1/clusterdefinition_conversion.go +++ b/apis/apps/v1alpha1/clusterdefinition_conversion.go @@ -35,9 +35,7 @@ func (r *ClusterDefinition) ConvertTo(dstRaw conversion.Hub) error { // spec copier.Copy(&dst.Spec, &r.Spec) - // TODO(v1.0): - // 1. add original ClusterDefinition definition back - // 2. changed fields + // TODO(v1.0): changed fields // status copier.Copy(&dst.Status, &r.Status) @@ -54,9 +52,7 @@ func (r *ClusterDefinition) ConvertFrom(srcRaw conversion.Hub) error { // spec copier.Copy(&r.Spec, &src.Spec) - // TODO(v1.0): - // 1. add original ClusterDefinition definition back - // 2. changed fields + // TODO(v1.0): changed fields // status copier.Copy(&r.Status, &src.Status) diff --git a/apis/apps/v1alpha1/component_conversion.go b/apis/apps/v1alpha1/component_conversion.go index 703f9875ee7..9c265b511d5 100644 --- a/apis/apps/v1alpha1/component_conversion.go +++ b/apis/apps/v1alpha1/component_conversion.go @@ -20,11 +20,7 @@ along with this program. If not, see . package v1alpha1 import ( - "encoding/json" - "k8s.io/apimachinery/pkg/runtime" - "github.com/jinzhu/copier" - corev1 "k8s.io/api/core/v1" "sigs.k8s.io/controller-runtime/pkg/conversion" appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" @@ -39,12 +35,7 @@ func (r *Component) ConvertTo(dstRaw conversion.Hub) error { // spec copier.Copy(&dst.Spec, &r.Spec) - convertor := &incrementConvertor{ - deleted: &componentDeleted{}, - } - if err := convertor.convertTo(r, dst); err != nil { - return err - } + // TODO(v1.0): changed fields // status copier.Copy(&dst.Status, &r.Status) @@ -61,45 +52,10 @@ func (r *Component) ConvertFrom(srcRaw conversion.Hub) error { // spec copier.Copy(&r.Spec, &src.Spec) - convertor := &incrementConvertor{ - deleted: &componentDeleted{}, - } - if err := convertor.convertFrom(src, r); err != nil { - return err - } + // TODO(v1.0): changed fields // status copier.Copy(&r.Status, &src.Status) return nil } - -type componentDeleted struct { - affinity *Affinity `json:"affinity,omitempty"` - tolerations []corev1.Toleration `json:"tolerations,omitempty"` -} - -func (r *componentDeleted) To(obj runtime.Object) ([]byte, error) { - comp := obj.(*Component) - diff := &componentDeleted{ - affinity: comp.Spec.Affinity, - tolerations: comp.Spec.Tolerations, - } - out, err := json.Marshal(diff) - if err != nil { - return nil, err - } - return out, nil -} - -func (r *componentDeleted) From(data []byte, obj runtime.Object) error { - diff := &componentDeleted{} - err := json.Unmarshal(data, diff) - if err != nil { - return err - } - comp := obj.(*Component) - comp.Spec.Affinity = diff.affinity - comp.Spec.Tolerations = diff.tolerations - return nil -} diff --git a/apis/apps/v1alpha1/componentdefinition_conversion.go b/apis/apps/v1alpha1/componentdefinition_conversion.go index 4e6417adc59..e9ff5275368 100644 --- a/apis/apps/v1alpha1/componentdefinition_conversion.go +++ b/apis/apps/v1alpha1/componentdefinition_conversion.go @@ -33,7 +33,8 @@ func (r *ComponentDefinition) ConvertTo(dstRaw conversion.Hub) error { dst.ObjectMeta = r.ObjectMeta // spec - copier.Copy(&dst.Spec, &r.Spec) // TODO(v1.0): changed fields + copier.Copy(&dst.Spec, &r.Spec) + // TODO(v1.0): changed fields // status copier.Copy(&dst.Status, &r.Status) @@ -49,7 +50,8 @@ func (r *ComponentDefinition) ConvertFrom(srcRaw conversion.Hub) error { r.ObjectMeta = src.ObjectMeta // spec - copier.Copy(&r.Spec, &src.Spec) // TODO(v1.0): changed fields + copier.Copy(&r.Spec, &src.Spec) + // TODO(v1.0): changed fields // status copier.Copy(&r.Status, &src.Status) From 4f40b467d1c6f7e4a230d131565209a5622e41bc Mon Sep 17 00:00:00 2001 From: Leon Date: Mon, 9 Sep 2024 17:48:49 +0800 Subject: [PATCH 12/15] udpate --- apis/apps/v1alpha1/cluster_conversion.go | 198 ++++++++++++- apis/apps/v1alpha1/cluster_types.go | 8 +- .../v1alpha1/clusterdefinition_conversion.go | 62 +++- apis/apps/v1alpha1/component_conversion.go | 59 +++- apis/apps/v1alpha1/component_types.go | 7 + .../componentdefinition_conversion.go | 274 +++++++++++++++++- .../v1alpha1/componentdefinition_types.go | 2 +- .../v1alpha1/componentversion_conversion.go | 16 +- apis/apps/v1alpha1/conversion.go | 90 ++++++ .../v1alpha1/servicedescriptor_conversion.go | 16 +- apis/apps/v1alpha1/type.go | 20 ++ apis/apps/v1alpha1/zz_generated.deepcopy.go | 37 ++- .../v1alpha1/instanceset_conversion.go | 16 +- .../bases/apps.kubeblocks.io_clusters.yaml | 54 ++++ .../bases/apps.kubeblocks.io_components.yaml | 27 ++ controllers/dataprotection/utils.go | 8 +- .../crds/apps.kubeblocks.io_clusters.yaml | 54 ++++ .../crds/apps.kubeblocks.io_components.yaml | 27 ++ docs/developer_docs/api-reference/cluster.md | 101 +++++++ 19 files changed, 1031 insertions(+), 45 deletions(-) create mode 100644 apis/apps/v1alpha1/conversion.go diff --git a/apis/apps/v1alpha1/cluster_conversion.go b/apis/apps/v1alpha1/cluster_conversion.go index 05a6d0bdda6..1d60d9128ce 100644 --- a/apis/apps/v1alpha1/cluster_conversion.go +++ b/apis/apps/v1alpha1/cluster_conversion.go @@ -21,9 +21,12 @@ package v1alpha1 import ( "github.com/jinzhu/copier" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/conversion" appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" + workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" ) // ConvertTo converts this Cluster to the Hub version (v1). @@ -34,11 +37,17 @@ func (r *Cluster) ConvertTo(dstRaw conversion.Hub) error { dst.ObjectMeta = r.ObjectMeta // spec - copier.Copy(&dst.Spec, &r.Spec) - // TODO(v1.0): changed fields + if err := copier.Copy(&dst.Spec, &r.Spec); err != nil { + return err + } + if err := incrementConvertTo(r, dst); err != nil { + return err + } // status - copier.Copy(&dst.Status, &r.Status) + if err := copier.Copy(&dst.Status, &r.Status); err != nil { + return err + } return nil } @@ -51,11 +60,188 @@ func (r *Cluster) ConvertFrom(srcRaw conversion.Hub) error { r.ObjectMeta = src.ObjectMeta // spec - copier.Copy(&r.Spec, &src.Spec) - // TODO(v1.0): changed fields + if err := copier.Copy(&r.Spec, &src.Spec); err != nil { + return err + } + if err := incrementConvertFrom(r, src, &clusterConverter{}); err != nil { + return err + } // status - copier.Copy(&r.Status, &src.Status) + if err := copier.Copy(&r.Status, &src.Status); err != nil { + return err + } return nil } + +func (r *Cluster) incrementConvertTo(dstRaw metav1.Object) (incrementChange, error) { + // changed + r.changesToCluster(dstRaw.(*appsv1.Cluster)) + + // deleted + c := &clusterConverter{} + c.fromCluster(r) + return c, nil +} + +func (r *Cluster) incrementConvertFrom(srcRaw metav1.Object, ic incrementChange) error { + // deleted + c := ic.(*clusterConverter) + c.toCluster(r) + + // changed + r.changesFromCluster(srcRaw.(*appsv1.Cluster)) + + return nil +} + +func (r *Cluster) changesToCluster(cluster *appsv1.Cluster) { + // changed: + // spec + // components + // - volumeClaimTemplates + // spec: + // resources: corev1.ResourceRequirements -> corev1.VolumeResourceRequirements + // podUpdatePolicy: *workloads.PodUpdatePolicyType -> *PodUpdatePolicyType + // sharings + // - template + // volumeClaimTemplates + // spec: + // resources: corev1.ResourceRequirements -> corev1.VolumeResourceRequirements + // podUpdatePolicy: *workloads.PodUpdatePolicyType -> *PodUpdatePolicyType + // status + // components + // - message: ComponentMessageMap -> map[string]string +} + +func (r *Cluster) changesFromCluster(cluster *appsv1.Cluster) { + // changed: + // spec + // components + // - volumeClaimTemplates + // spec: + // resources: corev1.ResourceRequirements -> corev1.VolumeResourceRequirements + // podUpdatePolicy: *workloads.PodUpdatePolicyType -> *PodUpdatePolicyType + // sharings + // - template + // volumeClaimTemplates + // spec: + // resources: corev1.ResourceRequirements -> corev1.VolumeResourceRequirements + // podUpdatePolicy: *workloads.PodUpdatePolicyType -> *PodUpdatePolicyType + // status + // components + // - message: ComponentMessageMap -> map[string]string +} + +type clusterConverter struct { + Spec clusterSpecConverter `json:"spec,omitempty"` + Status clusterStatusConverter `json:"status,omitempty"` +} + +type clusterSpecConverter struct { + Affinity *Affinity `json:"affinity,omitempty"` + Tolerations []corev1.Toleration `json:"tolerations,omitempty"` + Tenancy TenancyType `json:"tenancy,omitempty"` + AvailabilityPolicy AvailabilityPolicyType `json:"availabilityPolicy,omitempty"` + Replicas *int32 `json:"replicas,omitempty"` + Resources ClusterResources `json:"resources,omitempty"` + Storage ClusterStorage `json:"storage,omitempty"` + Network *ClusterNetwork `json:"network,omitempty"` + Components map[string]clusterCompConverter `json:"Components,omitempty"` + Shardings map[string]clusterCompConverter `json:"shardings,omitempty"` +} + +type clusterCompConverter struct { + ClassDefRef *ClassDefRef `json:"classDefRef,omitempty"` + Affinity *Affinity `json:"affinity,omitempty"` + Tolerations []corev1.Toleration `json:"tolerations,omitempty"` + SwitchPolicy *ClusterSwitchPolicy `json:"switchPolicy,omitempty"` + InstanceUpdateStrategy *InstanceUpdateStrategy `json:"instanceUpdateStrategy,omitempty"` +} + +type clusterStatusConverter struct { + Components map[string]clusterCompStatusConverter `json:"components,omitempty"` +} + +type clusterCompStatusConverter struct { + PodsReady *bool `json:"podsReady,omitempty"` + PodsReadyTime *metav1.Time `json:"podsReadyTime,omitempty"` + MembersStatus []workloads.MemberStatus `json:"membersStatus,omitempty"` +} + +func (c *clusterConverter) fromCluster(cluster *Cluster) { + c.Spec.Affinity = cluster.Spec.Affinity + c.Spec.Tolerations = cluster.Spec.Tolerations + c.Spec.Tenancy = cluster.Spec.Tenancy + c.Spec.AvailabilityPolicy = cluster.Spec.AvailabilityPolicy + c.Spec.Replicas = cluster.Spec.Replicas + c.Spec.Resources = cluster.Spec.Resources + c.Spec.Storage = cluster.Spec.Storage + c.Spec.Network = cluster.Spec.Network + + deletedComp := func(spec ClusterComponentSpec) clusterCompConverter { + return clusterCompConverter{ + ClassDefRef: spec.ClassDefRef, + Affinity: spec.Affinity, + Tolerations: spec.Tolerations, + SwitchPolicy: spec.SwitchPolicy, + InstanceUpdateStrategy: spec.InstanceUpdateStrategy, + } + } + for _, comp := range cluster.Spec.ComponentSpecs { + c.Spec.Components[comp.Name] = deletedComp(comp) + } + for _, sharding := range cluster.Spec.ShardingSpecs { + c.Spec.Shardings[sharding.Name] = deletedComp(sharding.Template) + } + + for name, status := range cluster.Status.Components { + c.Status.Components[name] = clusterCompStatusConverter{ + PodsReady: status.PodsReady, + PodsReadyTime: status.PodsReadyTime, + MembersStatus: status.MembersStatus, + } + } +} + +func (c *clusterConverter) toCluster(cluster *Cluster) { + cluster.Spec.Affinity = c.Spec.Affinity + cluster.Spec.Tolerations = c.Spec.Tolerations + cluster.Spec.Tenancy = c.Spec.Tenancy + cluster.Spec.AvailabilityPolicy = c.Spec.AvailabilityPolicy + cluster.Spec.Replicas = c.Spec.Replicas + cluster.Spec.Resources = c.Spec.Resources + cluster.Spec.Storage = c.Spec.Storage + cluster.Spec.Network = c.Spec.Network + + deletedComp := func(comp clusterCompConverter, spec *ClusterComponentSpec) { + spec.ClassDefRef = comp.ClassDefRef + spec.Affinity = comp.Affinity + spec.Tolerations = comp.Tolerations + spec.SwitchPolicy = comp.SwitchPolicy + spec.InstanceUpdateStrategy = comp.InstanceUpdateStrategy + } + for i, spec := range cluster.Spec.ComponentSpecs { + comp, ok := c.Spec.Components[spec.Name] + if ok { + deletedComp(comp, &cluster.Spec.ComponentSpecs[i]) + } + } + for i, spec := range cluster.Spec.ShardingSpecs { + template, ok := c.Spec.Shardings[spec.Name] + if ok { + deletedComp(template, &cluster.Spec.ShardingSpecs[i].Template) + } + } + + for name, comp := range cluster.Status.Components { + status, ok := c.Status.Components[name] + if ok { + comp.PodsReady = status.PodsReady + comp.PodsReadyTime = status.PodsReadyTime + comp.MembersStatus = status.MembersStatus + cluster.Status.Components[name] = comp + } + } +} diff --git a/apis/apps/v1alpha1/cluster_types.go b/apis/apps/v1alpha1/cluster_types.go index fc83f5f487c..bfb10ece790 100644 --- a/apis/apps/v1alpha1/cluster_types.go +++ b/apis/apps/v1alpha1/cluster_types.go @@ -810,8 +810,12 @@ type ClusterComponentSpec struct { // +optional UpdateStrategy *UpdateStrategy `json:"updateStrategy,omitempty"` - // TODO(v1.0): ? - // InstanceUpdateStrategy *InstanceUpdateStrategy + // Indicates the InstanceUpdateStrategy that will be + // employed to update Pods in the InstanceSet when a revision is made to + // Template. + // + // +optional + InstanceUpdateStrategy *InstanceUpdateStrategy `json:"instanceUpdateStrategy,omitempty"` // Controls the concurrency of pods during initial scale up, when replacing pods on nodes, // or when scaling down. It only used when `PodManagementPolicy` is set to `Parallel`. diff --git a/apis/apps/v1alpha1/clusterdefinition_conversion.go b/apis/apps/v1alpha1/clusterdefinition_conversion.go index e1068be381e..7fb9b747c82 100644 --- a/apis/apps/v1alpha1/clusterdefinition_conversion.go +++ b/apis/apps/v1alpha1/clusterdefinition_conversion.go @@ -21,6 +21,7 @@ package v1alpha1 import ( "github.com/jinzhu/copier" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/conversion" appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" @@ -34,11 +35,17 @@ func (r *ClusterDefinition) ConvertTo(dstRaw conversion.Hub) error { dst.ObjectMeta = r.ObjectMeta // spec - copier.Copy(&dst.Spec, &r.Spec) - // TODO(v1.0): changed fields + if err := copier.Copy(&dst.Spec, &r.Spec); err != nil { + return err + } + if err := incrementConvertTo(r, dst); err != nil { + return err + } // status - copier.Copy(&dst.Status, &r.Status) + if err := copier.Copy(&dst.Status, &r.Status); err != nil { + return err + } return nil } @@ -51,11 +58,54 @@ func (r *ClusterDefinition) ConvertFrom(srcRaw conversion.Hub) error { r.ObjectMeta = src.ObjectMeta // spec - copier.Copy(&r.Spec, &src.Spec) - // TODO(v1.0): changed fields + if err := copier.Copy(&r.Spec, &src.Spec); err != nil { + return err + } + if err := incrementConvertFrom(r, src, &clusterDefinitionConverter{}); err != nil { + return err + } // status - copier.Copy(&r.Status, &src.Status) + if err := copier.Copy(&r.Status, &src.Status); err != nil { + return err + } return nil } + +func (r *ClusterDefinition) incrementConvertTo(metav1.Object) (incrementChange, error) { + return &clusterDefinitionConverter{ + Spec: clusterDefinitionSpecConverter{ + Type: r.Spec.Type, + ComponentDefs: r.Spec.ComponentDefs, + ConnectionCredential: r.Spec.ConnectionCredential, + }, + Status: clusterDefinitionStatusConverter{ + ServiceRefs: r.Status.ServiceRefs, + }, + }, nil +} + +func (r *ClusterDefinition) incrementConvertFrom(_ metav1.Object, ic incrementChange) error { + c := ic.(*clusterDefinitionConverter) + r.Spec.Type = c.Spec.Type + r.Spec.ComponentDefs = c.Spec.ComponentDefs + r.Spec.ConnectionCredential = c.Spec.ConnectionCredential + r.Status.ServiceRefs = c.Status.ServiceRefs + return nil +} + +type clusterDefinitionConverter struct { + Spec clusterDefinitionSpecConverter `json:"spec,omitempty"` + Status clusterDefinitionStatusConverter `json:"status,omitempty"` +} + +type clusterDefinitionSpecConverter struct { + Type string `json:"type,omitempty"` + ComponentDefs []ClusterComponentDefinition `json:"componentDefs"` + ConnectionCredential map[string]string `json:"connectionCredential,omitempty"` +} + +type clusterDefinitionStatusConverter struct { + ServiceRefs string `json:"serviceRefs,omitempty"` +} diff --git a/apis/apps/v1alpha1/component_conversion.go b/apis/apps/v1alpha1/component_conversion.go index 9c265b511d5..e397d59491a 100644 --- a/apis/apps/v1alpha1/component_conversion.go +++ b/apis/apps/v1alpha1/component_conversion.go @@ -21,6 +21,8 @@ package v1alpha1 import ( "github.com/jinzhu/copier" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/conversion" appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" @@ -34,11 +36,17 @@ func (r *Component) ConvertTo(dstRaw conversion.Hub) error { dst.ObjectMeta = r.ObjectMeta // spec - copier.Copy(&dst.Spec, &r.Spec) - // TODO(v1.0): changed fields + if err := copier.Copy(&dst.Spec, &r.Spec); err != nil { + return err + } + if err := incrementConvertTo(r, dst); err != nil { + return err + } // status - copier.Copy(&dst.Status, &r.Status) + if err := copier.Copy(&dst.Status, &r.Status); err != nil { + return err + } return nil } @@ -51,11 +59,50 @@ func (r *Component) ConvertFrom(srcRaw conversion.Hub) error { r.ObjectMeta = src.ObjectMeta // spec - copier.Copy(&r.Spec, &src.Spec) - // TODO(v1.0): changed fields + if err := copier.Copy(&r.Spec, &src.Spec); err != nil { + return err + } + if err := incrementConvertFrom(r, src, &componentConverter{}); err != nil { + return err + } // status - copier.Copy(&r.Status, &src.Status) + if err := copier.Copy(&r.Status, &src.Status); err != nil { + return err + } return nil } + +func (r *Component) incrementConvertTo(dstRaw metav1.Object) (incrementChange, error) { + // changed + comp := dstRaw.(*appsv1.Component) + comp.Status.Message = r.Status.Message + + // deleted + return &componentConverter{ + Affinity: r.Spec.Affinity, + Tolerations: r.Spec.Tolerations, + InstanceUpdateStrategy: r.Spec.InstanceUpdateStrategy, + }, nil +} + +func (r *Component) incrementConvertFrom(srcRaw metav1.Object, ic incrementChange) error { + // deleted + c := ic.(*componentConverter) + r.Spec.Affinity = c.Affinity + r.Spec.Tolerations = c.Tolerations + r.Spec.InstanceUpdateStrategy = c.InstanceUpdateStrategy + + // changed + comp := srcRaw.(*appsv1.Component) + r.Status.Message = comp.Status.Message + + return nil +} + +type componentConverter struct { + Affinity *Affinity `json:"affinity,omitempty"` + Tolerations []corev1.Toleration `json:"tolerations,omitempty"` + InstanceUpdateStrategy *InstanceUpdateStrategy `json:"instanceUpdateStrategy,omitempty"` +} diff --git a/apis/apps/v1alpha1/component_types.go b/apis/apps/v1alpha1/component_types.go index 8c1fc0dd995..c63b063868f 100644 --- a/apis/apps/v1alpha1/component_types.go +++ b/apis/apps/v1alpha1/component_types.go @@ -163,6 +163,13 @@ type ComponentSpec struct { // +optional ServiceAccountName string `json:"serviceAccountName,omitempty"` + // Indicates the InstanceUpdateStrategy that will be + // employed to update Pods in the InstanceSet when a revision is made to + // Template. + // + // +optional + InstanceUpdateStrategy *InstanceUpdateStrategy `json:"instanceUpdateStrategy,omitempty"` + // Controls the concurrency of pods during initial scale up, when replacing pods on nodes, // or when scaling down. It only used when `PodManagementPolicy` is set to `Parallel`. // The default Concurrency is 100%. diff --git a/apis/apps/v1alpha1/componentdefinition_conversion.go b/apis/apps/v1alpha1/componentdefinition_conversion.go index e9ff5275368..85db2069511 100644 --- a/apis/apps/v1alpha1/componentdefinition_conversion.go +++ b/apis/apps/v1alpha1/componentdefinition_conversion.go @@ -20,9 +20,11 @@ along with this program. If not, see . package v1alpha1 import ( - appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" "github.com/jinzhu/copier" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/conversion" + + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" ) // ConvertTo converts this ComponentDefinition to the Hub version (v1). @@ -33,11 +35,17 @@ func (r *ComponentDefinition) ConvertTo(dstRaw conversion.Hub) error { dst.ObjectMeta = r.ObjectMeta // spec - copier.Copy(&dst.Spec, &r.Spec) - // TODO(v1.0): changed fields + if err := copier.Copy(&dst.Spec, &r.Spec); err != nil { + return err + } + if err := incrementConvertTo(r, dst); err != nil { + return err + } // status - copier.Copy(&dst.Status, &r.Status) + if err := copier.Copy(&dst.Status, &r.Status); err != nil { + return err + } return nil } @@ -50,11 +58,263 @@ func (r *ComponentDefinition) ConvertFrom(srcRaw conversion.Hub) error { r.ObjectMeta = src.ObjectMeta // spec - copier.Copy(&r.Spec, &src.Spec) - // TODO(v1.0): changed fields + if err := copier.Copy(&r.Spec, &src.Spec); err != nil { + return err + } + if err := incrementConvertFrom(r, src, &componentDefinitionConverter{}); err != nil { + return err + } // status - copier.Copy(&r.Status, &src.Status) + if err := copier.Copy(&r.Status, &src.Status); err != nil { + return err + } + + return nil +} + +// convertTo converts this ComponentDefinition to the Hub version (v1). +func (r *ComponentDefinition) incrementConvertTo(dstRaw metav1.Object) (incrementChange, error) { + // changed + r.changesToComponentDefinition(dstRaw.(*appsv1.ComponentDefinition)) + + // deleted + c := &componentDefinitionConverter{ + Monitor: r.Spec.Monitor, + RoleArbitrator: r.Spec.RoleArbitrator, + LifecycleActionSwitchover: r.Spec.LifecycleActions.Switchover, + } + if r.Spec.LifecycleActions != nil && r.Spec.LifecycleActions.Switchover != nil { + c.LifecycleActionSwitchover = r.Spec.LifecycleActions.Switchover + } + return c, nil +} + +// convertFrom converts from the Hub version (v1) to this version. +func (r *ComponentDefinition) incrementConvertFrom(srcRaw metav1.Object, ic incrementChange) error { + // deleted + c := ic.(*componentDefinitionConverter) + r.Spec.Monitor = c.Monitor + r.Spec.RoleArbitrator = c.RoleArbitrator + if c.LifecycleActionSwitchover != nil { + if r.Spec.LifecycleActions == nil { + r.Spec.LifecycleActions = &ComponentLifecycleActions{} + } + r.Spec.LifecycleActions.Switchover = c.LifecycleActionSwitchover + } + + // changed + r.changesFromComponentDefinition(srcRaw.(*appsv1.ComponentDefinition)) return nil } + +func (r *ComponentDefinition) changesToComponentDefinition(cmpd *appsv1.ComponentDefinition) { + // changed: + // spec + // vars + // - ValueFrom + // componentVarRef: + // instanceNames -> podNames + // lifecycleActions + + for _, v := range r.Spec.Vars { + if v.ValueFrom == nil || v.ValueFrom.ComponentVarRef == nil || v.ValueFrom.ComponentVarRef.InstanceNames == nil { + continue + } + r.toV1VarsPodNames(v, cmpd) + } + r.toV1LifecycleActions(cmpd) +} + +func (r *ComponentDefinition) changesFromComponentDefinition(cmpd *appsv1.ComponentDefinition) { + // changed: + // spec + // vars + // - ValueFrom + // componentVarRef: + // instanceNames -> podNames + // lifecycleActions + + for _, v := range cmpd.Spec.Vars { + if v.ValueFrom == nil || v.ValueFrom.ComponentVarRef == nil || v.ValueFrom.ComponentVarRef.PodNames == nil { + continue + } + r.fromV1VarsPodNames(v) + } + r.fromV1LifecycleActions(cmpd) +} + +func (r *ComponentDefinition) toV1VarsPodNames(v EnvVar, cmpd *appsv1.ComponentDefinition) { + for i, vv := range cmpd.Spec.Vars { + if vv.Name == v.Name { + opt := appsv1.VarOption(*v.ValueFrom.ComponentVarRef.InstanceNames) + cmpd.Spec.Vars[i].ValueFrom.ComponentVarRef.PodNames = &opt + } + } +} + +func (r *ComponentDefinition) fromV1VarsPodNames(v appsv1.EnvVar) { + for i, vv := range r.Spec.Vars { + if vv.Name == v.Name { + opt := VarOption(*v.ValueFrom.ComponentVarRef.PodNames) + r.Spec.Vars[i].ValueFrom.ComponentVarRef.InstanceNames = &opt + } + } +} + +func (r *ComponentDefinition) toV1LifecycleActions(cmpd *appsv1.ComponentDefinition) { + if r.Spec.LifecycleActions == nil { + return + } + cmpd.Spec.LifecycleActions.PostProvision = r.toV1LifecycleActionHandler(r.Spec.LifecycleActions.PostProvision) + cmpd.Spec.LifecycleActions.PreTerminate = r.toV1LifecycleActionHandler(r.Spec.LifecycleActions.PreTerminate) + cmpd.Spec.LifecycleActions.MemberJoin = r.toV1LifecycleActionHandler(r.Spec.LifecycleActions.MemberJoin) + cmpd.Spec.LifecycleActions.MemberLeave = r.toV1LifecycleActionHandler(r.Spec.LifecycleActions.MemberLeave) + cmpd.Spec.LifecycleActions.Readonly = r.toV1LifecycleActionHandler(r.Spec.LifecycleActions.Readonly) + cmpd.Spec.LifecycleActions.Readwrite = r.toV1LifecycleActionHandler(r.Spec.LifecycleActions.Readwrite) + cmpd.Spec.LifecycleActions.DataDump = r.toV1LifecycleActionHandler(r.Spec.LifecycleActions.DataDump) + cmpd.Spec.LifecycleActions.DataLoad = r.toV1LifecycleActionHandler(r.Spec.LifecycleActions.DataLoad) + cmpd.Spec.LifecycleActions.Reconfigure = r.toV1LifecycleActionHandler(r.Spec.LifecycleActions.Reconfigure) + cmpd.Spec.LifecycleActions.AccountProvision = r.toV1LifecycleActionHandler(r.Spec.LifecycleActions.AccountProvision) + + cmpd.Spec.LifecycleActions.RoleProbe = r.toV1LifecycleRoleProbe(r.Spec.LifecycleActions.RoleProbe) + + // don't convert switchover +} + +func (r *ComponentDefinition) fromV1LifecycleActions(cmpd *appsv1.ComponentDefinition) { + if cmpd.Spec.LifecycleActions == nil { + return + } + r.Spec.LifecycleActions.PostProvision = r.fromV1LifecycleActionHandler(cmpd.Spec.LifecycleActions.PostProvision) + r.Spec.LifecycleActions.PreTerminate = r.fromV1LifecycleActionHandler(cmpd.Spec.LifecycleActions.PreTerminate) + r.Spec.LifecycleActions.MemberJoin = r.fromV1LifecycleActionHandler(cmpd.Spec.LifecycleActions.MemberJoin) + r.Spec.LifecycleActions.MemberLeave = r.fromV1LifecycleActionHandler(cmpd.Spec.LifecycleActions.MemberLeave) + r.Spec.LifecycleActions.Readonly = r.fromV1LifecycleActionHandler(cmpd.Spec.LifecycleActions.Readonly) + r.Spec.LifecycleActions.Readwrite = r.fromV1LifecycleActionHandler(cmpd.Spec.LifecycleActions.Readwrite) + r.Spec.LifecycleActions.DataDump = r.fromV1LifecycleActionHandler(cmpd.Spec.LifecycleActions.DataDump) + r.Spec.LifecycleActions.DataLoad = r.fromV1LifecycleActionHandler(cmpd.Spec.LifecycleActions.DataLoad) + r.Spec.LifecycleActions.Reconfigure = r.fromV1LifecycleActionHandler(cmpd.Spec.LifecycleActions.Reconfigure) + r.Spec.LifecycleActions.AccountProvision = r.fromV1LifecycleActionHandler(cmpd.Spec.LifecycleActions.AccountProvision) + + r.Spec.LifecycleActions.RoleProbe = r.fromV1LifecycleRoleProbe(cmpd.Spec.LifecycleActions.RoleProbe) + + // don't convert switchover +} + +func (r *ComponentDefinition) toV1LifecycleActionHandler(handler *LifecycleActionHandler) *appsv1.Action { + if handler == nil || handler.CustomHandler == nil || handler.CustomHandler.Exec == nil { + return nil + } + return r.toV1LifecycleAction(handler.CustomHandler) +} + +func (r *ComponentDefinition) fromV1LifecycleActionHandler(action *appsv1.Action) *LifecycleActionHandler { + if action == nil || action.Exec == nil { + return nil + } + return &LifecycleActionHandler{ + CustomHandler: r.fromV1LifecycleAction(action), + } +} + +func (r *ComponentDefinition) toV1LifecycleRoleProbe(probe *RoleProbe) *appsv1.Probe { + if probe == nil || probe.CustomHandler == nil || probe.CustomHandler.Exec == nil { + return nil + } + a := r.toV1LifecycleAction(probe.CustomHandler) + if a == nil { + return nil + } + if probe.TimeoutSeconds > 0 { + a.TimeoutSeconds = probe.TimeoutSeconds + } + return &appsv1.Probe{ + Action: *a, + InitialDelaySeconds: probe.InitialDelaySeconds, + PeriodSeconds: probe.PeriodSeconds, + } +} + +func (r *ComponentDefinition) fromV1LifecycleRoleProbe(probe *appsv1.Probe) *RoleProbe { + if probe == nil || probe.Exec == nil { + return nil + } + a := r.fromV1LifecycleAction(&probe.Action) + if a == nil { + return nil + } + return &RoleProbe{ + LifecycleActionHandler: LifecycleActionHandler{ + CustomHandler: a, + }, + TimeoutSeconds: a.TimeoutSeconds, + InitialDelaySeconds: probe.InitialDelaySeconds, + PeriodSeconds: probe.PeriodSeconds, + } +} + +func (r *ComponentDefinition) toV1LifecycleAction(action *Action) *appsv1.Action { + if action == nil || action.Exec == nil { + return nil + } + a := &appsv1.Action{ + Exec: &appsv1.ExecAction{ + Image: action.Image, + Env: action.Env, + Command: action.Exec.Command, + Args: action.Exec.Args, + TargetPodSelector: appsv1.TargetPodSelector(action.TargetPodSelector), + MatchingKey: action.MatchingKey, + Container: action.Container, + }, + TimeoutSeconds: action.TimeoutSeconds, + } + if action.RetryPolicy != nil { + a.RetryPolicy = &appsv1.RetryPolicy{ + MaxRetries: action.RetryPolicy.MaxRetries, + RetryInterval: action.RetryPolicy.RetryInterval, + } + } + if action.PreCondition != nil { + cond := appsv1.PreConditionType(*action.PreCondition) + a.PreCondition = &cond + } + return a +} + +func (r *ComponentDefinition) fromV1LifecycleAction(action *appsv1.Action) *Action { + if action == nil || action.Exec == nil { + return nil + } + a := &Action{ + Image: action.Exec.Image, + Exec: &ExecAction{ + Command: action.Exec.Command, + Args: action.Exec.Args, + }, + Env: action.Exec.Env, + TargetPodSelector: TargetPodSelector(action.Exec.TargetPodSelector), + MatchingKey: action.Exec.MatchingKey, + Container: action.Exec.Container, + TimeoutSeconds: action.TimeoutSeconds, + } + if action.RetryPolicy != nil { + a.RetryPolicy = &RetryPolicy{ + MaxRetries: action.RetryPolicy.MaxRetries, + RetryInterval: action.RetryPolicy.RetryInterval, + } + } + if action.PreCondition != nil { + cond := PreConditionType(*action.PreCondition) + a.PreCondition = &cond + } + return a +} + +type componentDefinitionConverter struct { + Monitor *MonitorConfig `json:"monitor,omitempty"` + RoleArbitrator *RoleArbitrator `json:"roleArbitrator,omitempty"` + LifecycleActionSwitchover *ComponentSwitchover `json:"lifecycleActionSwitchover,omitempty"` +} diff --git a/apis/apps/v1alpha1/componentdefinition_types.go b/apis/apps/v1alpha1/componentdefinition_types.go index 56dc16e8d9d..5b78e8354fb 100644 --- a/apis/apps/v1alpha1/componentdefinition_types.go +++ b/apis/apps/v1alpha1/componentdefinition_types.go @@ -17,13 +17,13 @@ limitations under the License. package v1alpha1 import ( - "k8s.io/apimachinery/pkg/util/intstr" "time" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" rbacv1 "k8s.io/api/rbac/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/intstr" ) // +genclient diff --git a/apis/apps/v1alpha1/componentversion_conversion.go b/apis/apps/v1alpha1/componentversion_conversion.go index 031042bde38..a88f2460e7b 100644 --- a/apis/apps/v1alpha1/componentversion_conversion.go +++ b/apis/apps/v1alpha1/componentversion_conversion.go @@ -34,10 +34,14 @@ func (r *ComponentVersion) ConvertTo(dstRaw conversion.Hub) error { dst.ObjectMeta = r.ObjectMeta // spec - copier.Copy(&dst.Spec, &r.Spec) + if err := copier.Copy(&dst.Spec, &r.Spec); err != nil { + return err + } // status - copier.Copy(&dst.Status, &r.Status) + if err := copier.Copy(&dst.Status, &r.Status); err != nil { + return err + } return nil } @@ -50,10 +54,14 @@ func (r *ComponentVersion) ConvertFrom(srcRaw conversion.Hub) error { r.ObjectMeta = src.ObjectMeta // spec - copier.Copy(&r.Spec, &src.Spec) + if err := copier.Copy(&r.Spec, &src.Spec); err != nil { + return err + } // status - copier.Copy(&r.Status, &src.Status) + if err := copier.Copy(&r.Status, &src.Status); err != nil { + return err + } return nil } diff --git a/apis/apps/v1alpha1/conversion.go b/apis/apps/v1alpha1/conversion.go new file mode 100644 index 00000000000..60ac9b1d732 --- /dev/null +++ b/apis/apps/v1alpha1/conversion.go @@ -0,0 +1,90 @@ +/* +Copyright (C) 2022-2024 ApeCloud Co., Ltd + +This file is part of KubeBlocks project + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ + +package v1alpha1 + +import ( + "encoding/json" + "maps" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +const ( + kbIncrementConverterAK = "kb-increment-converter" +) + +type incrementChange any + +type incrementConverter interface { + // incrementConvertTo converts the object to the target version, + // returning any incremental changes that need to be persisted out of the target object. + incrementConvertTo(dstRaw metav1.Object) (incrementChange, error) + + // incrementConvertFrom converts the object from the source version, + // and applies any incremental changes that were persisted out of the source object. + incrementConvertFrom(srcRaw metav1.Object, ic incrementChange) error +} + +func incrementConvertTo(converter incrementConverter, target metav1.Object) error { + if converter == nil { + return nil + } + + changes, err := converter.incrementConvertTo(target) + if err != nil { + return err + } + if changes == nil { + return nil + } + + bytes, err := json.Marshal(changes) + if err != nil { + return err + } + annotations := target.GetAnnotations() + if annotations == nil { + annotations = make(map[string]string) + } + annotations[kbIncrementConverterAK] = string(bytes) + target.SetAnnotations(annotations) + + return nil +} + +func incrementConvertFrom(converter incrementConverter, source metav1.Object, ic incrementChange) error { + if converter == nil { + return nil + } + + annotations := source.GetAnnotations() + if annotations != nil { + data, ok := annotations[kbIncrementConverterAK] + if ok { + if err := json.Unmarshal([]byte(data), ic); err != nil { + return err + } + maps.DeleteFunc(annotations, func(k, v string) bool { return k == kbIncrementConverterAK }) + source.SetAnnotations(annotations) + } + } + + return converter.incrementConvertFrom(source, ic) +} diff --git a/apis/apps/v1alpha1/servicedescriptor_conversion.go b/apis/apps/v1alpha1/servicedescriptor_conversion.go index 7c99a6b1e0f..fea57b7e855 100644 --- a/apis/apps/v1alpha1/servicedescriptor_conversion.go +++ b/apis/apps/v1alpha1/servicedescriptor_conversion.go @@ -34,10 +34,14 @@ func (r *ServiceDescriptor) ConvertTo(dstRaw conversion.Hub) error { dst.ObjectMeta = r.ObjectMeta // spec - copier.Copy(&dst.Spec, &r.Spec) + if err := copier.Copy(&dst.Spec, &r.Spec); err != nil { + return err + } // status - copier.Copy(&dst.Status, &r.Status) + if err := copier.Copy(&dst.Status, &r.Status); err != nil { + return err + } return nil } @@ -50,10 +54,14 @@ func (r *ServiceDescriptor) ConvertFrom(srcRaw conversion.Hub) error { r.ObjectMeta = src.ObjectMeta // spec - copier.Copy(&r.Spec, &src.Spec) + if err := copier.Copy(&r.Spec, &src.Spec); err != nil { + return err + } // status - copier.Copy(&r.Status, &src.Status) + if err := copier.Copy(&r.Status, &src.Status); err != nil { + return err + } return nil } diff --git a/apis/apps/v1alpha1/type.go b/apis/apps/v1alpha1/type.go index dc74d672e0b..2d9d8dbab3b 100644 --- a/apis/apps/v1alpha1/type.go +++ b/apis/apps/v1alpha1/type.go @@ -22,6 +22,7 @@ import ( appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/util/intstr" kbappsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" ) @@ -447,6 +448,25 @@ const ( BestEffortParallelStrategy UpdateStrategy = "BestEffortParallel" ) +// InstanceUpdateStrategy indicates the strategy that the InstanceSet +// controller will use to perform updates. +type InstanceUpdateStrategy struct { + // Partition indicates the number of pods that should be updated during a rolling update. + // The remaining pods will remain untouched. This is helpful in defining how many pods + // should participate in the update process. The update process will follow the order + // of pod names in descending lexicographical (dictionary) order. The default value is + // ComponentSpec.Replicas (i.e., update all pods). + // +optional + Partition *int32 `json:"partition,omitempty"` + // The maximum number of pods that can be unavailable during the update. + // Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). + // Absolute number is calculated from percentage by rounding up. This can not be 0. + // Defaults to 1. The field applies to all pods. That means if there is any unavailable pod, + // it will be counted towards MaxUnavailable. + // +optional + MaxUnavailable *intstr.IntOrString `json:"maxUnavailable,omitempty"` +} + // TerminationPolicyType defines termination policy types. // // +enum diff --git a/apis/apps/v1alpha1/zz_generated.deepcopy.go b/apis/apps/v1alpha1/zz_generated.deepcopy.go index ff0b4e5ba58..5114f3dd00b 100644 --- a/apis/apps/v1alpha1/zz_generated.deepcopy.go +++ b/apis/apps/v1alpha1/zz_generated.deepcopy.go @@ -32,7 +32,7 @@ import ( "k8s.io/api/core/v1" rbacv1 "k8s.io/api/rbac/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" + runtime "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/util/intstr" ) @@ -699,6 +699,11 @@ func (in *ClusterComponentSpec) DeepCopyInto(out *ClusterComponentSpec) { *out = new(UpdateStrategy) **out = **in } + if in.InstanceUpdateStrategy != nil { + in, out := &in.InstanceUpdateStrategy, &out.InstanceUpdateStrategy + *out = new(InstanceUpdateStrategy) + (*in).DeepCopyInto(*out) + } if in.ParallelPodManagementConcurrency != nil { in, out := &in.ParallelPodManagementConcurrency, &out.ParallelPodManagementConcurrency *out = new(intstr.IntOrString) @@ -1956,6 +1961,11 @@ func (in *ComponentSpec) DeepCopyInto(out *ComponentSpec) { *out = make([]string, len(*in)) copy(*out, *in) } + if in.InstanceUpdateStrategy != nil { + in, out := &in.InstanceUpdateStrategy, &out.InstanceUpdateStrategy + *out = new(InstanceUpdateStrategy) + (*in).DeepCopyInto(*out) + } if in.ParallelPodManagementConcurrency != nil { in, out := &in.ParallelPodManagementConcurrency, &out.ParallelPodManagementConcurrency *out = new(intstr.IntOrString) @@ -3471,6 +3481,31 @@ func (in *InstanceTemplate) DeepCopy() *InstanceTemplate { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *InstanceUpdateStrategy) DeepCopyInto(out *InstanceUpdateStrategy) { + *out = *in + if in.Partition != nil { + in, out := &in.Partition, &out.Partition + *out = new(int32) + **out = **in + } + if in.MaxUnavailable != nil { + in, out := &in.MaxUnavailable, &out.MaxUnavailable + *out = new(intstr.IntOrString) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InstanceUpdateStrategy. +func (in *InstanceUpdateStrategy) DeepCopy() *InstanceUpdateStrategy { + if in == nil { + return nil + } + out := new(InstanceUpdateStrategy) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *InstanceVolumeClaimTemplate) DeepCopyInto(out *InstanceVolumeClaimTemplate) { *out = *in diff --git a/apis/workloads/v1alpha1/instanceset_conversion.go b/apis/workloads/v1alpha1/instanceset_conversion.go index c4bd86ddaf4..7da2721cf7e 100644 --- a/apis/workloads/v1alpha1/instanceset_conversion.go +++ b/apis/workloads/v1alpha1/instanceset_conversion.go @@ -34,10 +34,14 @@ func (r *InstanceSet) ConvertTo(dstRaw conversion.Hub) error { dst.ObjectMeta = r.ObjectMeta // spec - copier.Copy(&dst.Spec, &r.Spec) + if err := copier.Copy(&dst.Spec, &r.Spec); err != nil { + return err + } // status - copier.Copy(&dst.Status, &r.Status) + if err := copier.Copy(&dst.Status, &r.Status); err != nil { + return err + } return nil } @@ -50,10 +54,14 @@ func (r *InstanceSet) ConvertFrom(srcRaw conversion.Hub) error { r.ObjectMeta = src.ObjectMeta // spec - copier.Copy(&r.Spec, &src.Spec) + if err := copier.Copy(&r.Spec, &src.Spec); err != nil { + return err + } // status - copier.Copy(&r.Status, &src.Status) + if err := copier.Copy(&r.Status, &src.Status); err != nil { + return err + } return nil } diff --git a/config/crd/bases/apps.kubeblocks.io_clusters.yaml b/config/crd/bases/apps.kubeblocks.io_clusters.yaml index 476972cd760..543b44a7b02 100644 --- a/config/crd/bases/apps.kubeblocks.io_clusters.yaml +++ b/config/crd/bases/apps.kubeblocks.io_clusters.yaml @@ -17264,6 +17264,33 @@ spec: - name type: object type: array + instanceUpdateStrategy: + description: |- + Indicates the InstanceUpdateStrategy that will be + employed to update Pods in the InstanceSet when a revision is made to + Template. + properties: + maxUnavailable: + anyOf: + - type: integer + - type: string + description: |- + The maximum number of pods that can be unavailable during the update. + Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). + Absolute number is calculated from percentage by rounding up. This can not be 0. + Defaults to 1. The field applies to all pods. That means if there is any unavailable pod, + it will be counted towards MaxUnavailable. + x-kubernetes-int-or-string: true + partition: + description: |- + Partition indicates the number of pods that should be updated during a rolling update. + The remaining pods will remain untouched. This is helpful in defining how many pods + should participate in the update process. The update process will follow the order + of pod names in descending lexicographical (dictionary) order. The default value is + ComponentSpec.Replicas (i.e., update all pods). + format: int32 + type: integer + type: object instances: description: |- Allows for the customization of configuration values for each instance within a Component. @@ -26405,6 +26432,33 @@ spec: - name type: object type: array + instanceUpdateStrategy: + description: |- + Indicates the InstanceUpdateStrategy that will be + employed to update Pods in the InstanceSet when a revision is made to + Template. + properties: + maxUnavailable: + anyOf: + - type: integer + - type: string + description: |- + The maximum number of pods that can be unavailable during the update. + Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). + Absolute number is calculated from percentage by rounding up. This can not be 0. + Defaults to 1. The field applies to all pods. That means if there is any unavailable pod, + it will be counted towards MaxUnavailable. + x-kubernetes-int-or-string: true + partition: + description: |- + Partition indicates the number of pods that should be updated during a rolling update. + The remaining pods will remain untouched. This is helpful in defining how many pods + should participate in the update process. The update process will follow the order + of pod names in descending lexicographical (dictionary) order. The default value is + ComponentSpec.Replicas (i.e., update all pods). + format: int32 + type: integer + type: object instances: description: |- Allows for the customization of configuration values for each instance within a Component. diff --git a/config/crd/bases/apps.kubeblocks.io_components.yaml b/config/crd/bases/apps.kubeblocks.io_components.yaml index 05f79b07c61..cf29501af6b 100644 --- a/config/crd/bases/apps.kubeblocks.io_components.yaml +++ b/config/crd/bases/apps.kubeblocks.io_components.yaml @@ -7889,6 +7889,33 @@ spec: - name type: object type: array + instanceUpdateStrategy: + description: |- + Indicates the InstanceUpdateStrategy that will be + employed to update Pods in the InstanceSet when a revision is made to + Template. + properties: + maxUnavailable: + anyOf: + - type: integer + - type: string + description: |- + The maximum number of pods that can be unavailable during the update. + Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). + Absolute number is calculated from percentage by rounding up. This can not be 0. + Defaults to 1. The field applies to all pods. That means if there is any unavailable pod, + it will be counted towards MaxUnavailable. + x-kubernetes-int-or-string: true + partition: + description: |- + Partition indicates the number of pods that should be updated during a rolling update. + The remaining pods will remain untouched. This is helpful in defining how many pods + should participate in the update process. The update process will follow the order + of pod names in descending lexicographical (dictionary) order. The default value is + ComponentSpec.Replicas (i.e., update all pods). + format: int32 + type: integer + type: object instances: description: |- Allows for the customization of configuration values for each instance within a Component. diff --git a/controllers/dataprotection/utils.go b/controllers/dataprotection/utils.go index 04883999e52..ed267431c60 100644 --- a/controllers/dataprotection/utils.go +++ b/controllers/dataprotection/utils.go @@ -40,7 +40,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/reconcile" - appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" + kbappsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" dpv1alpha1 "github.com/apecloud/kubeblocks/apis/dataprotection/v1alpha1" "github.com/apecloud/kubeblocks/pkg/constant" "github.com/apecloud/kubeblocks/pkg/controller/multicluster" @@ -217,12 +217,12 @@ func GetTargetPods(reqCtx intctrlutil.RequestCtx, // getCluster gets the cluster and will ignore the error. func getCluster(ctx context.Context, cli client.Client, - targetPod *corev1.Pod) *appsv1.Cluster { + targetPod *corev1.Pod) *kbappsv1.Cluster { clusterName := targetPod.Labels[constant.AppInstanceLabelKey] if len(clusterName) == 0 { return nil } - cluster := &appsv1.Cluster{} + cluster := &kbappsv1.Cluster{} if err := cli.Get(ctx, client.ObjectKey{ Namespace: targetPod.Namespace, Name: clusterName, @@ -236,7 +236,7 @@ func getCluster(ctx context.Context, // listObjectsOfCluster list the objects of the cluster by labels. func listObjectsOfCluster(ctx context.Context, cli client.Client, - cluster *appsv1.Cluster, + cluster *kbappsv1.Cluster, object client.ObjectList) (client.ObjectList, error) { labels := constant.GetClusterWellKnownLabels(cluster.Name) if err := cli.List(ctx, object, client.InNamespace(cluster.Namespace), client.MatchingLabels(labels)); err != nil { diff --git a/deploy/helm/crds/apps.kubeblocks.io_clusters.yaml b/deploy/helm/crds/apps.kubeblocks.io_clusters.yaml index 476972cd760..543b44a7b02 100644 --- a/deploy/helm/crds/apps.kubeblocks.io_clusters.yaml +++ b/deploy/helm/crds/apps.kubeblocks.io_clusters.yaml @@ -17264,6 +17264,33 @@ spec: - name type: object type: array + instanceUpdateStrategy: + description: |- + Indicates the InstanceUpdateStrategy that will be + employed to update Pods in the InstanceSet when a revision is made to + Template. + properties: + maxUnavailable: + anyOf: + - type: integer + - type: string + description: |- + The maximum number of pods that can be unavailable during the update. + Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). + Absolute number is calculated from percentage by rounding up. This can not be 0. + Defaults to 1. The field applies to all pods. That means if there is any unavailable pod, + it will be counted towards MaxUnavailable. + x-kubernetes-int-or-string: true + partition: + description: |- + Partition indicates the number of pods that should be updated during a rolling update. + The remaining pods will remain untouched. This is helpful in defining how many pods + should participate in the update process. The update process will follow the order + of pod names in descending lexicographical (dictionary) order. The default value is + ComponentSpec.Replicas (i.e., update all pods). + format: int32 + type: integer + type: object instances: description: |- Allows for the customization of configuration values for each instance within a Component. @@ -26405,6 +26432,33 @@ spec: - name type: object type: array + instanceUpdateStrategy: + description: |- + Indicates the InstanceUpdateStrategy that will be + employed to update Pods in the InstanceSet when a revision is made to + Template. + properties: + maxUnavailable: + anyOf: + - type: integer + - type: string + description: |- + The maximum number of pods that can be unavailable during the update. + Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). + Absolute number is calculated from percentage by rounding up. This can not be 0. + Defaults to 1. The field applies to all pods. That means if there is any unavailable pod, + it will be counted towards MaxUnavailable. + x-kubernetes-int-or-string: true + partition: + description: |- + Partition indicates the number of pods that should be updated during a rolling update. + The remaining pods will remain untouched. This is helpful in defining how many pods + should participate in the update process. The update process will follow the order + of pod names in descending lexicographical (dictionary) order. The default value is + ComponentSpec.Replicas (i.e., update all pods). + format: int32 + type: integer + type: object instances: description: |- Allows for the customization of configuration values for each instance within a Component. diff --git a/deploy/helm/crds/apps.kubeblocks.io_components.yaml b/deploy/helm/crds/apps.kubeblocks.io_components.yaml index 05f79b07c61..cf29501af6b 100644 --- a/deploy/helm/crds/apps.kubeblocks.io_components.yaml +++ b/deploy/helm/crds/apps.kubeblocks.io_components.yaml @@ -7889,6 +7889,33 @@ spec: - name type: object type: array + instanceUpdateStrategy: + description: |- + Indicates the InstanceUpdateStrategy that will be + employed to update Pods in the InstanceSet when a revision is made to + Template. + properties: + maxUnavailable: + anyOf: + - type: integer + - type: string + description: |- + The maximum number of pods that can be unavailable during the update. + Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). + Absolute number is calculated from percentage by rounding up. This can not be 0. + Defaults to 1. The field applies to all pods. That means if there is any unavailable pod, + it will be counted towards MaxUnavailable. + x-kubernetes-int-or-string: true + partition: + description: |- + Partition indicates the number of pods that should be updated during a rolling update. + The remaining pods will remain untouched. This is helpful in defining how many pods + should participate in the update process. The update process will follow the order + of pod names in descending lexicographical (dictionary) order. The default value is + ComponentSpec.Replicas (i.e., update all pods). + format: int32 + type: integer + type: object instances: description: |- Allows for the customization of configuration values for each instance within a Component. diff --git a/docs/developer_docs/api-reference/cluster.md b/docs/developer_docs/api-reference/cluster.md index 348f06342ee..dbe2741c885 100644 --- a/docs/developer_docs/api-reference/cluster.md +++ b/docs/developer_docs/api-reference/cluster.md @@ -11047,6 +11047,22 @@ an existed ServiceAccount in this field.

      +instanceUpdateStrategy
      + + +InstanceUpdateStrategy + + + + +(Optional) +

      Indicates the InstanceUpdateStrategy that will be +employed to update Pods in the InstanceSet when a revision is made to +Template.

      + + + + parallelPodManagementConcurrency
      @@ -15268,6 +15284,22 @@ Existing usage should be updated to the current preferred approach to avoid comp +instanceUpdateStrategy
      + +
      +InstanceUpdateStrategy + + + + +(Optional) +

      Indicates the InstanceUpdateStrategy that will be +employed to update Pods in the InstanceSet when a revision is made to +Template.

      + + + + parallelPodManagementConcurrency
      @@ -18925,6 +18957,22 @@ an existed ServiceAccount in this field.

      +instanceUpdateStrategy
      + +
      +InstanceUpdateStrategy + + + + +(Optional) +

      Indicates the InstanceUpdateStrategy that will be +employed to update Pods in the InstanceSet when a revision is made to +Template.

      + + + + parallelPodManagementConcurrency
      @@ -22765,6 +22813,59 @@ Add new or override existing volume claim templates.

      +

      InstanceUpdateStrategy +

      +

      +(Appears on:ClusterComponentSpec, ComponentSpec) +

      +
      +

      InstanceUpdateStrategy indicates the strategy that the InstanceSet +controller will use to perform updates.

      +
      + + + + + + + + + + + + + + + + + +
      FieldDescription
      +partition
      + +int32 + +
      +(Optional) +

      Partition indicates the number of pods that should be updated during a rolling update. +The remaining pods will remain untouched. This is helpful in defining how many pods +should participate in the update process. The update process will follow the order +of pod names in descending lexicographical (dictionary) order. The default value is +ComponentSpec.Replicas (i.e., update all pods).

      +
      +maxUnavailable
      + + +Kubernetes api utils intstr.IntOrString + + +
      +(Optional) +

      The maximum number of pods that can be unavailable during the update. +Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). +Absolute number is calculated from percentage by rounding up. This can not be 0. +Defaults to 1. The field applies to all pods. That means if there is any unavailable pod, +it will be counted towards MaxUnavailable.

      +

      InstanceVolumeClaimTemplate

      From 6fae3dbb4541ad9497ae02f05dce859ab5e9ae9e Mon Sep 17 00:00:00 2001 From: Leon Date: Wed, 11 Sep 2024 11:13:39 +0800 Subject: [PATCH 13/15] update --- apis/apps/v1/{legacy.go => deprecated.go} | 0 apis/apps/v1alpha1/cluster_conversion.go | 2 +- .../componentdefinition_conversion.go | 53 +++-- apis/apps/v1alpha1/conversion.go | 3 +- controllers/apps/component_controller.go | 5 +- .../apps/component_plan_builder_test.go | 4 +- controllers/apps/configuration/suite_test.go | 3 + .../apps/operations/util/suite_test.go | 4 +- .../apps/operations/volume_expansion.go | 1 - .../apps/operations/volume_expansion_test.go | 2 +- .../apps/opsrequest_controller_test.go | 20 +- controllers/apps/transform_types.go | 3 +- .../apps/transformer_cluster_component.go | 7 +- .../apps/transformer_cluster_deletion_test.go | 7 +- controllers/dataprotection/suite_test.go | 4 +- controllers/extensions/suite_test.go | 4 +- controllers/k8score/suite_test.go | 8 +- hack/client-sdk-gen.sh | 2 +- pkg/client/clientset/versioned/clientset.go | 13 ++ .../versioned/fake/clientset_generated.go | 7 + .../clientset/versioned/fake/register.go | 2 + .../clientset/versioned/scheme/register.go | 2 + .../versioned/typed/workloads/v1/doc.go | 20 ++ .../versioned/typed/workloads/v1/fake/doc.go | 20 ++ .../workloads/v1/fake/fake_instanceset.go | 141 +++++++++++++ .../v1/fake/fake_workloads_client.go | 40 ++++ .../typed/workloads/v1/generated_expansion.go | 21 ++ .../typed/workloads/v1/instanceset.go | 195 ++++++++++++++++++ .../typed/workloads/v1/workloads_client.go | 107 ++++++++++ .../informers/externalversions/generic.go | 5 + .../externalversions/workloads/interface.go | 8 + .../workloads/v1/instanceset.go | 90 ++++++++ .../workloads/v1/interface.go | 45 ++++ .../workloads/v1/expansion_generated.go | 27 +++ .../listers/workloads/v1/instanceset.go | 99 +++++++++ .../component/lifecycle/suite_test.go | 6 +- pkg/controller/component/suite_test.go | 2 - pkg/controller/configuration/suite_test.go | 4 + pkg/controller/factory/suite_test.go | 4 + pkg/controller/job/suite_test.go | 7 +- pkg/controller/plan/restore.go | 2 +- pkg/controller/plan/suite_test.go | 4 + pkg/controllerutil/suite_test.go | 4 + pkg/controllerutil/util.go | 12 +- pkg/dataprotection/action/suite_test.go | 4 - pkg/dataprotection/backup/suite_test.go | 4 + pkg/dataprotection/restore/suite_test.go | 10 +- 47 files changed, 964 insertions(+), 73 deletions(-) rename apis/apps/v1/{legacy.go => deprecated.go} (100%) create mode 100644 pkg/client/clientset/versioned/typed/workloads/v1/doc.go create mode 100644 pkg/client/clientset/versioned/typed/workloads/v1/fake/doc.go create mode 100644 pkg/client/clientset/versioned/typed/workloads/v1/fake/fake_instanceset.go create mode 100644 pkg/client/clientset/versioned/typed/workloads/v1/fake/fake_workloads_client.go create mode 100644 pkg/client/clientset/versioned/typed/workloads/v1/generated_expansion.go create mode 100644 pkg/client/clientset/versioned/typed/workloads/v1/instanceset.go create mode 100644 pkg/client/clientset/versioned/typed/workloads/v1/workloads_client.go create mode 100644 pkg/client/informers/externalversions/workloads/v1/instanceset.go create mode 100644 pkg/client/informers/externalversions/workloads/v1/interface.go create mode 100644 pkg/client/listers/workloads/v1/expansion_generated.go create mode 100644 pkg/client/listers/workloads/v1/instanceset.go diff --git a/apis/apps/v1/legacy.go b/apis/apps/v1/deprecated.go similarity index 100% rename from apis/apps/v1/legacy.go rename to apis/apps/v1/deprecated.go diff --git a/apis/apps/v1alpha1/cluster_conversion.go b/apis/apps/v1alpha1/cluster_conversion.go index 1d60d9128ce..b61d53d979e 100644 --- a/apis/apps/v1alpha1/cluster_conversion.go +++ b/apis/apps/v1alpha1/cluster_conversion.go @@ -148,7 +148,7 @@ type clusterSpecConverter struct { Resources ClusterResources `json:"resources,omitempty"` Storage ClusterStorage `json:"storage,omitempty"` Network *ClusterNetwork `json:"network,omitempty"` - Components map[string]clusterCompConverter `json:"Components,omitempty"` + Components map[string]clusterCompConverter `json:"components,omitempty"` Shardings map[string]clusterCompConverter `json:"shardings,omitempty"` } diff --git a/apis/apps/v1alpha1/componentdefinition_conversion.go b/apis/apps/v1alpha1/componentdefinition_conversion.go index 85db2069511..bc16131e525 100644 --- a/apis/apps/v1alpha1/componentdefinition_conversion.go +++ b/apis/apps/v1alpha1/componentdefinition_conversion.go @@ -76,13 +76,14 @@ func (r *ComponentDefinition) ConvertFrom(srcRaw conversion.Hub) error { // convertTo converts this ComponentDefinition to the Hub version (v1). func (r *ComponentDefinition) incrementConvertTo(dstRaw metav1.Object) (incrementChange, error) { // changed - r.changesToComponentDefinition(dstRaw.(*appsv1.ComponentDefinition)) + if err := r.changesToComponentDefinition(dstRaw.(*appsv1.ComponentDefinition)); err != nil { + return nil, err + } // deleted c := &componentDefinitionConverter{ - Monitor: r.Spec.Monitor, - RoleArbitrator: r.Spec.RoleArbitrator, - LifecycleActionSwitchover: r.Spec.LifecycleActions.Switchover, + Monitor: r.Spec.Monitor, + RoleArbitrator: r.Spec.RoleArbitrator, } if r.Spec.LifecycleActions != nil && r.Spec.LifecycleActions.Switchover != nil { c.LifecycleActionSwitchover = r.Spec.LifecycleActions.Switchover @@ -104,12 +105,10 @@ func (r *ComponentDefinition) incrementConvertFrom(srcRaw metav1.Object, ic incr } // changed - r.changesFromComponentDefinition(srcRaw.(*appsv1.ComponentDefinition)) - - return nil + return r.changesFromComponentDefinition(srcRaw.(*appsv1.ComponentDefinition)) } -func (r *ComponentDefinition) changesToComponentDefinition(cmpd *appsv1.ComponentDefinition) { +func (r *ComponentDefinition) changesToComponentDefinition(cmpd *appsv1.ComponentDefinition) error { // changed: // spec // vars @@ -122,12 +121,15 @@ func (r *ComponentDefinition) changesToComponentDefinition(cmpd *appsv1.Componen if v.ValueFrom == nil || v.ValueFrom.ComponentVarRef == nil || v.ValueFrom.ComponentVarRef.InstanceNames == nil { continue } - r.toV1VarsPodNames(v, cmpd) + if err := r.toV1VarsPodNames(v, cmpd); err != nil { + return err + } } r.toV1LifecycleActions(cmpd) + return nil } -func (r *ComponentDefinition) changesFromComponentDefinition(cmpd *appsv1.ComponentDefinition) { +func (r *ComponentDefinition) changesFromComponentDefinition(cmpd *appsv1.ComponentDefinition) error { // changed: // spec // vars @@ -140,27 +142,52 @@ func (r *ComponentDefinition) changesFromComponentDefinition(cmpd *appsv1.Compon if v.ValueFrom == nil || v.ValueFrom.ComponentVarRef == nil || v.ValueFrom.ComponentVarRef.PodNames == nil { continue } - r.fromV1VarsPodNames(v) + if err := r.fromV1VarsPodNames(v); err != nil { + return err + } } r.fromV1LifecycleActions(cmpd) + return nil } -func (r *ComponentDefinition) toV1VarsPodNames(v EnvVar, cmpd *appsv1.ComponentDefinition) { +func (r *ComponentDefinition) toV1VarsPodNames(v EnvVar, cmpd *appsv1.ComponentDefinition) error { for i, vv := range cmpd.Spec.Vars { if vv.Name == v.Name { opt := appsv1.VarOption(*v.ValueFrom.ComponentVarRef.InstanceNames) + if cmpd.Spec.Vars[i].ValueFrom == nil { + cmpd.Spec.Vars[i].ValueFrom = &appsv1.VarSource{} + } + if cmpd.Spec.Vars[i].ValueFrom.ComponentVarRef == nil { + if err := copier.Copy(&cmpd.Spec.Vars[i].ValueFrom.ComponentVarRef.ClusterObjectReference, + &v.ValueFrom.ComponentVarRef.ClusterObjectReference); err != nil { + return err + } + } cmpd.Spec.Vars[i].ValueFrom.ComponentVarRef.PodNames = &opt + break } } + return nil } -func (r *ComponentDefinition) fromV1VarsPodNames(v appsv1.EnvVar) { +func (r *ComponentDefinition) fromV1VarsPodNames(v appsv1.EnvVar) error { for i, vv := range r.Spec.Vars { if vv.Name == v.Name { opt := VarOption(*v.ValueFrom.ComponentVarRef.PodNames) + if r.Spec.Vars[i].ValueFrom == nil { + r.Spec.Vars[i].ValueFrom = &VarSource{} + } + if r.Spec.Vars[i].ValueFrom.ComponentVarRef == nil { + if err := copier.Copy(&r.Spec.Vars[i].ValueFrom.ComponentVarRef.ClusterObjectReference, + &v.ValueFrom.ComponentVarRef.ClusterObjectReference); err != nil { + return err + } + } r.Spec.Vars[i].ValueFrom.ComponentVarRef.InstanceNames = &opt + break } } + return nil } func (r *ComponentDefinition) toV1LifecycleActions(cmpd *appsv1.ComponentDefinition) { diff --git a/apis/apps/v1alpha1/conversion.go b/apis/apps/v1alpha1/conversion.go index 60ac9b1d732..19a2fd8aea3 100644 --- a/apis/apps/v1alpha1/conversion.go +++ b/apis/apps/v1alpha1/conversion.go @@ -21,7 +21,6 @@ package v1alpha1 import ( "encoding/json" - "maps" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -81,7 +80,7 @@ func incrementConvertFrom(converter incrementConverter, source metav1.Object, ic if err := json.Unmarshal([]byte(data), ic); err != nil { return err } - maps.DeleteFunc(annotations, func(k, v string) bool { return k == kbIncrementConverterAK }) + delete(annotations, kbIncrementConverterAK) source.SetAnnotations(annotations) } } diff --git a/controllers/apps/component_controller.go b/controllers/apps/component_controller.go index 90322d7dbe9..7311e20086a 100644 --- a/controllers/apps/component_controller.go +++ b/controllers/apps/component_controller.go @@ -37,6 +37,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/log" "sigs.k8s.io/controller-runtime/pkg/reconcile" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" dpv1alpha1 "github.com/apecloud/kubeblocks/apis/dataprotection/v1alpha1" workloads "github.com/apecloud/kubeblocks/apis/workloads/v1" @@ -218,7 +219,7 @@ func (r *ComponentReconciler) SetupWithManager(mgr ctrl.Manager, multiClusterMgr func (r *ComponentReconciler) setupWithManager(mgr ctrl.Manager) error { b := intctrlutil.NewNamespacedControllerManagedBy(mgr). - For(&appsv1alpha1.Component{}). + For(&appsv1.Component{}). WithOptions(controller.Options{ MaxConcurrentReconciles: viper.GetInt(constant.CfgKBReconcileWorkers), }). @@ -247,7 +248,7 @@ func (r *ComponentReconciler) setupWithManager(mgr ctrl.Manager) error { func (r *ComponentReconciler) setupWithMultiClusterManager(mgr ctrl.Manager, multiClusterMgr multicluster.Manager) error { b := intctrlutil.NewNamespacedControllerManagedBy(mgr). - For(&appsv1alpha1.Component{}). + For(&appsv1.Component{}). WithOptions(controller.Options{ MaxConcurrentReconciles: viper.GetInt(constant.CfgKBReconcileWorkers), }). diff --git a/controllers/apps/component_plan_builder_test.go b/controllers/apps/component_plan_builder_test.go index bf6539ba7ea..90c7ca3b4f8 100644 --- a/controllers/apps/component_plan_builder_test.go +++ b/controllers/apps/component_plan_builder_test.go @@ -27,7 +27,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/log" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" intctrlutil "github.com/apecloud/kubeblocks/pkg/controllerutil" "github.com/apecloud/kubeblocks/pkg/generics" testapps "github.com/apecloud/kubeblocks/pkg/testutil/apps" @@ -77,7 +77,7 @@ var _ = Describe("component plan builder test", func() { compObj := testapps.NewComponentFactory(testCtx.DefaultNamespace, compName, compDefName).WithRandomName().GetObject() Expect(testCtx.Cli.Create(testCtx.Ctx, compObj)).Should(Succeed()) compKey := client.ObjectKeyFromObject(compObj) - Eventually(testapps.CheckObjExists(&testCtx, compKey, &appsv1alpha1.Component{}, true)).Should(Succeed()) + Eventually(testapps.CheckObjExists(&testCtx, compKey, &appsv1.Component{}, true)).Should(Succeed()) req := ctrl.Request{ NamespacedName: compKey, diff --git a/controllers/apps/configuration/suite_test.go b/controllers/apps/configuration/suite_test.go index 0035a97c3eb..c7ff421396d 100644 --- a/controllers/apps/configuration/suite_test.go +++ b/controllers/apps/configuration/suite_test.go @@ -37,6 +37,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/log/zap" "sigs.k8s.io/controller-runtime/pkg/metrics/server" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" appsv1beta1 "github.com/apecloud/kubeblocks/apis/apps/v1beta1" workloadsv1 "github.com/apecloud/kubeblocks/apis/workloads/v1" @@ -83,6 +84,8 @@ var _ = BeforeSuite(func() { Expect(err).NotTo(HaveOccurred()) err = appsv1beta1.AddToScheme(scheme.Scheme) Expect(err).NotTo(HaveOccurred()) + err = appsv1.AddToScheme(scheme.Scheme) + Expect(err).NotTo(HaveOccurred()) err = workloadsv1.AddToScheme(scheme.Scheme) Expect(err).NotTo(HaveOccurred()) diff --git a/controllers/apps/operations/util/suite_test.go b/controllers/apps/operations/util/suite_test.go index 0362d14318c..52bf1c8cd27 100644 --- a/controllers/apps/operations/util/suite_test.go +++ b/controllers/apps/operations/util/suite_test.go @@ -37,8 +37,8 @@ import ( "sigs.k8s.io/controller-runtime/pkg/log/zap" "sigs.k8s.io/controller-runtime/pkg/metrics/server" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" - appsv1beta1 "github.com/apecloud/kubeblocks/apis/apps/v1beta1" intctrlutil "github.com/apecloud/kubeblocks/pkg/controllerutil" "github.com/apecloud/kubeblocks/pkg/testutil" viper "github.com/apecloud/kubeblocks/pkg/viperx" @@ -88,7 +88,7 @@ var _ = BeforeSuite(func() { err = appsv1alpha1.AddToScheme(scheme.Scheme) Expect(err).NotTo(HaveOccurred()) - err = appsv1beta1.AddToScheme(scheme.Scheme) + err = appsv1.AddToScheme(scheme.Scheme) Expect(err).NotTo(HaveOccurred()) // +kubebuilder:scaffold:scheme diff --git a/controllers/apps/operations/volume_expansion.go b/controllers/apps/operations/volume_expansion.go index 0cc0cb5cfc2..6a91ed9d645 100644 --- a/controllers/apps/operations/volume_expansion.go +++ b/controllers/apps/operations/volume_expansion.go @@ -1,5 +1,4 @@ /* -/* Copyright (C) 2022-2024 ApeCloud Co., Ltd This file is part of KubeBlocks project diff --git a/controllers/apps/operations/volume_expansion_test.go b/controllers/apps/operations/volume_expansion_test.go index 61503e1e11a..0d17e3e20a0 100644 --- a/controllers/apps/operations/volume_expansion_test.go +++ b/controllers/apps/operations/volume_expansion_test.go @@ -213,7 +213,7 @@ var _ = Describe("OpsRequest Controller Volume Expansion Handler", func() { pvc := &corev1.PersistentVolumeClaim{} Expect(k8sClient.Get(ctx, client.ObjectKey{Name: pvcNames[0], Namespace: testCtx.DefaultNamespace}, pvc)).Should(Succeed()) - Eventually(testapps.GetClusterPhase(&testCtx, client.ObjectKeyFromObject(clusterObject))).Should(Equal(appsv1alpha1.RunningClusterPhase)) + Eventually(testapps.GetClusterPhase(&testCtx, client.ObjectKeyFromObject(clusterObject))).Should(Equal(appsv1.RunningClusterPhase)) } Context("Test VolumeExpansion", func() { diff --git a/controllers/apps/opsrequest_controller_test.go b/controllers/apps/opsrequest_controller_test.go index 532cfcb6243..5a40bebf1cf 100644 --- a/controllers/apps/opsrequest_controller_test.go +++ b/controllers/apps/opsrequest_controller_test.go @@ -146,7 +146,7 @@ var _ = Describe("OpsRequest Controller", func() { clusterKey = client.ObjectKeyFromObject(clusterObj) By("Waiting for the cluster enters creating phase") - Eventually(testapps.GetClusterPhase(&testCtx, clusterKey)).Should(Equal(appsv1alpha1.CreatingClusterPhase)) + Eventually(testapps.GetClusterPhase(&testCtx, clusterKey)).Should(Equal(appsv1.CreatingClusterPhase)) By("mock pods are available and wait for cluster enter running phase") podName := fmt.Sprintf("%s-%s-0", clusterObj.Name, mysqlCompName) @@ -166,7 +166,7 @@ var _ = Describe("OpsRequest Controller", func() { Expect(testapps.ChangeObjStatus(&testCtx, mysqlIts, func() { testk8s.MockInstanceSetReady(mysqlIts, pod) })).ShouldNot(HaveOccurred()) - Eventually(testapps.GetClusterPhase(&testCtx, clusterKey)).Should(Equal(appsv1alpha1.RunningClusterPhase)) + Eventually(testapps.GetClusterPhase(&testCtx, clusterKey)).Should(Equal(appsv1.RunningClusterPhase)) By("send VerticalScalingOpsRequest successfully") opsKey := types.NamespacedName{Name: opsName, Namespace: testCtx.DefaultNamespace} @@ -184,15 +184,15 @@ var _ = Describe("OpsRequest Controller", func() { Eventually(testapps.GetOpsRequestPhase(&testCtx, opsKey)).Should(Equal(appsv1alpha1.OpsRunningPhase)) By("check cluster & component phase as updating") - Eventually(testapps.GetClusterPhase(&testCtx, clusterKey)).Should(Equal(appsv1alpha1.UpdatingClusterPhase)) - Eventually(testapps.GetClusterComponentPhase(&testCtx, clusterKey, mysqlCompName)).Should(Equal(appsv1alpha1.UpdatingClusterCompPhase)) + Eventually(testapps.GetClusterPhase(&testCtx, clusterKey)).Should(Equal(appsv1.UpdatingClusterPhase)) + Eventually(testapps.GetClusterComponentPhase(&testCtx, clusterKey, mysqlCompName)).Should(Equal(appsv1.UpdatingClusterCompPhase)) By("mock bring Cluster and changed component back to running status") Expect(testapps.GetAndChangeObjStatus(&testCtx, client.ObjectKeyFromObject(mysqlIts), func(tmpIts *workloads.InstanceSet) { testk8s.MockInstanceSetReady(tmpIts, pod) })()).ShouldNot(HaveOccurred()) - Eventually(testapps.GetClusterComponentPhase(&testCtx, clusterKey, mysqlCompName)).Should(Equal(appsv1alpha1.RunningClusterCompPhase)) - Eventually(testapps.GetClusterPhase(&testCtx, clusterKey)).Should(Equal(appsv1alpha1.RunningClusterPhase)) + Eventually(testapps.GetClusterComponentPhase(&testCtx, clusterKey, mysqlCompName)).Should(Equal(appsv1.RunningClusterCompPhase)) + Eventually(testapps.GetClusterPhase(&testCtx, clusterKey)).Should(Equal(appsv1.RunningClusterPhase)) By("notice opsrequest controller to run") testk8s.MockPodIsTerminating(ctx, testCtx, pod) @@ -305,7 +305,7 @@ var _ = Describe("OpsRequest Controller", func() { testk8s.MockInstanceSetReady(its, mockPods...) })).ShouldNot(HaveOccurred()) - Eventually(testapps.GetClusterComponentPhase(&testCtx, clusterKey, mysqlCompName)).Should(Equal(appsv1alpha1.RunningClusterCompPhase)) + Eventually(testapps.GetClusterComponentPhase(&testCtx, clusterKey, mysqlCompName)).Should(Equal(appsv1.RunningClusterCompPhase)) } createMysqlCluster := func(replicas int32) { @@ -737,7 +737,7 @@ var _ = Describe("OpsRequest Controller", func() { time.Sleep(time.Second) ops1 := createRestartOps(clusterObj.Name, 1) Eventually(testapps.GetOpsRequestPhase(&testCtx, client.ObjectKeyFromObject(ops1))).Should(Equal(appsv1alpha1.OpsRunningPhase)) - Eventually(testapps.GetClusterPhase(&testCtx, clusterKey)).Should(Equal(appsv1alpha1.UpdatingClusterPhase)) + Eventually(testapps.GetClusterPhase(&testCtx, clusterKey)).Should(Equal(appsv1.UpdatingClusterPhase)) By("create second restart ops") ops2 := createRestartOps(clusterObj.Name, 2) @@ -793,7 +793,7 @@ var _ = Describe("OpsRequest Controller", func() { time.Sleep(time.Second) ops1 := createRestartOps(clusterObj.Name, 1) Eventually(testapps.GetOpsRequestPhase(&testCtx, client.ObjectKeyFromObject(ops1))).Should(Equal(appsv1alpha1.OpsRunningPhase)) - Eventually(testapps.GetClusterPhase(&testCtx, clusterKey)).Should(Equal(appsv1alpha1.UpdatingClusterPhase)) + Eventually(testapps.GetClusterPhase(&testCtx, clusterKey)).Should(Equal(appsv1.UpdatingClusterPhase)) By("create secondary restart ops") ops2 := createRestartOps(clusterObj.Name, 2) @@ -828,7 +828,7 @@ var _ = Describe("OpsRequest Controller", func() { time.Sleep(time.Second) restartOps1 := createRestartOps(clusterObj.Name, 0) Eventually(testapps.GetOpsRequestPhase(&testCtx, client.ObjectKeyFromObject(restartOps1))).Should(Equal(appsv1alpha1.OpsRunningPhase)) - Eventually(testapps.GetClusterPhase(&testCtx, clusterKey)).Should(Equal(appsv1alpha1.UpdatingClusterPhase)) + Eventually(testapps.GetClusterPhase(&testCtx, clusterKey)).Should(Equal(appsv1.UpdatingClusterPhase)) createExposeOps := func(clusterName string, index int, exposeSwitch appsv1alpha1.ExposeSwitch) *appsv1alpha1.OpsRequest { ops := testapps.NewOpsRequestObj(fmt.Sprintf("expose-ops-%d", index), testCtx.DefaultNamespace, diff --git a/controllers/apps/transform_types.go b/controllers/apps/transform_types.go index 735ce8428c9..5b89554b7a1 100644 --- a/controllers/apps/transform_types.go +++ b/controllers/apps/transform_types.go @@ -28,6 +28,7 @@ import ( clientgoscheme "k8s.io/client-go/kubernetes/scheme" "sigs.k8s.io/controller-runtime/pkg/client" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" appsv1beta1 "github.com/apecloud/kubeblocks/apis/apps/v1beta1" dpv1alpha1 "github.com/apecloud/kubeblocks/apis/dataprotection/v1alpha1" @@ -41,9 +42,9 @@ var ( func init() { utilruntime.Must(clientgoscheme.AddToScheme(rscheme)) - utilruntime.Must(appsv1alpha1.AddToScheme(rscheme)) utilruntime.Must(appsv1beta1.AddToScheme(rscheme)) + utilruntime.Must(appsv1.AddToScheme(rscheme)) utilruntime.Must(dpv1alpha1.AddToScheme(rscheme)) utilruntime.Must(snapshotv1.AddToScheme(rscheme)) utilruntime.Must(extensionsv1alpha1.AddToScheme(rscheme)) diff --git a/controllers/apps/transformer_cluster_component.go b/controllers/apps/transformer_cluster_component.go index c26aac9ef9e..ebb48254cb8 100644 --- a/controllers/apps/transformer_cluster_component.go +++ b/controllers/apps/transformer_cluster_component.go @@ -33,7 +33,6 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" "github.com/apecloud/kubeblocks/pkg/constant" "github.com/apecloud/kubeblocks/pkg/controller/component" "github.com/apecloud/kubeblocks/pkg/controller/graph" @@ -403,7 +402,7 @@ type compNotExistPrecondition struct { func (c *compNotExistPrecondition) match(transCtx *clusterTransformContext, dag *graph.DAG, compName string) (bool, error) { get := func(compKey types.NamespacedName) (bool, error) { - comp := &appsv1alpha1.Component{} + comp := &appsv1.Component{} err := transCtx.Client.Get(transCtx.Context, compKey, comp) if err != nil && !apierrors.IsNotFound(err) { return false, err @@ -412,7 +411,7 @@ func (c *compNotExistPrecondition) match(transCtx *clusterTransformContext, dag } dagCreate := func(compKey types.NamespacedName) bool { graphCli, _ := transCtx.Client.(model.GraphClient) - comp := &appsv1alpha1.Component{ + comp := &appsv1.Component{ ObjectMeta: metav1.ObjectMeta{ Namespace: compKey.Namespace, Name: compKey.Name, @@ -447,7 +446,7 @@ type compPhasePrecondition struct { func (c *compPhasePrecondition) match(transCtx *clusterTransformContext, dag *graph.DAG, compName string) (bool, error) { dagGet := func(compKey types.NamespacedName) bool { graphCli, _ := transCtx.Client.(model.GraphClient) - for _, obj := range graphCli.FindAll(dag, &appsv1alpha1.Component{}) { + for _, obj := range graphCli.FindAll(dag, &appsv1.Component{}) { if client.ObjectKeyFromObject(obj) == compKey { return true } diff --git a/controllers/apps/transformer_cluster_deletion_test.go b/controllers/apps/transformer_cluster_deletion_test.go index bd143af2a2a..b1bf3864b21 100644 --- a/controllers/apps/transformer_cluster_deletion_test.go +++ b/controllers/apps/transformer_cluster_deletion_test.go @@ -30,7 +30,6 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" "github.com/apecloud/kubeblocks/pkg/controller/graph" "github.com/apecloud/kubeblocks/pkg/controller/model" testapps "github.com/apecloud/kubeblocks/pkg/testutil/apps" @@ -78,19 +77,19 @@ var _ = Describe("clusterDeletionTransformer", func() { reader = &mockReader{ objs: []client.Object{ clusterDef, - &appsv1alpha1.Component{ + &appsv1.Component{ ObjectMeta: metav1.ObjectMeta{ Namespace: testCtx.DefaultNamespace, Name: "test-cluster-comp1", }, }, - &appsv1alpha1.Component{ + &appsv1.Component{ ObjectMeta: metav1.ObjectMeta{ Namespace: testCtx.DefaultNamespace, Name: "test-cluster-comp2", }, }, - &appsv1alpha1.Component{ + &appsv1.Component{ ObjectMeta: metav1.ObjectMeta{ Namespace: testCtx.DefaultNamespace, Name: "test-cluster-comp3", diff --git a/controllers/dataprotection/suite_test.go b/controllers/dataprotection/suite_test.go index c016fcf9f21..a1150186a02 100644 --- a/controllers/dataprotection/suite_test.go +++ b/controllers/dataprotection/suite_test.go @@ -45,7 +45,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/manager" "sigs.k8s.io/controller-runtime/pkg/metrics/server" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" dpv1alpha1 "github.com/apecloud/kubeblocks/apis/dataprotection/v1alpha1" "github.com/apecloud/kubeblocks/pkg/constant" dptypes "github.com/apecloud/kubeblocks/pkg/dataprotection/types" @@ -118,7 +118,7 @@ var _ = BeforeSuite(func() { err = vsv1beta1.AddToScheme(scheme) Expect(err).NotTo(HaveOccurred()) - err = appsv1alpha1.AddToScheme(scheme) + err = appsv1.AddToScheme(scheme) Expect(err).NotTo(HaveOccurred()) err = dpv1alpha1.AddToScheme(scheme) diff --git a/controllers/extensions/suite_test.go b/controllers/extensions/suite_test.go index 0bb9676e426..7346407349f 100644 --- a/controllers/extensions/suite_test.go +++ b/controllers/extensions/suite_test.go @@ -36,7 +36,7 @@ import ( logf "sigs.k8s.io/controller-runtime/pkg/log" "sigs.k8s.io/controller-runtime/pkg/log/zap" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" extensionsv1alpha1 "github.com/apecloud/kubeblocks/apis/extensions/v1alpha1" "github.com/apecloud/kubeblocks/pkg/constant" @@ -97,7 +97,7 @@ var _ = BeforeSuite(func() { err = extensionsv1alpha1.AddToScheme(scheme.Scheme) Expect(err).NotTo(HaveOccurred()) - err = appsv1alpha1.AddToScheme(scheme.Scheme) + err = appsv1.AddToScheme(scheme.Scheme) Expect(err).NotTo(HaveOccurred()) // +kubebuilder:scaffold:scheme diff --git a/controllers/k8score/suite_test.go b/controllers/k8score/suite_test.go index d6bc14aa37c..64d229938b8 100644 --- a/controllers/k8score/suite_test.go +++ b/controllers/k8score/suite_test.go @@ -40,8 +40,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/manager" "sigs.k8s.io/controller-runtime/pkg/metrics/server" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" - appsv1beta1 "github.com/apecloud/kubeblocks/apis/apps/v1beta1" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" workloads "github.com/apecloud/kubeblocks/apis/workloads/v1" "github.com/apecloud/kubeblocks/pkg/testutil" viper "github.com/apecloud/kubeblocks/pkg/viperx" @@ -95,10 +94,7 @@ var _ = BeforeSuite(func() { err = storagev1.AddToScheme(scheme.Scheme) Expect(err).NotTo(HaveOccurred()) - err = appsv1beta1.AddToScheme(scheme.Scheme) - Expect(err).NotTo(HaveOccurred()) - - err = appsv1alpha1.AddToScheme(scheme.Scheme) + err = appsv1.AddToScheme(scheme.Scheme) Expect(err).NotTo(HaveOccurred()) err = workloads.AddToScheme(scheme.Scheme) diff --git a/hack/client-sdk-gen.sh b/hack/client-sdk-gen.sh index ce3d9d5f899..78f681746c4 100755 --- a/hack/client-sdk-gen.sh +++ b/hack/client-sdk-gen.sh @@ -32,7 +32,7 @@ chmod u+x ${CODE_GENERATOR_PATH}/*.sh GENERATORS="client,informer,lister" OUTPUT_PACKAGE="github.com/apecloud/kubeblocks/pkg/client" APIS_PACKAGE="github.com/apecloud/kubeblocks/apis" -GROUP_VERSIONS="apps:v1alpha1 apps:v1beta1 apps:v1 dataprotection:v1alpha1 extensions:v1alpha1 workloads:v1alpha1" +GROUP_VERSIONS="apps:v1alpha1 apps:v1beta1 apps:v1 dataprotection:v1alpha1 extensions:v1alpha1 workloads:v1alpha1 workloads:v1" OUTPUT_BASE="${SCRIPT_ROOT}/hack" diff --git a/pkg/client/clientset/versioned/clientset.go b/pkg/client/clientset/versioned/clientset.go index a7b93e6756f..b833f00d898 100644 --- a/pkg/client/clientset/versioned/clientset.go +++ b/pkg/client/clientset/versioned/clientset.go @@ -27,6 +27,7 @@ import ( appsv1beta1 "github.com/apecloud/kubeblocks/pkg/client/clientset/versioned/typed/apps/v1beta1" dataprotectionv1alpha1 "github.com/apecloud/kubeblocks/pkg/client/clientset/versioned/typed/dataprotection/v1alpha1" extensionsv1alpha1 "github.com/apecloud/kubeblocks/pkg/client/clientset/versioned/typed/extensions/v1alpha1" + workloadsv1 "github.com/apecloud/kubeblocks/pkg/client/clientset/versioned/typed/workloads/v1" workloadsv1alpha1 "github.com/apecloud/kubeblocks/pkg/client/clientset/versioned/typed/workloads/v1alpha1" discovery "k8s.io/client-go/discovery" rest "k8s.io/client-go/rest" @@ -41,6 +42,7 @@ type Interface interface { DataprotectionV1alpha1() dataprotectionv1alpha1.DataprotectionV1alpha1Interface ExtensionsV1alpha1() extensionsv1alpha1.ExtensionsV1alpha1Interface WorkloadsV1alpha1() workloadsv1alpha1.WorkloadsV1alpha1Interface + WorkloadsV1() workloadsv1.WorkloadsV1Interface } // Clientset contains the clients for groups. @@ -52,6 +54,7 @@ type Clientset struct { dataprotectionV1alpha1 *dataprotectionv1alpha1.DataprotectionV1alpha1Client extensionsV1alpha1 *extensionsv1alpha1.ExtensionsV1alpha1Client workloadsV1alpha1 *workloadsv1alpha1.WorkloadsV1alpha1Client + workloadsV1 *workloadsv1.WorkloadsV1Client } // AppsV1alpha1 retrieves the AppsV1alpha1Client @@ -84,6 +87,11 @@ func (c *Clientset) WorkloadsV1alpha1() workloadsv1alpha1.WorkloadsV1alpha1Inter return c.workloadsV1alpha1 } +// WorkloadsV1 retrieves the WorkloadsV1Client +func (c *Clientset) WorkloadsV1() workloadsv1.WorkloadsV1Interface { + return c.workloadsV1 +} + // Discovery retrieves the DiscoveryClient func (c *Clientset) Discovery() discovery.DiscoveryInterface { if c == nil { @@ -152,6 +160,10 @@ func NewForConfigAndClient(c *rest.Config, httpClient *http.Client) (*Clientset, if err != nil { return nil, err } + cs.workloadsV1, err = workloadsv1.NewForConfigAndClient(&configShallowCopy, httpClient) + if err != nil { + return nil, err + } cs.DiscoveryClient, err = discovery.NewDiscoveryClientForConfigAndClient(&configShallowCopy, httpClient) if err != nil { @@ -179,6 +191,7 @@ func New(c rest.Interface) *Clientset { cs.dataprotectionV1alpha1 = dataprotectionv1alpha1.New(c) cs.extensionsV1alpha1 = extensionsv1alpha1.New(c) cs.workloadsV1alpha1 = workloadsv1alpha1.New(c) + cs.workloadsV1 = workloadsv1.New(c) cs.DiscoveryClient = discovery.NewDiscoveryClient(c) return &cs diff --git a/pkg/client/clientset/versioned/fake/clientset_generated.go b/pkg/client/clientset/versioned/fake/clientset_generated.go index 1d5d8e85a9c..14f21210c12 100644 --- a/pkg/client/clientset/versioned/fake/clientset_generated.go +++ b/pkg/client/clientset/versioned/fake/clientset_generated.go @@ -30,6 +30,8 @@ import ( fakedataprotectionv1alpha1 "github.com/apecloud/kubeblocks/pkg/client/clientset/versioned/typed/dataprotection/v1alpha1/fake" extensionsv1alpha1 "github.com/apecloud/kubeblocks/pkg/client/clientset/versioned/typed/extensions/v1alpha1" fakeextensionsv1alpha1 "github.com/apecloud/kubeblocks/pkg/client/clientset/versioned/typed/extensions/v1alpha1/fake" + workloadsv1 "github.com/apecloud/kubeblocks/pkg/client/clientset/versioned/typed/workloads/v1" + fakeworkloadsv1 "github.com/apecloud/kubeblocks/pkg/client/clientset/versioned/typed/workloads/v1/fake" workloadsv1alpha1 "github.com/apecloud/kubeblocks/pkg/client/clientset/versioned/typed/workloads/v1alpha1" fakeworkloadsv1alpha1 "github.com/apecloud/kubeblocks/pkg/client/clientset/versioned/typed/workloads/v1alpha1/fake" "k8s.io/apimachinery/pkg/runtime" @@ -118,3 +120,8 @@ func (c *Clientset) ExtensionsV1alpha1() extensionsv1alpha1.ExtensionsV1alpha1In func (c *Clientset) WorkloadsV1alpha1() workloadsv1alpha1.WorkloadsV1alpha1Interface { return &fakeworkloadsv1alpha1.FakeWorkloadsV1alpha1{Fake: &c.Fake} } + +// WorkloadsV1 retrieves the WorkloadsV1Client +func (c *Clientset) WorkloadsV1() workloadsv1.WorkloadsV1Interface { + return &fakeworkloadsv1.FakeWorkloadsV1{Fake: &c.Fake} +} diff --git a/pkg/client/clientset/versioned/fake/register.go b/pkg/client/clientset/versioned/fake/register.go index b4e4ed192ed..c6fde5bc7e7 100644 --- a/pkg/client/clientset/versioned/fake/register.go +++ b/pkg/client/clientset/versioned/fake/register.go @@ -24,6 +24,7 @@ import ( appsv1beta1 "github.com/apecloud/kubeblocks/apis/apps/v1beta1" dataprotectionv1alpha1 "github.com/apecloud/kubeblocks/apis/dataprotection/v1alpha1" extensionsv1alpha1 "github.com/apecloud/kubeblocks/apis/extensions/v1alpha1" + workloadsv1 "github.com/apecloud/kubeblocks/apis/workloads/v1" workloadsv1alpha1 "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" @@ -42,6 +43,7 @@ var localSchemeBuilder = runtime.SchemeBuilder{ dataprotectionv1alpha1.AddToScheme, extensionsv1alpha1.AddToScheme, workloadsv1alpha1.AddToScheme, + workloadsv1.AddToScheme, } // AddToScheme adds all types of this clientset into the given scheme. This allows composition diff --git a/pkg/client/clientset/versioned/scheme/register.go b/pkg/client/clientset/versioned/scheme/register.go index f59c8386928..99748688090 100644 --- a/pkg/client/clientset/versioned/scheme/register.go +++ b/pkg/client/clientset/versioned/scheme/register.go @@ -24,6 +24,7 @@ import ( appsv1beta1 "github.com/apecloud/kubeblocks/apis/apps/v1beta1" dataprotectionv1alpha1 "github.com/apecloud/kubeblocks/apis/dataprotection/v1alpha1" extensionsv1alpha1 "github.com/apecloud/kubeblocks/apis/extensions/v1alpha1" + workloadsv1 "github.com/apecloud/kubeblocks/apis/workloads/v1" workloadsv1alpha1 "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" @@ -42,6 +43,7 @@ var localSchemeBuilder = runtime.SchemeBuilder{ dataprotectionv1alpha1.AddToScheme, extensionsv1alpha1.AddToScheme, workloadsv1alpha1.AddToScheme, + workloadsv1.AddToScheme, } // AddToScheme adds all types of this clientset into the given scheme. This allows composition diff --git a/pkg/client/clientset/versioned/typed/workloads/v1/doc.go b/pkg/client/clientset/versioned/typed/workloads/v1/doc.go new file mode 100644 index 00000000000..8a483cc3601 --- /dev/null +++ b/pkg/client/clientset/versioned/typed/workloads/v1/doc.go @@ -0,0 +1,20 @@ +/* +Copyright (C) 2022-2024 ApeCloud Co., Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +// This package has the automatically generated typed clients. +package v1 diff --git a/pkg/client/clientset/versioned/typed/workloads/v1/fake/doc.go b/pkg/client/clientset/versioned/typed/workloads/v1/fake/doc.go new file mode 100644 index 00000000000..a68eddec4bb --- /dev/null +++ b/pkg/client/clientset/versioned/typed/workloads/v1/fake/doc.go @@ -0,0 +1,20 @@ +/* +Copyright (C) 2022-2024 ApeCloud Co., Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +// Package fake has the automatically generated clients. +package fake diff --git a/pkg/client/clientset/versioned/typed/workloads/v1/fake/fake_instanceset.go b/pkg/client/clientset/versioned/typed/workloads/v1/fake/fake_instanceset.go new file mode 100644 index 00000000000..063ab796a9e --- /dev/null +++ b/pkg/client/clientset/versioned/typed/workloads/v1/fake/fake_instanceset.go @@ -0,0 +1,141 @@ +/* +Copyright (C) 2022-2024 ApeCloud Co., Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + "context" + + v1 "github.com/apecloud/kubeblocks/apis/workloads/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + labels "k8s.io/apimachinery/pkg/labels" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + testing "k8s.io/client-go/testing" +) + +// FakeInstanceSets implements InstanceSetInterface +type FakeInstanceSets struct { + Fake *FakeWorkloadsV1 + ns string +} + +var instancesetsResource = v1.SchemeGroupVersion.WithResource("instancesets") + +var instancesetsKind = v1.SchemeGroupVersion.WithKind("InstanceSet") + +// Get takes name of the instanceSet, and returns the corresponding instanceSet object, and an error if there is any. +func (c *FakeInstanceSets) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.InstanceSet, err error) { + obj, err := c.Fake. + Invokes(testing.NewGetAction(instancesetsResource, c.ns, name), &v1.InstanceSet{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.InstanceSet), err +} + +// List takes label and field selectors, and returns the list of InstanceSets that match those selectors. +func (c *FakeInstanceSets) List(ctx context.Context, opts metav1.ListOptions) (result *v1.InstanceSetList, err error) { + obj, err := c.Fake. + Invokes(testing.NewListAction(instancesetsResource, instancesetsKind, c.ns, opts), &v1.InstanceSetList{}) + + if obj == nil { + return nil, err + } + + label, _, _ := testing.ExtractFromListOptions(opts) + if label == nil { + label = labels.Everything() + } + list := &v1.InstanceSetList{ListMeta: obj.(*v1.InstanceSetList).ListMeta} + for _, item := range obj.(*v1.InstanceSetList).Items { + if label.Matches(labels.Set(item.Labels)) { + list.Items = append(list.Items, item) + } + } + return list, err +} + +// Watch returns a watch.Interface that watches the requested instanceSets. +func (c *FakeInstanceSets) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { + return c.Fake. + InvokesWatch(testing.NewWatchAction(instancesetsResource, c.ns, opts)) + +} + +// Create takes the representation of a instanceSet and creates it. Returns the server's representation of the instanceSet, and an error, if there is any. +func (c *FakeInstanceSets) Create(ctx context.Context, instanceSet *v1.InstanceSet, opts metav1.CreateOptions) (result *v1.InstanceSet, err error) { + obj, err := c.Fake. + Invokes(testing.NewCreateAction(instancesetsResource, c.ns, instanceSet), &v1.InstanceSet{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.InstanceSet), err +} + +// Update takes the representation of a instanceSet and updates it. Returns the server's representation of the instanceSet, and an error, if there is any. +func (c *FakeInstanceSets) Update(ctx context.Context, instanceSet *v1.InstanceSet, opts metav1.UpdateOptions) (result *v1.InstanceSet, err error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateAction(instancesetsResource, c.ns, instanceSet), &v1.InstanceSet{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.InstanceSet), err +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *FakeInstanceSets) UpdateStatus(ctx context.Context, instanceSet *v1.InstanceSet, opts metav1.UpdateOptions) (*v1.InstanceSet, error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateSubresourceAction(instancesetsResource, "status", c.ns, instanceSet), &v1.InstanceSet{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.InstanceSet), err +} + +// Delete takes name of the instanceSet and deletes it. Returns an error if one occurs. +func (c *FakeInstanceSets) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { + _, err := c.Fake. + Invokes(testing.NewDeleteActionWithOptions(instancesetsResource, c.ns, name, opts), &v1.InstanceSet{}) + + return err +} + +// DeleteCollection deletes a collection of objects. +func (c *FakeInstanceSets) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { + action := testing.NewDeleteCollectionAction(instancesetsResource, c.ns, listOpts) + + _, err := c.Fake.Invokes(action, &v1.InstanceSetList{}) + return err +} + +// Patch applies the patch and returns the patched instanceSet. +func (c *FakeInstanceSets) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.InstanceSet, err error) { + obj, err := c.Fake. + Invokes(testing.NewPatchSubresourceAction(instancesetsResource, c.ns, name, pt, data, subresources...), &v1.InstanceSet{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.InstanceSet), err +} diff --git a/pkg/client/clientset/versioned/typed/workloads/v1/fake/fake_workloads_client.go b/pkg/client/clientset/versioned/typed/workloads/v1/fake/fake_workloads_client.go new file mode 100644 index 00000000000..afbfc458495 --- /dev/null +++ b/pkg/client/clientset/versioned/typed/workloads/v1/fake/fake_workloads_client.go @@ -0,0 +1,40 @@ +/* +Copyright (C) 2022-2024 ApeCloud Co., Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + v1 "github.com/apecloud/kubeblocks/pkg/client/clientset/versioned/typed/workloads/v1" + rest "k8s.io/client-go/rest" + testing "k8s.io/client-go/testing" +) + +type FakeWorkloadsV1 struct { + *testing.Fake +} + +func (c *FakeWorkloadsV1) InstanceSets(namespace string) v1.InstanceSetInterface { + return &FakeInstanceSets{c, namespace} +} + +// RESTClient returns a RESTClient that is used to communicate +// with API server by this client implementation. +func (c *FakeWorkloadsV1) RESTClient() rest.Interface { + var ret *rest.RESTClient + return ret +} diff --git a/pkg/client/clientset/versioned/typed/workloads/v1/generated_expansion.go b/pkg/client/clientset/versioned/typed/workloads/v1/generated_expansion.go new file mode 100644 index 00000000000..6694e8e5dfd --- /dev/null +++ b/pkg/client/clientset/versioned/typed/workloads/v1/generated_expansion.go @@ -0,0 +1,21 @@ +/* +Copyright (C) 2022-2024 ApeCloud Co., Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1 + +type InstanceSetExpansion interface{} diff --git a/pkg/client/clientset/versioned/typed/workloads/v1/instanceset.go b/pkg/client/clientset/versioned/typed/workloads/v1/instanceset.go new file mode 100644 index 00000000000..7b53982d822 --- /dev/null +++ b/pkg/client/clientset/versioned/typed/workloads/v1/instanceset.go @@ -0,0 +1,195 @@ +/* +Copyright (C) 2022-2024 ApeCloud Co., Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1 + +import ( + "context" + "time" + + v1 "github.com/apecloud/kubeblocks/apis/workloads/v1" + scheme "github.com/apecloud/kubeblocks/pkg/client/clientset/versioned/scheme" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + rest "k8s.io/client-go/rest" +) + +// InstanceSetsGetter has a method to return a InstanceSetInterface. +// A group's client should implement this interface. +type InstanceSetsGetter interface { + InstanceSets(namespace string) InstanceSetInterface +} + +// InstanceSetInterface has methods to work with InstanceSet resources. +type InstanceSetInterface interface { + Create(ctx context.Context, instanceSet *v1.InstanceSet, opts metav1.CreateOptions) (*v1.InstanceSet, error) + Update(ctx context.Context, instanceSet *v1.InstanceSet, opts metav1.UpdateOptions) (*v1.InstanceSet, error) + UpdateStatus(ctx context.Context, instanceSet *v1.InstanceSet, opts metav1.UpdateOptions) (*v1.InstanceSet, error) + Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error + Get(ctx context.Context, name string, opts metav1.GetOptions) (*v1.InstanceSet, error) + List(ctx context.Context, opts metav1.ListOptions) (*v1.InstanceSetList, error) + Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.InstanceSet, err error) + InstanceSetExpansion +} + +// instanceSets implements InstanceSetInterface +type instanceSets struct { + client rest.Interface + ns string +} + +// newInstanceSets returns a InstanceSets +func newInstanceSets(c *WorkloadsV1Client, namespace string) *instanceSets { + return &instanceSets{ + client: c.RESTClient(), + ns: namespace, + } +} + +// Get takes name of the instanceSet, and returns the corresponding instanceSet object, and an error if there is any. +func (c *instanceSets) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.InstanceSet, err error) { + result = &v1.InstanceSet{} + err = c.client.Get(). + Namespace(c.ns). + Resource("instancesets"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(ctx). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of InstanceSets that match those selectors. +func (c *instanceSets) List(ctx context.Context, opts metav1.ListOptions) (result *v1.InstanceSetList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1.InstanceSetList{} + err = c.client.Get(). + Namespace(c.ns). + Resource("instancesets"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(ctx). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested instanceSets. +func (c *instanceSets) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + opts.Watch = true + return c.client.Get(). + Namespace(c.ns). + Resource("instancesets"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch(ctx) +} + +// Create takes the representation of a instanceSet and creates it. Returns the server's representation of the instanceSet, and an error, if there is any. +func (c *instanceSets) Create(ctx context.Context, instanceSet *v1.InstanceSet, opts metav1.CreateOptions) (result *v1.InstanceSet, err error) { + result = &v1.InstanceSet{} + err = c.client.Post(). + Namespace(c.ns). + Resource("instancesets"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(instanceSet). + Do(ctx). + Into(result) + return +} + +// Update takes the representation of a instanceSet and updates it. Returns the server's representation of the instanceSet, and an error, if there is any. +func (c *instanceSets) Update(ctx context.Context, instanceSet *v1.InstanceSet, opts metav1.UpdateOptions) (result *v1.InstanceSet, err error) { + result = &v1.InstanceSet{} + err = c.client.Put(). + Namespace(c.ns). + Resource("instancesets"). + Name(instanceSet.Name). + VersionedParams(&opts, scheme.ParameterCodec). + Body(instanceSet). + Do(ctx). + Into(result) + return +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *instanceSets) UpdateStatus(ctx context.Context, instanceSet *v1.InstanceSet, opts metav1.UpdateOptions) (result *v1.InstanceSet, err error) { + result = &v1.InstanceSet{} + err = c.client.Put(). + Namespace(c.ns). + Resource("instancesets"). + Name(instanceSet.Name). + SubResource("status"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(instanceSet). + Do(ctx). + Into(result) + return +} + +// Delete takes name of the instanceSet and deletes it. Returns an error if one occurs. +func (c *instanceSets) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { + return c.client.Delete(). + Namespace(c.ns). + Resource("instancesets"). + Name(name). + Body(&opts). + Do(ctx). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *instanceSets) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { + var timeout time.Duration + if listOpts.TimeoutSeconds != nil { + timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Namespace(c.ns). + Resource("instancesets"). + VersionedParams(&listOpts, scheme.ParameterCodec). + Timeout(timeout). + Body(&opts). + Do(ctx). + Error() +} + +// Patch applies the patch and returns the patched instanceSet. +func (c *instanceSets) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.InstanceSet, err error) { + result = &v1.InstanceSet{} + err = c.client.Patch(pt). + Namespace(c.ns). + Resource("instancesets"). + Name(name). + SubResource(subresources...). + VersionedParams(&opts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} diff --git a/pkg/client/clientset/versioned/typed/workloads/v1/workloads_client.go b/pkg/client/clientset/versioned/typed/workloads/v1/workloads_client.go new file mode 100644 index 00000000000..7f39eb6afcf --- /dev/null +++ b/pkg/client/clientset/versioned/typed/workloads/v1/workloads_client.go @@ -0,0 +1,107 @@ +/* +Copyright (C) 2022-2024 ApeCloud Co., Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1 + +import ( + "net/http" + + v1 "github.com/apecloud/kubeblocks/apis/workloads/v1" + "github.com/apecloud/kubeblocks/pkg/client/clientset/versioned/scheme" + rest "k8s.io/client-go/rest" +) + +type WorkloadsV1Interface interface { + RESTClient() rest.Interface + InstanceSetsGetter +} + +// WorkloadsV1Client is used to interact with features provided by the workloads.kubeblocks.io group. +type WorkloadsV1Client struct { + restClient rest.Interface +} + +func (c *WorkloadsV1Client) InstanceSets(namespace string) InstanceSetInterface { + return newInstanceSets(c, namespace) +} + +// NewForConfig creates a new WorkloadsV1Client for the given config. +// NewForConfig is equivalent to NewForConfigAndClient(c, httpClient), +// where httpClient was generated with rest.HTTPClientFor(c). +func NewForConfig(c *rest.Config) (*WorkloadsV1Client, error) { + config := *c + if err := setConfigDefaults(&config); err != nil { + return nil, err + } + httpClient, err := rest.HTTPClientFor(&config) + if err != nil { + return nil, err + } + return NewForConfigAndClient(&config, httpClient) +} + +// NewForConfigAndClient creates a new WorkloadsV1Client for the given config and http client. +// Note the http client provided takes precedence over the configured transport values. +func NewForConfigAndClient(c *rest.Config, h *http.Client) (*WorkloadsV1Client, error) { + config := *c + if err := setConfigDefaults(&config); err != nil { + return nil, err + } + client, err := rest.RESTClientForConfigAndClient(&config, h) + if err != nil { + return nil, err + } + return &WorkloadsV1Client{client}, nil +} + +// NewForConfigOrDie creates a new WorkloadsV1Client for the given config and +// panics if there is an error in the config. +func NewForConfigOrDie(c *rest.Config) *WorkloadsV1Client { + client, err := NewForConfig(c) + if err != nil { + panic(err) + } + return client +} + +// New creates a new WorkloadsV1Client for the given RESTClient. +func New(c rest.Interface) *WorkloadsV1Client { + return &WorkloadsV1Client{c} +} + +func setConfigDefaults(config *rest.Config) error { + gv := v1.SchemeGroupVersion + config.GroupVersion = &gv + config.APIPath = "/apis" + config.NegotiatedSerializer = scheme.Codecs.WithoutConversion() + + if config.UserAgent == "" { + config.UserAgent = rest.DefaultKubernetesUserAgent() + } + + return nil +} + +// RESTClient returns a RESTClient that is used to communicate +// with API server by this client implementation. +func (c *WorkloadsV1Client) RESTClient() rest.Interface { + if c == nil { + return nil + } + return c.restClient +} diff --git a/pkg/client/informers/externalversions/generic.go b/pkg/client/informers/externalversions/generic.go index 3a4ac3a9eab..b667b3a9fc0 100644 --- a/pkg/client/informers/externalversions/generic.go +++ b/pkg/client/informers/externalversions/generic.go @@ -26,6 +26,7 @@ import ( v1beta1 "github.com/apecloud/kubeblocks/apis/apps/v1beta1" dataprotectionv1alpha1 "github.com/apecloud/kubeblocks/apis/dataprotection/v1alpha1" extensionsv1alpha1 "github.com/apecloud/kubeblocks/apis/extensions/v1alpha1" + workloadsv1 "github.com/apecloud/kubeblocks/apis/workloads/v1" workloadsv1alpha1 "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1" schema "k8s.io/apimachinery/pkg/runtime/schema" cache "k8s.io/client-go/tools/cache" @@ -117,6 +118,10 @@ func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource case extensionsv1alpha1.SchemeGroupVersion.WithResource("addons"): return &genericInformer{resource: resource.GroupResource(), informer: f.Extensions().V1alpha1().Addons().Informer()}, nil + // Group=workloads.kubeblocks.io, Version=v1 + case workloadsv1.SchemeGroupVersion.WithResource("instancesets"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Workloads().V1().InstanceSets().Informer()}, nil + // Group=workloads.kubeblocks.io, Version=v1alpha1 case workloadsv1alpha1.SchemeGroupVersion.WithResource("instancesets"): return &genericInformer{resource: resource.GroupResource(), informer: f.Workloads().V1alpha1().InstanceSets().Informer()}, nil diff --git a/pkg/client/informers/externalversions/workloads/interface.go b/pkg/client/informers/externalversions/workloads/interface.go index 06c1050507d..0cddbd504a1 100644 --- a/pkg/client/informers/externalversions/workloads/interface.go +++ b/pkg/client/informers/externalversions/workloads/interface.go @@ -20,6 +20,7 @@ package workloads import ( internalinterfaces "github.com/apecloud/kubeblocks/pkg/client/informers/externalversions/internalinterfaces" + v1 "github.com/apecloud/kubeblocks/pkg/client/informers/externalversions/workloads/v1" v1alpha1 "github.com/apecloud/kubeblocks/pkg/client/informers/externalversions/workloads/v1alpha1" ) @@ -27,6 +28,8 @@ import ( type Interface interface { // V1alpha1 provides access to shared informers for resources in V1alpha1. V1alpha1() v1alpha1.Interface + // V1 provides access to shared informers for resources in V1. + V1() v1.Interface } type group struct { @@ -44,3 +47,8 @@ func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakList func (g *group) V1alpha1() v1alpha1.Interface { return v1alpha1.New(g.factory, g.namespace, g.tweakListOptions) } + +// V1 returns a new v1.Interface. +func (g *group) V1() v1.Interface { + return v1.New(g.factory, g.namespace, g.tweakListOptions) +} diff --git a/pkg/client/informers/externalversions/workloads/v1/instanceset.go b/pkg/client/informers/externalversions/workloads/v1/instanceset.go new file mode 100644 index 00000000000..c84bc24e168 --- /dev/null +++ b/pkg/client/informers/externalversions/workloads/v1/instanceset.go @@ -0,0 +1,90 @@ +/* +Copyright (C) 2022-2024 ApeCloud Co., Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1 + +import ( + "context" + time "time" + + workloadsv1 "github.com/apecloud/kubeblocks/apis/workloads/v1" + versioned "github.com/apecloud/kubeblocks/pkg/client/clientset/versioned" + internalinterfaces "github.com/apecloud/kubeblocks/pkg/client/informers/externalversions/internalinterfaces" + v1 "github.com/apecloud/kubeblocks/pkg/client/listers/workloads/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + cache "k8s.io/client-go/tools/cache" +) + +// InstanceSetInformer provides access to a shared informer and lister for +// InstanceSets. +type InstanceSetInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1.InstanceSetLister +} + +type instanceSetInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewInstanceSetInformer constructs a new informer for InstanceSet type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewInstanceSetInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredInstanceSetInformer(client, namespace, resyncPeriod, indexers, nil) +} + +// NewFilteredInstanceSetInformer constructs a new informer for InstanceSet type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredInstanceSetInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.WorkloadsV1().InstanceSets(namespace).List(context.TODO(), options) + }, + WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.WorkloadsV1().InstanceSets(namespace).Watch(context.TODO(), options) + }, + }, + &workloadsv1.InstanceSet{}, + resyncPeriod, + indexers, + ) +} + +func (f *instanceSetInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredInstanceSetInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *instanceSetInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&workloadsv1.InstanceSet{}, f.defaultInformer) +} + +func (f *instanceSetInformer) Lister() v1.InstanceSetLister { + return v1.NewInstanceSetLister(f.Informer().GetIndexer()) +} diff --git a/pkg/client/informers/externalversions/workloads/v1/interface.go b/pkg/client/informers/externalversions/workloads/v1/interface.go new file mode 100644 index 00000000000..b35825ba49b --- /dev/null +++ b/pkg/client/informers/externalversions/workloads/v1/interface.go @@ -0,0 +1,45 @@ +/* +Copyright (C) 2022-2024 ApeCloud Co., Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1 + +import ( + internalinterfaces "github.com/apecloud/kubeblocks/pkg/client/informers/externalversions/internalinterfaces" +) + +// Interface provides access to all the informers in this group version. +type Interface interface { + // InstanceSets returns a InstanceSetInformer. + InstanceSets() InstanceSetInformer +} + +type version struct { + factory internalinterfaces.SharedInformerFactory + namespace string + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// New returns a new Interface. +func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { + return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} +} + +// InstanceSets returns a InstanceSetInformer. +func (v *version) InstanceSets() InstanceSetInformer { + return &instanceSetInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +} diff --git a/pkg/client/listers/workloads/v1/expansion_generated.go b/pkg/client/listers/workloads/v1/expansion_generated.go new file mode 100644 index 00000000000..99daeb5158c --- /dev/null +++ b/pkg/client/listers/workloads/v1/expansion_generated.go @@ -0,0 +1,27 @@ +/* +Copyright (C) 2022-2024 ApeCloud Co., Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1 + +// InstanceSetListerExpansion allows custom methods to be added to +// InstanceSetLister. +type InstanceSetListerExpansion interface{} + +// InstanceSetNamespaceListerExpansion allows custom methods to be added to +// InstanceSetNamespaceLister. +type InstanceSetNamespaceListerExpansion interface{} diff --git a/pkg/client/listers/workloads/v1/instanceset.go b/pkg/client/listers/workloads/v1/instanceset.go new file mode 100644 index 00000000000..9adad56ad56 --- /dev/null +++ b/pkg/client/listers/workloads/v1/instanceset.go @@ -0,0 +1,99 @@ +/* +Copyright (C) 2022-2024 ApeCloud Co., Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1 + +import ( + v1 "github.com/apecloud/kubeblocks/apis/workloads/v1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// InstanceSetLister helps list InstanceSets. +// All objects returned here must be treated as read-only. +type InstanceSetLister interface { + // List lists all InstanceSets in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1.InstanceSet, err error) + // InstanceSets returns an object that can list and get InstanceSets. + InstanceSets(namespace string) InstanceSetNamespaceLister + InstanceSetListerExpansion +} + +// instanceSetLister implements the InstanceSetLister interface. +type instanceSetLister struct { + indexer cache.Indexer +} + +// NewInstanceSetLister returns a new InstanceSetLister. +func NewInstanceSetLister(indexer cache.Indexer) InstanceSetLister { + return &instanceSetLister{indexer: indexer} +} + +// List lists all InstanceSets in the indexer. +func (s *instanceSetLister) List(selector labels.Selector) (ret []*v1.InstanceSet, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1.InstanceSet)) + }) + return ret, err +} + +// InstanceSets returns an object that can list and get InstanceSets. +func (s *instanceSetLister) InstanceSets(namespace string) InstanceSetNamespaceLister { + return instanceSetNamespaceLister{indexer: s.indexer, namespace: namespace} +} + +// InstanceSetNamespaceLister helps list and get InstanceSets. +// All objects returned here must be treated as read-only. +type InstanceSetNamespaceLister interface { + // List lists all InstanceSets in the indexer for a given namespace. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1.InstanceSet, err error) + // Get retrieves the InstanceSet from the indexer for a given namespace and name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1.InstanceSet, error) + InstanceSetNamespaceListerExpansion +} + +// instanceSetNamespaceLister implements the InstanceSetNamespaceLister +// interface. +type instanceSetNamespaceLister struct { + indexer cache.Indexer + namespace string +} + +// List lists all InstanceSets in the indexer for a given namespace. +func (s instanceSetNamespaceLister) List(selector labels.Selector) (ret []*v1.InstanceSet, err error) { + err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { + ret = append(ret, m.(*v1.InstanceSet)) + }) + return ret, err +} + +// Get retrieves the InstanceSet from the indexer for a given namespace and name. +func (s instanceSetNamespaceLister) Get(name string) (*v1.InstanceSet, error) { + obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1.Resource("instanceset"), name) + } + return obj.(*v1.InstanceSet), nil +} diff --git a/pkg/controller/component/lifecycle/suite_test.go b/pkg/controller/component/lifecycle/suite_test.go index 6ce66750dae..541c2ba6798 100644 --- a/pkg/controller/component/lifecycle/suite_test.go +++ b/pkg/controller/component/lifecycle/suite_test.go @@ -38,7 +38,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/log/zap" "sigs.k8s.io/controller-runtime/pkg/metrics/server" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" "github.com/apecloud/kubeblocks/pkg/constant" "github.com/apecloud/kubeblocks/pkg/controller/model" "github.com/apecloud/kubeblocks/pkg/testutil" @@ -58,7 +58,7 @@ var logger logr.Logger func init() { viper.AutomaticEnv() - model.AddScheme(appsv1alpha1.AddToScheme) + model.AddScheme(appsv1.AddToScheme) // viper.Set("ENABLE_DEBUG_LOG", "true") viper.SetDefault(constant.KubernetesClusterDomainEnv, constant.DefaultDNSDomain) @@ -99,7 +99,7 @@ var _ = BeforeSuite(func() { Expect(err).NotTo(HaveOccurred()) Expect(cfg).NotTo(BeNil()) - err = appsv1alpha1.AddToScheme(scheme.Scheme) + err = appsv1.AddToScheme(scheme.Scheme) Expect(err).NotTo(HaveOccurred()) // +kubebuilder:scaffold:scheme diff --git a/pkg/controller/component/suite_test.go b/pkg/controller/component/suite_test.go index a9dae07f2ce..f18af56d10f 100644 --- a/pkg/controller/component/suite_test.go +++ b/pkg/controller/component/suite_test.go @@ -64,8 +64,6 @@ var logger logr.Logger func init() { viper.AutomaticEnv() - model.AddScheme(appsv1alpha1.AddToScheme) - model.AddScheme(appsv1beta1.AddToScheme) model.AddScheme(appsv1.AddToScheme) // viper.Set("ENABLE_DEBUG_LOG", "true") diff --git a/pkg/controller/configuration/suite_test.go b/pkg/controller/configuration/suite_test.go index eaeb8231788..f76029f5864 100644 --- a/pkg/controller/configuration/suite_test.go +++ b/pkg/controller/configuration/suite_test.go @@ -39,6 +39,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/log/zap" "sigs.k8s.io/controller-runtime/pkg/metrics/server" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" appsv1beta1 "github.com/apecloud/kubeblocks/apis/apps/v1beta1" dpv1alpha1 "github.com/apecloud/kubeblocks/apis/dataprotection/v1alpha1" @@ -105,6 +106,9 @@ var _ = BeforeSuite(func() { err = appsv1beta1.AddToScheme(scheme.Scheme) Expect(err).NotTo(HaveOccurred()) + err = appsv1.AddToScheme(scheme.Scheme) + Expect(err).NotTo(HaveOccurred()) + err = dpv1alpha1.AddToScheme(scheme.Scheme) Expect(err).NotTo(HaveOccurred()) diff --git a/pkg/controller/factory/suite_test.go b/pkg/controller/factory/suite_test.go index 9ff180b2824..b46a18c88fe 100644 --- a/pkg/controller/factory/suite_test.go +++ b/pkg/controller/factory/suite_test.go @@ -41,6 +41,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/log/zap" "sigs.k8s.io/controller-runtime/pkg/metrics/server" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" appsv1beta1 "github.com/apecloud/kubeblocks/apis/apps/v1beta1" dpv1alpha1 "github.com/apecloud/kubeblocks/apis/dataprotection/v1alpha1" @@ -105,6 +106,9 @@ var _ = BeforeSuite(func() { err = appsv1beta1.AddToScheme(scheme.Scheme) Expect(err).NotTo(HaveOccurred()) + err = appsv1.AddToScheme(scheme.Scheme) + Expect(err).NotTo(HaveOccurred()) + err = dpv1alpha1.AddToScheme(scheme.Scheme) Expect(err).NotTo(HaveOccurred()) diff --git a/pkg/controller/job/suite_test.go b/pkg/controller/job/suite_test.go index 8ff50e2fd4a..1069151f8cb 100644 --- a/pkg/controller/job/suite_test.go +++ b/pkg/controller/job/suite_test.go @@ -39,8 +39,8 @@ import ( "sigs.k8s.io/controller-runtime/pkg/log/zap" "sigs.k8s.io/controller-runtime/pkg/metrics/server" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" - appsv1beta1 "github.com/apecloud/kubeblocks/apis/apps/v1beta1" dpv1alpha1 "github.com/apecloud/kubeblocks/apis/dataprotection/v1alpha1" "github.com/apecloud/kubeblocks/pkg/controller/model" intctrlutil "github.com/apecloud/kubeblocks/pkg/controllerutil" @@ -62,8 +62,7 @@ var logger logr.Logger func init() { viper.AutomaticEnv() - model.AddScheme(appsv1alpha1.AddToScheme) - model.AddScheme(appsv1beta1.AddToScheme) + model.AddScheme(appsv1.AddToScheme) // viper.Set("ENABLE_DEBUG_LOG", "true") } @@ -105,7 +104,7 @@ var _ = BeforeSuite(func() { err = appsv1alpha1.AddToScheme(scheme.Scheme) Expect(err).NotTo(HaveOccurred()) - err = appsv1beta1.AddToScheme(scheme.Scheme) + err = appsv1.AddToScheme(scheme.Scheme) Expect(err).NotTo(HaveOccurred()) err = dpv1alpha1.AddToScheme(scheme.Scheme) diff --git a/pkg/controller/plan/restore.go b/pkg/controller/plan/restore.go index 97c7b363370..e76b0455271 100644 --- a/pkg/controller/plan/restore.go +++ b/pkg/controller/plan/restore.go @@ -309,7 +309,7 @@ func (r *RestoreManager) buildSchedulingSpec(comp *component.SynthesizedComponen compSpec = r.Cluster.Spec.GetComponentByName(comp.Name) } schedulingPolicy, err := scheduling.BuildSchedulingPolicy(r.Cluster, compSpec) - if err != nil { + if err != nil || schedulingPolicy == nil { return dpv1alpha1.SchedulingSpec{}, err } return dpv1alpha1.SchedulingSpec{ diff --git a/pkg/controller/plan/suite_test.go b/pkg/controller/plan/suite_test.go index 435f9626bc8..af72c0ff9a3 100644 --- a/pkg/controller/plan/suite_test.go +++ b/pkg/controller/plan/suite_test.go @@ -39,6 +39,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/log/zap" "sigs.k8s.io/controller-runtime/pkg/metrics/server" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" appsv1beta1 "github.com/apecloud/kubeblocks/apis/apps/v1beta1" dpv1alpha1 "github.com/apecloud/kubeblocks/apis/dataprotection/v1alpha1" @@ -105,6 +106,9 @@ var _ = BeforeSuite(func() { err = appsv1beta1.AddToScheme(scheme.Scheme) Expect(err).NotTo(HaveOccurred()) + err = appsv1.AddToScheme(scheme.Scheme) + Expect(err).NotTo(HaveOccurred()) + err = dpv1alpha1.AddToScheme(scheme.Scheme) Expect(err).NotTo(HaveOccurred()) diff --git a/pkg/controllerutil/suite_test.go b/pkg/controllerutil/suite_test.go index 4d85facd9a2..f316d92e526 100644 --- a/pkg/controllerutil/suite_test.go +++ b/pkg/controllerutil/suite_test.go @@ -38,6 +38,7 @@ import ( logf "sigs.k8s.io/controller-runtime/pkg/log" "sigs.k8s.io/controller-runtime/pkg/log/zap" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" appsv1beta1 "github.com/apecloud/kubeblocks/apis/apps/v1beta1" "github.com/apecloud/kubeblocks/pkg/testutil" @@ -103,6 +104,9 @@ var _ = BeforeSuite(func() { err = appsv1beta1.AddToScheme(scheme) Expect(err).NotTo(HaveOccurred()) + err = appsv1.AddToScheme(scheme) + Expect(err).NotTo(HaveOccurred()) + k8sClient, err = client.New(cfg, client.Options{Scheme: scheme}) Expect(err).NotTo(HaveOccurred()) Expect(k8sClient).NotTo(BeNil()) diff --git a/pkg/controllerutil/util.go b/pkg/controllerutil/util.go index 53db5ee6474..e48b68a59b0 100644 --- a/pkg/controllerutil/util.go +++ b/pkg/controllerutil/util.go @@ -26,6 +26,7 @@ import ( gruntime "runtime" "strings" + "github.com/apecloud/kubeblocks/pkg/client/clientset/versioned/scheme" "golang.org/x/exp/slices" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -43,6 +44,15 @@ import ( "github.com/apecloud/kubeblocks/version" ) +var ( + innerScheme = scheme.Scheme +) + +func init() { + appsv1alpha1.AddToScheme(innerScheme) // nolint: errcheck + appsv1.AddToScheme(innerScheme) // nolint: errcheck +} + // GetUncachedObjects returns a list of K8s objects, for these object types, // and their list types, client.Reader will read directly from the API server instead // of the cache, which may not be up-to-date. @@ -142,8 +152,6 @@ func MergeMetadataMaps(originalMap map[string]string, targetMaps ...map[string]s return mergeMap } -var innerScheme, _ = appsv1.SchemeBuilder.Build() - func SetOwnerReference(owner, object metav1.Object) error { return controllerutil.SetOwnerReference(owner, object, innerScheme) } diff --git a/pkg/dataprotection/action/suite_test.go b/pkg/dataprotection/action/suite_test.go index ee8c4e3371b..95c691a95b8 100644 --- a/pkg/dataprotection/action/suite_test.go +++ b/pkg/dataprotection/action/suite_test.go @@ -41,7 +41,6 @@ import ( "sigs.k8s.io/controller-runtime/pkg/log/zap" "sigs.k8s.io/controller-runtime/pkg/metrics/server" - appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" dpv1alpha1 "github.com/apecloud/kubeblocks/apis/dataprotection/v1alpha1" "github.com/apecloud/kubeblocks/pkg/dataprotection/action" "github.com/apecloud/kubeblocks/pkg/testutil" @@ -111,9 +110,6 @@ var _ = BeforeSuite(func() { Expect(err).NotTo(HaveOccurred()) Expect(cfg).NotTo(BeNil()) - err = appsv1alpha1.AddToScheme(scheme.Scheme) - Expect(err).NotTo(HaveOccurred()) - err = vsv1.AddToScheme(scheme.Scheme) Expect(err).NotTo(HaveOccurred()) diff --git a/pkg/dataprotection/backup/suite_test.go b/pkg/dataprotection/backup/suite_test.go index 38e15d8df3e..128d4a89971 100644 --- a/pkg/dataprotection/backup/suite_test.go +++ b/pkg/dataprotection/backup/suite_test.go @@ -41,6 +41,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/log/zap" "sigs.k8s.io/controller-runtime/pkg/metrics/server" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" dpv1alpha1 "github.com/apecloud/kubeblocks/apis/dataprotection/v1alpha1" ctrlutil "github.com/apecloud/kubeblocks/pkg/controllerutil" @@ -104,6 +105,9 @@ var _ = BeforeSuite(func() { err = appsv1alpha1.AddToScheme(scheme.Scheme) Expect(err).NotTo(HaveOccurred()) + err = appsv1.AddToScheme(scheme.Scheme) + Expect(err).NotTo(HaveOccurred()) + err = vsv1.AddToScheme(scheme.Scheme) Expect(err).NotTo(HaveOccurred()) diff --git a/pkg/dataprotection/restore/suite_test.go b/pkg/dataprotection/restore/suite_test.go index 542f0a296cb..cf7840d660f 100644 --- a/pkg/dataprotection/restore/suite_test.go +++ b/pkg/dataprotection/restore/suite_test.go @@ -42,6 +42,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/log/zap" "sigs.k8s.io/controller-runtime/pkg/metrics/server" + appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" dpv1alpha1 "github.com/apecloud/kubeblocks/apis/dataprotection/v1alpha1" ctrlutil "github.com/apecloud/kubeblocks/pkg/controllerutil" @@ -102,15 +103,18 @@ var _ = BeforeSuite(func() { Expect(err).NotTo(HaveOccurred()) Expect(cfg).NotTo(BeNil()) - err = appsv1alpha1.AddToScheme(scheme.Scheme) - Expect(err).NotTo(HaveOccurred()) - err = vsv1.AddToScheme(scheme.Scheme) Expect(err).NotTo(HaveOccurred()) err = corev1.AddToScheme(scheme.Scheme) Expect(err).NotTo(HaveOccurred()) + err = appsv1alpha1.AddToScheme(scheme.Scheme) + Expect(err).NotTo(HaveOccurred()) + + err = appsv1.AddToScheme(scheme.Scheme) + Expect(err).NotTo(HaveOccurred()) + err = dpv1alpha1.AddToScheme(scheme.Scheme) Expect(err).NotTo(HaveOccurred()) From 87249da4592c5f303bb52e06075be9f7157b1bbc Mon Sep 17 00:00:00 2001 From: Leon Date: Fri, 13 Sep 2024 10:21:15 +0800 Subject: [PATCH 14/15] fix lint --- pkg/controller/scheduling/scheduling_utils.go | 1 + 1 file changed, 1 insertion(+) diff --git a/pkg/controller/scheduling/scheduling_utils.go b/pkg/controller/scheduling/scheduling_utils.go index b016eb4f498..b86d2a4d210 100644 --- a/pkg/controller/scheduling/scheduling_utils.go +++ b/pkg/controller/scheduling/scheduling_utils.go @@ -21,6 +21,7 @@ package scheduling import ( "encoding/json" + corev1 "k8s.io/api/core/v1" appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1" From 2b739a5f462adf50155e19761aa15d02b8e85eac Mon Sep 17 00:00:00 2001 From: Leon Date: Fri, 13 Sep 2024 17:02:29 +0800 Subject: [PATCH 15/15] update --- pkg/controller/builder/builder_configuration.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pkg/controller/builder/builder_configuration.go b/pkg/controller/builder/builder_configuration.go index 5dbcf5d3840..2e6ae961da5 100644 --- a/pkg/controller/builder/builder_configuration.go +++ b/pkg/controller/builder/builder_configuration.go @@ -66,6 +66,7 @@ func ToV1ConfigSpec(spec *appsv1alpha1.ComponentConfigSpec) *appsv1.ComponentCon ConfigConstraintRef: spec.ConfigConstraintRef, AsEnvFrom: spec.AsEnvFrom, InjectEnvTo: spec.InjectEnvTo, + AsSecret: spec.AsSecret, } if spec.LegacyRenderedConfigSpec != nil { v1.LegacyRenderedConfigSpec = &appsv1.LegacyRenderedTemplateSpec{ @@ -98,6 +99,7 @@ func ToV1alpha1ConfigSpec(spec *appsv1.ComponentConfigSpec) *appsv1alpha1.Compon ConfigConstraintRef: spec.ConfigConstraintRef, AsEnvFrom: spec.AsEnvFrom, InjectEnvTo: spec.InjectEnvTo, + AsSecret: spec.AsSecret, } if spec.LegacyRenderedConfigSpec != nil { v1.LegacyRenderedConfigSpec = &appsv1alpha1.LegacyRenderedTemplateSpec{