istio.io/istio@v0.0.0-20240520182934-d79c90f27776/operator/pkg/name/name.go (about) 1 // Copyright Istio Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package name 16 17 import ( 18 "fmt" 19 "strings" 20 21 "istio.io/api/operator/v1alpha1" 22 iop "istio.io/istio/operator/pkg/apis/istio/v1alpha1" 23 "istio.io/istio/operator/pkg/helm" 24 "istio.io/istio/operator/pkg/tpath" 25 ) 26 27 // Kubernetes Kind strings. 28 const ( 29 CRDStr = "CustomResourceDefinition" 30 ClusterRoleStr = "ClusterRole" 31 ClusterRoleBindingStr = "ClusterRoleBinding" 32 CMStr = "ConfigMap" 33 DaemonSetStr = "DaemonSet" 34 DeploymentStr = "Deployment" 35 EndpointStr = "Endpoints" 36 HPAStr = "HorizontalPodAutoscaler" 37 IstioOperator = "IstioOperator" 38 MutatingWebhookConfigurationStr = "MutatingWebhookConfiguration" 39 NamespaceStr = "Namespace" 40 NetworkAttachmentDefinitionStr = "NetworkAttachmentDefinition" 41 PodStr = "Pod" 42 PDBStr = "PodDisruptionBudget" 43 ReplicaSetStr = "ReplicaSet" 44 RoleStr = "Role" 45 RoleBindingStr = "RoleBinding" 46 SAStr = "ServiceAccount" 47 ServiceStr = "Service" 48 SecretStr = "Secret" 49 StatefulSetStr = "StatefulSet" 50 ValidatingWebhookConfigurationStr = "ValidatingWebhookConfiguration" 51 ) 52 53 const ( 54 // IstioOperatorStr is the kind name of the IstioOperator CRD. 55 IstioOperatorStr = "IstioOperator" 56 57 // OperatorAPINamespace is the API namespace for operator config. 58 // TODO: move this to a base definitions file when one is created. 59 OperatorAPINamespace = "operator.istio.io" 60 61 // DefaultProfileName is the name of the default profile. 62 DefaultProfileName = "default" 63 ) 64 65 // ComponentName is a component name string, typed to constrain allowed values. 66 type ComponentName string 67 68 const ( 69 // IstioComponent names corresponding to the IstioOperator proto component names. Must be the same, since these 70 // are used for struct traversal. 71 IstioBaseComponentName ComponentName = "Base" 72 PilotComponentName ComponentName = "Pilot" 73 74 CNIComponentName ComponentName = "Cni" 75 ZtunnelComponentName ComponentName = "Ztunnel" 76 77 // istiod remote component 78 IstiodRemoteComponentName ComponentName = "IstiodRemote" 79 80 // Gateway components 81 IngressComponentName ComponentName = "IngressGateways" 82 EgressComponentName ComponentName = "EgressGateways" 83 84 // Operator components 85 IstioOperatorComponentName ComponentName = "IstioOperator" 86 IstioOperatorCustomResourceName ComponentName = "IstioOperatorCustomResource" 87 ) 88 89 var IstioComponentSuccessIcons = map[ComponentName]string{ 90 IstioBaseComponentName: "⛵️", 91 PilotComponentName: "🧠", 92 CNIComponentName: "🪢", 93 ZtunnelComponentName: "🔒", 94 IngressComponentName: "🛬", 95 EgressComponentName: "🛫", 96 } 97 98 // ComponentNamesConfig is used for unmarshaling legacy and addon naming data. 99 type ComponentNamesConfig struct { 100 DeprecatedComponentNames []string 101 } 102 103 var ( 104 AllCoreComponentNames = []ComponentName{ 105 IstioBaseComponentName, 106 PilotComponentName, 107 CNIComponentName, 108 IstiodRemoteComponentName, 109 ZtunnelComponentName, 110 } 111 112 // AllComponentNames is a list of all Istio components. 113 AllComponentNames = append(AllCoreComponentNames, IngressComponentName, EgressComponentName, 114 IstioOperatorComponentName, IstioOperatorCustomResourceName) 115 116 // ValuesEnablementPathMap defines a mapping between legacy values enablement paths and the corresponding enablement 117 // paths in IstioOperator. 118 ValuesEnablementPathMap = map[string]string{ 119 "spec.values.gateways.istio-ingressgateway.enabled": "spec.components.ingressGateways.[name:istio-ingressgateway].enabled", 120 "spec.values.gateways.istio-egressgateway.enabled": "spec.components.egressGateways.[name:istio-egressgateway].enabled", 121 } 122 123 // userFacingComponentNames are the names of components that are displayed to the user in high level CLIs 124 // (like progress log). 125 userFacingComponentNames = map[ComponentName]string{ 126 IstioBaseComponentName: "Istio core", 127 PilotComponentName: "Istiod", 128 CNIComponentName: "CNI", 129 ZtunnelComponentName: "Ztunnel", 130 IngressComponentName: "Ingress gateways", 131 EgressComponentName: "Egress gateways", 132 IstioOperatorComponentName: "Istio operator", 133 IstioOperatorCustomResourceName: "Istio operator CRDs", 134 IstiodRemoteComponentName: "Istiod remote", 135 } 136 ) 137 138 // Manifest defines a manifest for a component. 139 type Manifest struct { 140 Name ComponentName 141 Content string 142 } 143 144 // ManifestMap is a map of ComponentName to its manifest string. 145 type ManifestMap map[ComponentName][]string 146 147 // Consolidated returns a representation of mm where all manifests in the slice under a key are combined into a single 148 // manifest. 149 func (mm ManifestMap) Consolidated() map[string]string { 150 out := make(map[string]string) 151 for cname, ms := range mm { 152 allM := "" 153 for _, m := range ms { 154 allM += m + helm.YAMLSeparator 155 } 156 out[string(cname)] = allM 157 } 158 return out 159 } 160 161 // MergeManifestSlices merges a slice of manifests into a single manifest string. 162 func MergeManifestSlices(manifests []string) string { 163 return strings.Join(manifests, helm.YAMLSeparator) 164 } 165 166 // String implements the Stringer interface. 167 func (mm ManifestMap) String() string { 168 out := "" 169 for _, ms := range mm { 170 for _, m := range ms { 171 out += m + helm.YAMLSeparator 172 } 173 } 174 return out 175 } 176 177 // IsGateway reports whether cn is a gateway component. 178 func (cn ComponentName) IsGateway() bool { 179 return cn == IngressComponentName || cn == EgressComponentName 180 } 181 182 // Namespace returns the namespace for the component. It follows these rules: 183 // 1. If DefaultNamespace is unset, log and error and return the empty string. 184 // 2. If the feature and component namespaces are unset, return DefaultNamespace. 185 // 3. If the feature namespace is set but component name is unset, return the feature namespace. 186 // 4. Otherwise return the component namespace. 187 // Namespace assumes that controlPlaneSpec has been validated. 188 // TODO: remove extra validations when comfort level is high enough. 189 func Namespace(componentName ComponentName, controlPlaneSpec *v1alpha1.IstioOperatorSpec) (string, error) { 190 defaultNamespace := iop.Namespace(controlPlaneSpec) 191 192 componentNodeI, found, err := tpath.GetFromStructPath(controlPlaneSpec, "Components."+string(componentName)+".Namespace") 193 if err != nil { 194 return "", fmt.Errorf("error in Namespace GetFromStructPath componentNamespace for component=%s: %s", componentName, err) 195 } 196 if !found { 197 return defaultNamespace, nil 198 } 199 if componentNodeI == nil { 200 return defaultNamespace, nil 201 } 202 componentNamespace, ok := componentNodeI.(string) 203 if !ok { 204 return "", fmt.Errorf("component %s enabled has bad type %T, expect string", componentName, componentNodeI) 205 } 206 if componentNamespace == "" { 207 return defaultNamespace, nil 208 } 209 return componentNamespace, nil 210 } 211 212 // TitleCase returns a capitalized version of n. 213 func TitleCase(n ComponentName) ComponentName { 214 s := string(n) 215 return ComponentName(strings.ToUpper(s[0:1]) + s[1:]) 216 } 217 218 // UserFacingComponentName returns the name of the given component that should be displayed to the user in high 219 // level CLIs (like progress log). 220 func UserFacingComponentName(name ComponentName) string { 221 ret, ok := userFacingComponentNames[name] 222 if !ok { 223 return "Unknown" 224 } 225 return ret 226 }