istio.io/istio@v0.0.0-20240520182934-d79c90f27776/operator/pkg/helmreconciler/common.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 helmreconciler
    16  
    17  import (
    18  	"io"
    19  	"strings"
    20  
    21  	"istio.io/istio/operator/pkg/name"
    22  	"istio.io/istio/pkg/log"
    23  )
    24  
    25  const (
    26  	// MetadataNamespace is the namespace for mesh metadata (labels, annotations)
    27  	MetadataNamespace = "install.operator.istio.io"
    28  	// OwningResourceName represents the name of the owner to which the resource relates
    29  	OwningResourceName = MetadataNamespace + "/owning-resource"
    30  	// OwningResourceNamespace represents the namespace of the owner to which the resource relates
    31  	OwningResourceNamespace = MetadataNamespace + "/owning-resource-namespace"
    32  	// OwningResourceNotPruned indicates that the resource should not be pruned during reconciliation cycles,
    33  	// note this will not prevent the resource from being deleted if the owning resource is deleted.
    34  	OwningResourceNotPruned = MetadataNamespace + "/owning-resource-not-pruned"
    35  	// operatorLabelStr indicates Istio operator is managing this resource.
    36  	operatorLabelStr = name.OperatorAPINamespace + "/managed"
    37  	// operatorReconcileStr indicates that the operator will reconcile the resource.
    38  	operatorReconcileStr = "Reconcile"
    39  	// IstioComponentLabelStr indicates which Istio component a resource belongs to.
    40  	IstioComponentLabelStr = name.OperatorAPINamespace + "/component"
    41  	// istioVersionLabelStr indicates the Istio version of the installation.
    42  	istioVersionLabelStr = name.OperatorAPINamespace + "/version"
    43  )
    44  
    45  var (
    46  	// TestMode sets the controller into test mode. Used for unit tests to bypass things like waiting on resources.
    47  	TestMode = false
    48  
    49  	scope = log.RegisterScope("installer", "installer")
    50  )
    51  
    52  func init() {
    53  	// Tree representation and wait channels are an inversion of ComponentDependencies and are constructed from it.
    54  	buildInstallTree()
    55  }
    56  
    57  // ComponentTree represents a tree of component dependencies.
    58  type (
    59  	ComponentTree          map[name.ComponentName]any
    60  	componentNameToListMap map[name.ComponentName][]name.ComponentName
    61  )
    62  
    63  var (
    64  	// ComponentDependencies is a tree of component dependencies. The semantics are ComponentDependencies[cname] gives
    65  	// the subtree of components that must wait for cname to be installed before starting installation themselves.
    66  	ComponentDependencies = componentNameToListMap{
    67  		name.PilotComponentName: {
    68  			name.CNIComponentName,
    69  			name.IngressComponentName,
    70  			name.EgressComponentName,
    71  		},
    72  		name.IstioBaseComponentName: {
    73  			name.PilotComponentName,
    74  		},
    75  		name.CNIComponentName: {
    76  			name.ZtunnelComponentName,
    77  		},
    78  	}
    79  
    80  	// InstallTree is a top down hierarchy tree of dependencies where children must wait for the parent to complete
    81  	// before starting installation.
    82  	InstallTree = make(ComponentTree)
    83  )
    84  
    85  // buildInstallTree builds a tree from buildInstallTree where parents are the root of each subtree.
    86  func buildInstallTree() {
    87  	// Starting with root, recursively insert each first level child into each node.
    88  	insertChildrenRecursive(name.IstioBaseComponentName, InstallTree, ComponentDependencies)
    89  }
    90  
    91  func insertChildrenRecursive(componentName name.ComponentName, tree ComponentTree, children componentNameToListMap) {
    92  	tree[componentName] = make(ComponentTree)
    93  	for _, child := range children[componentName] {
    94  		insertChildrenRecursive(child, tree[componentName].(ComponentTree), children)
    95  	}
    96  }
    97  
    98  // InstallTreeString returns a string representation of the dependency tree.
    99  func InstallTreeString() string {
   100  	var sb strings.Builder
   101  	buildInstallTreeString(name.IstioBaseComponentName, "", &sb)
   102  	return sb.String()
   103  }
   104  
   105  func buildInstallTreeString(componentName name.ComponentName, prefix string, sb io.StringWriter) {
   106  	_, _ = sb.WriteString(prefix + string(componentName) + "\n")
   107  	if _, ok := InstallTree[componentName].(ComponentTree); !ok {
   108  		return
   109  	}
   110  	for k := range InstallTree[componentName].(ComponentTree) {
   111  		buildInstallTreeString(k, prefix+"  ", sb)
   112  	}
   113  }