api/doris/v1/doriscluster_util.go (316 lines of code) (raw):

// Licensed to the Apache Software Foundation (ASF) under one // or more contributor license agreements. See the NOTICE file // distributed with this work for additional information // regarding copyright ownership. The ASF licenses this file // to you 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 ( "github.com/apache/doris-operator/pkg/common/utils/metadata" corev1 "k8s.io/api/core/v1" "k8s.io/klog/v2" "strings" ) // the annotation key const ( //ComponentsResourceHash the component hash ComponentResourceHash string = "app.doris.components/hash" FERestartAt string = "apache.doris.fe/restartedAt" BERestartAt string = "apache.doris.be/restartedAt" ) // the labels key const ( // ComponentLabelKey is Kubernetes recommended label key, it represents the component within the architecture ComponentLabelKey string = "app.kubernetes.io/component" // NameLabelKey is Kubernetes recommended label key, it represents the name of the application NameLabelKey string = "app.kubernetes.io/name" DorisClusterLabelKey string = "app.doris.cluster" //OwnerReference list ownerReferences this object OwnerReference string = "app.doris.ownerreference/name" ServiceRoleForCluster string = "app.doris.service/role" ) type ServiceRole string const ( Service_Role_Access ServiceRole = "access" Service_Role_Internal ServiceRole = "internal" ) type ComponentType string const ( Component_FE ComponentType = "fe" Component_BE ComponentType = "be" Component_CN ComponentType = "cn" Component_Broker ComponentType = "broker" ) var DefaultFeElectionNumber int32 = 3 func GenerateExternalServiceName(dcr *DorisCluster, componentType ComponentType) string { switch componentType { case Component_FE: return dcr.Name + "-" + string(Component_FE) + "-service" case Component_CN: return dcr.Name + "-" + string(Component_CN) + "-service" case Component_BE: return dcr.Name + "-" + string(Component_BE) + "-service" case Component_Broker: return dcr.Name + "-" + string(Component_Broker) + "-service" default: return "" } } func GenerateComponentStatefulSetName(dcr *DorisCluster, componentType ComponentType) string { switch componentType { case Component_FE: return feStatefulSetName(dcr) case Component_BE: return beStatefulSetName(dcr) case Component_CN: return cnStatefulSetName(dcr) case Component_Broker: return brokerStatefulSetName(dcr) default: return "" } } func beStatefulSetName(dcr *DorisCluster) string { return dcr.Name + "-" + string(Component_BE) } func cnStatefulSetName(dcr *DorisCluster) string { return dcr.Name + "-" + string(Component_CN) } func feStatefulSetName(dcr *DorisCluster) string { return dcr.Name + "-" + string(Component_FE) } func brokerStatefulSetName(dcr *DorisCluster) string { return dcr.Name + "-" + string(Component_Broker) } func GenerateExternalServiceLabels(dcr *DorisCluster, componentType ComponentType) metadata.Labels { labels := metadata.Labels{} labels[OwnerReference] = dcr.Name labels[ComponentLabelKey] = string(componentType) labels[ServiceRoleForCluster] = string(Service_Role_Access) //once the labels updated, the statefulset will enter into a not reconcile state. //labels.AddLabel(src.Labels) return labels } const ( SEARCH_SERVICE_SUFFIX = "-internal" ) func GenerateInternalCommunicateServiceName(dcr *DorisCluster, componentType ComponentType) string { return dcr.Name + "-" + string(componentType) + SEARCH_SERVICE_SUFFIX } func GenerateInternalServiceLabels(dcr *DorisCluster, componentType ComponentType) metadata.Labels { labels := metadata.Labels{} labels[OwnerReference] = dcr.Name labels[ComponentLabelKey] = string(componentType) labels[ServiceRoleForCluster] = string(Service_Role_Internal) //once the labels updated, the statefulset will enter into a not reconcile state. //labels.AddLabel(src.Labels) return labels } func GenerateServiceSelector(dcr *DorisCluster, componentType ComponentType) metadata.Labels { return GenerateStatefulSetSelector(dcr, componentType) } func GenerateStatefulSetSelector(dcr *DorisCluster, componentType ComponentType) metadata.Labels { switch componentType { case Component_FE: return feStatefulSetSelector(dcr) case Component_BE: return beStatefulSetSelector(dcr) case Component_CN: return cnStatefulSetSelector(dcr) case Component_Broker: return brokerStatefulSetSelector(dcr) default: return metadata.Labels{} } } func feStatefulSetSelector(dcr *DorisCluster) metadata.Labels { labels := metadata.Labels{} labels[OwnerReference] = feStatefulSetName(dcr) labels[ComponentLabelKey] = string(Component_FE) return labels } func cnStatefulSetSelector(dcr *DorisCluster) metadata.Labels { labels := metadata.Labels{} labels[OwnerReference] = cnStatefulSetName(dcr) labels[ComponentLabelKey] = string(Component_CN) return labels } func beStatefulSetSelector(dcr *DorisCluster) metadata.Labels { labels := metadata.Labels{} labels[OwnerReference] = beStatefulSetName(dcr) labels[ComponentLabelKey] = string(Component_BE) return labels } func brokerStatefulSetSelector(dcr *DorisCluster) metadata.Labels { labels := metadata.Labels{} labels[OwnerReference] = brokerStatefulSetName(dcr) labels[ComponentLabelKey] = string(Component_Broker) return labels } func GenerateStatefulSetLabels(dcr *DorisCluster, componentType ComponentType) metadata.Labels { switch componentType { case Component_FE: return feStatefulSetLabels(dcr) case Component_BE: return beStatefulSetLabels(dcr) case Component_CN: return cnStatefulSetLabels(dcr) case Component_Broker: return brokerStatefulSetLabels(dcr) default: return metadata.Labels{} } } func feStatefulSetLabels(dcr *DorisCluster) metadata.Labels { labels := metadata.Labels{} labels[OwnerReference] = dcr.Name labels[ComponentLabelKey] = string(Component_FE) //once the labels updated, the statefulset will enter into a not reconcile state. //labels.AddLabel(src.Labels) return labels } func beStatefulSetLabels(dcr *DorisCluster) metadata.Labels { labels := metadata.Labels{} labels[OwnerReference] = dcr.Name labels[ComponentLabelKey] = string(Component_BE) //once the labels updated, the statefulset will enter into a not reconcile state. //labels.AddLabel(src.Labels) return labels } func cnStatefulSetLabels(dcr *DorisCluster) metadata.Labels { labels := metadata.Labels{} labels[OwnerReference] = dcr.Name labels[ComponentLabelKey] = string(Component_CN) //once the labels updated, the statefulset will enter into a not reconcile state. //labels.AddLabel(src.Labels) return labels } func brokerStatefulSetLabels(dcr *DorisCluster) metadata.Labels { labels := metadata.Labels{} labels[OwnerReference] = dcr.Name labels[ComponentLabelKey] = string(Component_Broker) //once the labels updated, the statefulset will enter into a not reconcile state. //labels.AddLabel(src.Labels) return labels } func GetPodLabels(dcr *DorisCluster, componentType ComponentType) metadata.Labels { switch componentType { case Component_FE: return getFEPodLabels(dcr) case Component_BE: return getBEPodLabels(dcr) case Component_CN: return getCNPodLabels(dcr) case Component_Broker: return getBrokerPodLabels(dcr) default: klog.Infof("GetPodLabels the componentType %s is not supported.", componentType) return metadata.Labels{} } } func getFEPodLabels(dcr *DorisCluster) metadata.Labels { labels := feStatefulSetSelector(dcr) labels.AddLabel(getDefaultLabels(dcr)) labels.AddLabel(dcr.Spec.FeSpec.PodLabels) return labels } func getBEPodLabels(dcr *DorisCluster) metadata.Labels { labels := beStatefulSetSelector(dcr) labels.AddLabel(getDefaultLabels(dcr)) labels.AddLabel(dcr.Spec.BeSpec.PodLabels) return labels } func getCNPodLabels(dcr *DorisCluster) metadata.Labels { labels := cnStatefulSetSelector(dcr) labels.AddLabel(getDefaultLabels(dcr)) labels.AddLabel(dcr.Spec.CnSpec.PodLabels) return labels } func getBrokerPodLabels(dcr *DorisCluster) metadata.Labels { labels := brokerStatefulSetSelector(dcr) labels.AddLabel(getDefaultLabels(dcr)) labels.AddLabel(dcr.Spec.BrokerSpec.PodLabels) return labels } func getDefaultLabels(dcr *DorisCluster) metadata.Labels { labels := metadata.Labels{} labels[DorisClusterLabelKey] = dcr.Name return labels } func GetConfigFEAddrForAccess(dcr *DorisCluster, componentType ComponentType) (string, int) { switch componentType { case Component_FE: return getFEAccessAddrForFEADD(dcr) case Component_BE: return getFEAddrForBackends(dcr) case Component_CN: return getFeAddrForComputeNodes(dcr) case Component_Broker: return getFeAddrForBroker(dcr) default: klog.Infof("GetFEAddrForAccess the componentType %s not supported.", componentType) return "", -1 } } func getFEAccessAddrForFEADD(dcr *DorisCluster) (string, int) { if dcr.Spec.FeSpec != nil && dcr.Spec.FeSpec.FeAddress != nil { if len(dcr.Spec.FeSpec.FeAddress.Endpoints.Address) != 0 { return getEndpointsToString(dcr.Spec.FeSpec.FeAddress.Endpoints) } } return "", -1 } func getEndpointsToString(ep Endpoints) (string, int) { if len(ep.Address) == 0 { return "", -1 } return strings.Join(ep.Address, ","), ep.Port } func getFEAddrForBackends(dcr *DorisCluster) (string, int) { if dcr.Spec.BeSpec != nil && dcr.Spec.BeSpec.FeAddress != nil { if len(dcr.Spec.BeSpec.FeAddress.Endpoints.Address) != 0 { return getEndpointsToString(dcr.Spec.BeSpec.FeAddress.Endpoints) } } return getFEAccessAddrForFEADD(dcr) } func getFeAddrForComputeNodes(dcr *DorisCluster) (string, int) { if dcr.Spec.CnSpec != nil && dcr.Spec.CnSpec.FeAddress != nil { if len(dcr.Spec.CnSpec.FeAddress.Endpoints.Address) != 0 { return getEndpointsToString(dcr.Spec.CnSpec.FeAddress.Endpoints) } } return getFEAccessAddrForFEADD(dcr) } func getFeAddrForBroker(dcr *DorisCluster) (string, int) { if dcr.Spec.BrokerSpec != nil && dcr.Spec.BrokerSpec.FeAddress != nil { if len(dcr.Spec.BrokerSpec.FeAddress.Endpoints.Address) != 0 { return getEndpointsToString(dcr.Spec.BrokerSpec.FeAddress.Endpoints) } } return getFEAccessAddrForFEADD(dcr) } // GetClusterSecret get the cluster's adminuser and password through the cluster management account and password configuration in crd func GetClusterSecret(dcr *DorisCluster, secret *corev1.Secret) (adminUserName, password string) { if secret != nil && secret.Data != nil { return string(secret.Data["username"]), string(secret.Data["password"]) } // AdminUser was deprecated since 1.4.1 if dcr.Spec.AdminUser != nil { return dcr.Spec.AdminUser.Name, dcr.Spec.AdminUser.Password } return "root", "" } func IsReconcilingStatusPhase(c *ComponentStatus) bool { return c.ComponentCondition.Phase == Upgrading || c.ComponentCondition.Phase == Scaling || c.ComponentCondition.Phase == Restarting || c.ComponentCondition.Phase == Reconciling } func (dcr *DorisCluster) GetElectionNumber() int32 { if dcr.Spec.FeSpec.ElectionNumber != nil { return *dcr.Spec.FeSpec.ElectionNumber } return DefaultFeElectionNumber } func GetRestartAnnotationKey(componentType ComponentType) string { var restartAnnotationsKey string switch componentType { case Component_FE: restartAnnotationsKey = FERestartAt case Component_BE: restartAnnotationsKey = BERestartAt default: klog.Infof("GetRestartAnnotationKey the componentType %s is not supported.", componentType) } return restartAnnotationsKey } func (dcr *DorisCluster) GetComponentStatus(componentType ComponentType) *ComponentStatus { switch componentType { case Component_FE: return dcr.Status.FEStatus case Component_BE: return dcr.Status.BEStatus case Component_CN: return &dcr.Status.CnStatus.ComponentStatus case Component_Broker: return dcr.Status.BrokerStatus default: klog.Infof("GetComponentStatus the componentType %s is not supported.", componentType) } return nil }