istio.io/istio@v0.0.0-20240520182934-d79c90f27776/pkg/config/analysis/analyzers/util/proxyconfig.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 util
    16  
    17  import (
    18  	"strings"
    19  
    20  	"istio.io/api/annotation"
    21  	meshconfig "istio.io/api/mesh/v1alpha1"
    22  	"istio.io/api/networking/v1beta1"
    23  	"istio.io/istio/pkg/config/analysis"
    24  	"istio.io/istio/pkg/config/resource"
    25  	"istio.io/istio/pkg/config/schema/gvk"
    26  	"istio.io/istio/pkg/maps"
    27  	"istio.io/istio/pkg/util/protomarshal"
    28  )
    29  
    30  type EffectiveProxyConfigResolver struct {
    31  	meshConfig    *meshconfig.MeshConfig
    32  	rootNamespace string
    33  	root          *v1beta1.ProxyConfig
    34  	namespace     map[string]*v1beta1.ProxyConfig
    35  	workload      map[string]*v1beta1.ProxyConfig
    36  }
    37  
    38  // ImageType returns the effective image type for the given pod.
    39  func (e *EffectiveProxyConfigResolver) ImageType(pod *resource.Instance) string {
    40  	variant := ""
    41  	if e.meshConfig.GetDefaultConfig().GetImage().GetImageType() != "" {
    42  		variant = e.meshConfig.GetDefaultConfig().GetImage().GetImageType()
    43  	}
    44  	if e.root.GetImage().GetImageType() != "" {
    45  		variant = e.root.GetImage().GetImageType()
    46  	}
    47  	if v, ok := e.namespace[pod.Metadata.FullName.Namespace.String()]; ok {
    48  		if v.GetImage().GetImageType() != "" {
    49  			variant = v.GetImage().GetImageType()
    50  		}
    51  	}
    52  	// check if there are workload level resources that match the pod
    53  	for k, v := range e.workload {
    54  		if !strings.HasPrefix(k, pod.Metadata.FullName.Namespace.String()) {
    55  			continue
    56  		}
    57  		if maps.Contains(pod.Metadata.Labels, v.GetSelector().GetMatchLabels()) {
    58  			if v.GetImage().GetImageType() != "" {
    59  				variant = v.GetImage().GetImageType()
    60  			}
    61  		}
    62  	}
    63  	if v, ok := pod.Metadata.Annotations[annotation.ProxyConfig.Name]; ok {
    64  		pc := &meshconfig.ProxyConfig{}
    65  		if err := protomarshal.ApplyYAML(v, pc); err == nil {
    66  			if pc.GetImage().GetImageType() != "" {
    67  				variant = pc.GetImage().GetImageType()
    68  			}
    69  		}
    70  	}
    71  	if variant == "default" {
    72  		variant = ""
    73  	}
    74  	return variant
    75  }
    76  
    77  func NewEffectiveProxyConfigResolver(c analysis.Context) *EffectiveProxyConfigResolver {
    78  	mc := &meshconfig.MeshConfig{}
    79  	rootNamespace := ""
    80  	c.ForEach(gvk.MeshConfig, func(r *resource.Instance) bool {
    81  		meshConfig := r.Message.(*meshconfig.MeshConfig)
    82  		rootNamespace = meshConfig.GetRootNamespace()
    83  		if rootNamespace == "" {
    84  			rootNamespace = "istio-system"
    85  		}
    86  		mc = meshConfig
    87  		return true
    88  	})
    89  
    90  	resolver := &EffectiveProxyConfigResolver{
    91  		meshConfig:    mc,
    92  		rootNamespace: rootNamespace,
    93  		namespace:     make(map[string]*v1beta1.ProxyConfig),
    94  		workload:      make(map[string]*v1beta1.ProxyConfig),
    95  	}
    96  
    97  	c.ForEach(gvk.ProxyConfig, func(r *resource.Instance) bool {
    98  		proxyConfig := r.Message.(*v1beta1.ProxyConfig)
    99  		if r.Metadata.FullName.Namespace.String() == resolver.rootNamespace {
   100  			resolver.root = proxyConfig
   101  			return true
   102  		}
   103  		if proxyConfig.GetSelector() == nil {
   104  			resolver.namespace[r.Metadata.FullName.Namespace.String()] = proxyConfig
   105  		} else {
   106  			resolver.workload[r.Metadata.FullName.String()] = proxyConfig
   107  		}
   108  		return true
   109  	})
   110  	return resolver
   111  }