github.com/kiali/kiali@v1.84.0/models/istio_config.go (about)

     1  package models
     2  
     3  import (
     4  	extentions_v1alpha1 "istio.io/client-go/pkg/apis/extensions/v1alpha1"
     5  	networking_v1alpha3 "istio.io/client-go/pkg/apis/networking/v1alpha3"
     6  	networking_v1beta1 "istio.io/client-go/pkg/apis/networking/v1beta1"
     7  	security_v1beta "istio.io/client-go/pkg/apis/security/v1beta1"
     8  	"istio.io/client-go/pkg/apis/telemetry/v1alpha1"
     9  	k8s_networking_v1 "sigs.k8s.io/gateway-api/apis/v1"
    10  	k8s_networking_v1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2"
    11  	k8s_networking_v1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1"
    12  )
    13  
    14  // IstioConfigList istioConfigList
    15  // This type is used for returning a response of IstioConfigList
    16  // swagger:model IstioConfigList
    17  type IstioConfigList struct {
    18  	DestinationRules []*networking_v1beta1.DestinationRule `json:"destinationRules"`
    19  	EnvoyFilters     []*networking_v1alpha3.EnvoyFilter    `json:"envoyFilters"`
    20  	Gateways         []*networking_v1beta1.Gateway         `json:"gateways"`
    21  	ServiceEntries   []*networking_v1beta1.ServiceEntry    `json:"serviceEntries"`
    22  	Sidecars         []*networking_v1beta1.Sidecar         `json:"sidecars"`
    23  	VirtualServices  []*networking_v1beta1.VirtualService  `json:"virtualServices"`
    24  	WorkloadEntries  []*networking_v1beta1.WorkloadEntry   `json:"workloadEntries"`
    25  	WorkloadGroups   []*networking_v1beta1.WorkloadGroup   `json:"workloadGroups"`
    26  	WasmPlugins      []*extentions_v1alpha1.WasmPlugin     `json:"wasmPlugins"`
    27  	Telemetries      []*v1alpha1.Telemetry                 `json:"telemetries"`
    28  
    29  	K8sGateways        []*k8s_networking_v1.Gateway             `json:"k8sGateways"`
    30  	K8sGRPCRoutes      []*k8s_networking_v1alpha2.GRPCRoute     `json:"k8sGRPCRoutes"`
    31  	K8sHTTPRoutes      []*k8s_networking_v1.HTTPRoute           `json:"k8sHTTPRoutes"`
    32  	K8sReferenceGrants []*k8s_networking_v1beta1.ReferenceGrant `json:"k8sReferenceGrants"`
    33  	K8sTCPRoutes       []*k8s_networking_v1alpha2.TCPRoute      `json:"k8sTCPRoutes"`
    34  	K8sTLSRoutes       []*k8s_networking_v1alpha2.TLSRoute      `json:"k8sTLSRoutes"`
    35  
    36  	AuthorizationPolicies  []*security_v1beta.AuthorizationPolicy   `json:"authorizationPolicies"`
    37  	PeerAuthentications    []*security_v1beta.PeerAuthentication    `json:"peerAuthentications"`
    38  	RequestAuthentications []*security_v1beta.RequestAuthentication `json:"requestAuthentications"`
    39  	IstioValidations       IstioValidations                         `json:"validations"`
    40  }
    41  
    42  func (i *IstioConfigList) ConvertToResponse() {
    43  	// The frontend blows up when you return a nil array so coercing these to
    44  	// empty before returning them.
    45  
    46  	// There's probably a more clever way of doing this but due to typed nils
    47  	// we can't just put all the slices into a new generic slice as putting
    48  	// them in that slice would cause them to no longer be nil.
    49  	if i.DestinationRules == nil {
    50  		i.DestinationRules = []*networking_v1beta1.DestinationRule{}
    51  	}
    52  	if i.EnvoyFilters == nil {
    53  		i.EnvoyFilters = []*networking_v1alpha3.EnvoyFilter{}
    54  	}
    55  	if i.Gateways == nil {
    56  		i.Gateways = []*networking_v1beta1.Gateway{}
    57  	}
    58  	if i.ServiceEntries == nil {
    59  		i.ServiceEntries = []*networking_v1beta1.ServiceEntry{}
    60  	}
    61  	if i.Sidecars == nil {
    62  		i.Sidecars = []*networking_v1beta1.Sidecar{}
    63  	}
    64  	if i.VirtualServices == nil {
    65  		i.VirtualServices = []*networking_v1beta1.VirtualService{}
    66  	}
    67  	if i.WorkloadEntries == nil {
    68  		i.WorkloadEntries = []*networking_v1beta1.WorkloadEntry{}
    69  	}
    70  	if i.WorkloadGroups == nil {
    71  		i.WorkloadGroups = []*networking_v1beta1.WorkloadGroup{}
    72  	}
    73  	if i.WasmPlugins == nil {
    74  		i.WasmPlugins = []*extentions_v1alpha1.WasmPlugin{}
    75  	}
    76  	if i.Telemetries == nil {
    77  		i.Telemetries = []*v1alpha1.Telemetry{}
    78  	}
    79  
    80  	if i.K8sGateways == nil {
    81  		i.K8sGateways = []*k8s_networking_v1.Gateway{}
    82  	}
    83  	if i.K8sGRPCRoutes == nil {
    84  		i.K8sGRPCRoutes = []*k8s_networking_v1alpha2.GRPCRoute{}
    85  	}
    86  	if i.K8sHTTPRoutes == nil {
    87  		i.K8sHTTPRoutes = []*k8s_networking_v1.HTTPRoute{}
    88  	}
    89  	if i.K8sReferenceGrants == nil {
    90  		i.K8sReferenceGrants = []*k8s_networking_v1beta1.ReferenceGrant{}
    91  	}
    92  	if i.K8sTCPRoutes == nil {
    93  		i.K8sTCPRoutes = []*k8s_networking_v1alpha2.TCPRoute{}
    94  	}
    95  	if i.K8sTLSRoutes == nil {
    96  		i.K8sTLSRoutes = []*k8s_networking_v1alpha2.TLSRoute{}
    97  	}
    98  
    99  	if i.AuthorizationPolicies == nil {
   100  		i.AuthorizationPolicies = []*security_v1beta.AuthorizationPolicy{}
   101  	}
   102  	if i.PeerAuthentications == nil {
   103  		i.PeerAuthentications = []*security_v1beta.PeerAuthentication{}
   104  	}
   105  	if i.RequestAuthentications == nil {
   106  		i.RequestAuthentications = []*security_v1beta.RequestAuthentication{}
   107  	}
   108  }
   109  
   110  // IstioConfigMap holds a map of IstioConfigList per cluster
   111  type IstioConfigMap map[string]IstioConfigList
   112  
   113  type IstioConfigDetails struct {
   114  	Namespace  Namespace `json:"namespace"`
   115  	ObjectType string    `json:"objectType"`
   116  
   117  	AuthorizationPolicy   *security_v1beta.AuthorizationPolicy   `json:"authorizationPolicy"`
   118  	DestinationRule       *networking_v1beta1.DestinationRule    `json:"destinationRule"`
   119  	EnvoyFilter           *networking_v1alpha3.EnvoyFilter       `json:"envoyFilter"`
   120  	Gateway               *networking_v1beta1.Gateway            `json:"gateway"`
   121  	PeerAuthentication    *security_v1beta.PeerAuthentication    `json:"peerAuthentication"`
   122  	RequestAuthentication *security_v1beta.RequestAuthentication `json:"requestAuthentication"`
   123  	ServiceEntry          *networking_v1beta1.ServiceEntry       `json:"serviceEntry"`
   124  	Sidecar               *networking_v1beta1.Sidecar            `json:"sidecar"`
   125  	VirtualService        *networking_v1beta1.VirtualService     `json:"virtualService"`
   126  	WorkloadEntry         *networking_v1beta1.WorkloadEntry      `json:"workloadEntry"`
   127  	WorkloadGroup         *networking_v1beta1.WorkloadGroup      `json:"workloadGroup"`
   128  	WasmPlugin            *extentions_v1alpha1.WasmPlugin        `json:"wasmPlugin"`
   129  	Telemetry             *v1alpha1.Telemetry                    `json:"telemetry"`
   130  
   131  	K8sGateway        *k8s_networking_v1.Gateway             `json:"k8sGateway"`
   132  	K8sGRPCRoute      *k8s_networking_v1alpha2.GRPCRoute     `json:"k8sGRPCRoute"`
   133  	K8sHTTPRoute      *k8s_networking_v1.HTTPRoute           `json:"k8sHTTPRoute"`
   134  	K8sReferenceGrant *k8s_networking_v1beta1.ReferenceGrant `json:"k8sReferenceGrant"`
   135  	K8sTCPRoute       *k8s_networking_v1alpha2.TCPRoute      `json:"k8sTCPRoute"`
   136  	K8sTLSRoute       *k8s_networking_v1alpha2.TLSRoute      `json:"k8sTLSRoute"`
   137  
   138  	Permissions           ResourcePermissions `json:"permissions"`
   139  	IstioValidation       *IstioValidation    `json:"validation"`
   140  	IstioReferences       *IstioReferences    `json:"references"`
   141  	IstioConfigHelpFields []IstioConfigHelp   `json:"help"`
   142  }
   143  
   144  // IstioConfigHelp represents a help message for a given Istio object type and field
   145  type IstioConfigHelp struct {
   146  	ObjectField string `json:"objectField"`
   147  	Message     string `json:"message"`
   148  }
   149  
   150  // IstioConfigHelpMessages represents the help messages for a given Istio object type
   151  var IstioConfigHelpMessages = map[string][]IstioConfigHelp{
   152  	"authorizationpolicies": {
   153  		{ObjectField: "spec.selector", Message: "Optional. The selector decides where to apply the authorization policy. The selector will match with workloads in the same namespace as the authorization policy. If the authorization policy is in the root namespace, the selector will additionally match with workloads in all namespaces."},
   154  		{ObjectField: "spec.selector.matchLabels", Message: "One or more labels that indicate a specific set of pods/VMs on which a policy should be applied."},
   155  		{ObjectField: "spec.rules", Message: "Optional. A list of rules to match the request. A match occurs when at least one rule matches the request."},
   156  		{ObjectField: "spec.rules.from", Message: "Optional. from specifies the source of a request. If not set, any source is allowed."},
   157  		{ObjectField: "spec.rules.from.source.principals", Message: "Optional. A list of peer identities derived from the peer certificate. If not set, any principal is allowed."},
   158  		{ObjectField: "spec.rules.to", Message: "Optional. to specifies the operation of a request. If not set, any operation is allowed."},
   159  		{ObjectField: "spec.rules.when", Message: "Optional. when specifies a list of additional conditions of a request. If not set, any condition is allowed."},
   160  		{ObjectField: "spec.action", Message: "Optional. The action to take if the request is matched with the rules. Default is ALLOW if not specified."},
   161  	},
   162  	"destinationrules": {
   163  		{ObjectField: "spec.host", Message: "The name of a service from the service registry. Rules defined for services that do not exist in the service registry will be ignored."},
   164  		{ObjectField: "spec.trafficPolicy", Message: "Traffic policies to apply (load balancing policy, connection pool sizes, outlier detection)."},
   165  		{ObjectField: "spec.subsets", Message: "One or more named sets that represent individual versions of a service. Traffic policies can be overridden at subset level."},
   166  		{ObjectField: "spec.exportTo", Message: "A list of namespaces to which this destination rule is exported. The resolution of a destination rule to apply to a service occurs in the context of a hierarchy of namespaces. This feature provides a mechanism for service owners and mesh administrators to control the visibility of destination rules across namespace boundaries. If no namespaces are specified then the destination rule is exported to all namespaces by default."},
   167  	},
   168  	"envoyfilters": {
   169  		{ObjectField: "spec.workloadSelector", Message: "Criteria used to select the specific set of pods/VMs on which this patch configuration should be applied. If omitted, the set of patches in this configuration will be applied to all workload instances in the same namespace."},
   170  		{ObjectField: "spec.configPatches", Message: "One or more patches with match conditions."},
   171  		{ObjectField: "spec.configPatches.applyTo", Message: "Specifies where in the Envoy configuration, the patch should be applied."},
   172  		{ObjectField: "spec.configPatches.match", Message: "Match on listener/route configuration/cluster."},
   173  		{ObjectField: "spec.configPatches.patch", Message: "The patch to apply along with the operation."},
   174  		{ObjectField: "spec.priority", Message: "riority defines the order in which patch sets are applied within a context. When one patch depends on another patch, the order of patch application is significant."},
   175  	},
   176  	"gateways": {
   177  		{ObjectField: "spec.servers", Message: "A list of server specifications."},
   178  		{ObjectField: "spec.selector", Message: "One or more labels that indicate a specific set of pods/VMs on which this gateway configuration should be applied. By default workloads are searched across all namespaces based on label selectors."},
   179  		{ObjectField: "spec.servers.port", Message: "The port on which the proxy should listen for incoming connections."},
   180  		{ObjectField: "spec.servers.hosts", Message: "One or more hosts exposed by this gateway. While typically applicable to HTTP services, it can also be used for TCP services using TLS with SNI."},
   181  		{ObjectField: "spec.servers.tls", Message: "Set of TLS related options that govern the server’s behavior. Use these options to control if all http requests should be redirected to https, and the TLS modes to use."},
   182  	},
   183  	"sidecars": {
   184  		{ObjectField: "spec.workloadSelector", Message: "Criteria used to select the specific set of pods/VMs on which this Sidecar configuration should be applied. If omitted, the Sidecar configuration will be applied to all workload instances in the same namespace."},
   185  		{ObjectField: "spec.ingress", Message: "Ingress specifies the configuration of the sidecar for processing inbound traffic to the attached workload instance."},
   186  		{ObjectField: "spec.egress", Message: "Egress specifies the configuration of the sidecar for processing outbound traffic from the attached workload instance to other services in the mesh"},
   187  	},
   188  	"peerauthentications": {
   189  		{ObjectField: "spec.selector", Message: "The selector determines the workloads to apply the ChannelAuthentication on. If not set, the policy will be applied to all workloads in the same namespace as the policy."},
   190  		{ObjectField: "spec.selector.matchLabels", Message: "One or more labels that indicate a specific set of pods/VMs on which a policy should be applied."},
   191  		{ObjectField: "spec.mtls", Message: "Mutual TLS settings for workload. If not defined, inherit from parent."},
   192  	},
   193  	"requestauthentications": {
   194  		{ObjectField: "spec.selector", Message: "Optional. The selector decides where to apply the request authentication policy. The selector will match with workloads in the same namespace as the request authentication policy. If the request authentication policy is in the root namespace, the selector will additionally match with workloads in all namespaces."},
   195  		{ObjectField: "spec.selector.matchLabels", Message: "One or more labels that indicate a specific set of pods/VMs on which a policy should be applied."},
   196  		{ObjectField: "spec.jwtRules", Message: "Define the list of JWTs that can be validated at the selected workloads’ proxy. A valid token will be used to extract the authenticated identity."},
   197  	},
   198  	"serviceentries": {
   199  		{ObjectField: "spec.hosts", Message: "The hosts associated with the ServiceEntry. Could be a DNS name with wildcard prefix."},
   200  		{ObjectField: "spec.addresses", Message: "The virtual IP addresses associated with the service. Could be CIDR prefix."},
   201  		{ObjectField: "spec.ports", Message: "The ports associated with the external service. If the Endpoints are Unix domain socket addresses, there must be exactly one port."},
   202  		{ObjectField: "spec.location", Message: "Specify whether the service should be considered external to the mesh or part of the mesh."},
   203  		{ObjectField: "spec.resolution", Message: "Service discovery mode for the hosts."},
   204  		{ObjectField: "spec.endpoints", Message: "One or more endpoints associated with the service. Only one of endpoints or workloadSelector can be specified."},
   205  		{ObjectField: "spec.workloadSelector", Message: "Applicable only for MESH_INTERNAL services. Only one of endpoints or workloadSelector can be specified."},
   206  		{ObjectField: "spec.exportTo", Message: "A list of namespaces to which this service is exported. Exporting a service allows it to be used by sidecars, gateways and virtual services defined in other namespaces. This feature provides a mechanism for service owners and mesh administrators to control the visibility of services across namespace boundaries."},
   207  	},
   208  	"virtualservices": {
   209  		{ObjectField: "spec.hosts", Message: "The destination hosts to which traffic is being sent. Could be a DNS name with wildcard prefix or an IP address. Depending on the platform, short-names can also be used instead of a FQDN (i.e. has no dots in the name)."},
   210  		{ObjectField: "spec.gateways", Message: "The names of gateways and sidecars that should apply these routes. Gateways in other namespaces may be referred to by <gateway namespace>/<gateway name>; specifying a gateway with no namespace qualifier is the same as specifying the VirtualService’s namespace. To apply the rules to both gateways and sidecars, specify mesh as one of the gateway names."},
   211  		{ObjectField: "spec.http", Message: "An ordered list of route rules for HTTP traffic."},
   212  		{ObjectField: "spec.exportTo", Message: "A list of namespaces to which this virtual service is exported. Exporting a virtual service allows it to be used by sidecars and gateways defined in other namespaces."},
   213  		{ObjectField: "spec.http.match", Message: "Match conditions to be satisfied for the rule to be activated."},
   214  		{ObjectField: "spec.http.route", Message: "A HTTP rule can either redirect or forward (default) traffic. The forwarding target can be one of several versions of a service. Weights associated with the service version determine the proportion of traffic it receives."},
   215  		{ObjectField: "spec.http.route.destination.host", Message: "The name of a service from the service registry. Service names are looked up from the platform’s service registry (e.g., Kubernetes services, Consul services, etc.) and from the hosts declared by ServiceEntry."},
   216  		{ObjectField: "spec.http.route.destination.subset", Message: "The name of a subset within the service. Applicable only to services within the mesh. The subset must be defined in a corresponding DestinationRule."},
   217  	},
   218  	"workloadentries": {
   219  		{ObjectField: "spec.address", Message: "Address associated with the network endpoint without the port."},
   220  		{ObjectField: "spec.ports", Message: "Set of ports associated with the endpoint."},
   221  		{ObjectField: "spec.labels", Message: "One or more labels associated with the endpoint."},
   222  		{ObjectField: "spec.network", Message: "Network enables Istio to group endpoints resident in the same L3 domain/network. All endpoints in the same network are assumed to be directly reachable from one another."},
   223  		{ObjectField: "spec.locality", Message: "The locality associated with the endpoint. A locality corresponds to a failure domain (e.g., country/region/zone). Arbitrary failure domain hierarchies can be represented by separating each encapsulating failure domain by /."},
   224  		{ObjectField: "spec.weight", Message: "The load balancing weight associated with the endpoint. Endpoints with higher weights will receive proportionally higher traffic."},
   225  		{ObjectField: "spec.serviceAccount", Message: "The service account associated with the workload if a sidecar is present in the workload."},
   226  	},
   227  	"workloadgroups": {
   228  		{ObjectField: "spec.metadata", Message: "Metadata that will be used for all corresponding WorkloadEntries. User labels for a workload group should be set here in metadata rather than in template."},
   229  		{ObjectField: "spec.template", Message: "Template to be used for the generation of WorkloadEntry resources that belong to this WorkloadGroup."},
   230  		{ObjectField: "spec.probe", Message: "ReadinessProbe describes the configuration the user must provide for healthchecking on their workload."},
   231  	},
   232  	"wasmplugins": { // TODO
   233  		{},
   234  	},
   235  	"telemetries": { // TODO
   236  		{},
   237  	},
   238  	"k8sgateways": {
   239  		{ObjectField: "spec", Message: "Kubernetes Gateway API Configuration Object. A Gateway describes how traffic can be translated to Services within the cluster."},
   240  		{ObjectField: "spec.gatewayClassName", Message: "Defines the name of a GatewayClass object used by this Gateway."},
   241  		{ObjectField: "spec.listeners", Message: "Define the hostnames, ports, protocol, termination, TLS settings and which routes can be attached to a listener."},
   242  		{ObjectField: "spec.addresses", Message: "Define the network addresses requested for this gateway."},
   243  	},
   244  	"k8sgrpcroutes": {
   245  		{ObjectField: "", Message: "Kubernetes Gateway API Configuration Object. GRPCRoute provides a way to route gRPC requests"},
   246  	},
   247  	"k8shttproutes": { // TODO
   248  		{ObjectField: "", Message: "Kubernetes Gateway API Configuration Object. HTTPRoute is for multiplexing HTTP or terminated HTTPS connections."},
   249  	},
   250  	"k8sreferencegrants": {
   251  		{ObjectField: "spec", Message: "Kubernetes Gateway API Configuration Object. ReferenceGrant is for enabling cross namespace references within Gateway API."},
   252  		{ObjectField: "spec.from", Message: "Define the group, kind, and namespace of resources that may reference items described in the to list."},
   253  		{ObjectField: "spec.to", Message: "Define the group and kind of resources that may be referenced by items described in the from list."},
   254  	},
   255  	"k8stcproutes": {
   256  		{ObjectField: "", Message: "Kubernetes Gateway API Configuration Object. TCPRoute provides a way to route TCP requests"},
   257  	},
   258  	"k8stlsroutes": {
   259  		{ObjectField: "", Message: "Kubernetes Gateway API Configuration Object. TLSRoute provides a way to route TLS requests"},
   260  	},
   261  	"internal": {
   262  		{ObjectField: "", Message: "Internal resources are not editable"},
   263  	},
   264  }
   265  
   266  // ResourcePermissions holds permission flags for an object type
   267  // True means allowed.
   268  type ResourcePermissions struct {
   269  	Create bool `json:"create"`
   270  	Update bool `json:"update"`
   271  	Delete bool `json:"delete"`
   272  }
   273  
   274  // ResourcesPermissions holds a map of permission flags per resource
   275  type ResourcesPermissions map[string]*ResourcePermissions
   276  
   277  // IstioConfigPermissions holds a map of ResourcesPermissions per namespace
   278  type IstioConfigPermissions map[string]*ResourcesPermissions
   279  
   280  // IstioConfigs holds a map of IstioConfigList per namespace
   281  type IstioConfigs map[string]*IstioConfigList
   282  
   283  // FilterIstioConfigs Filters all Istio configs from Istio registry by given namespaces and return a map config list per namespace
   284  func (configList IstioConfigList) FilterIstioConfigs(nss []string) *IstioConfigs {
   285  	filtered := IstioConfigs{}
   286  
   287  	for _, ns := range nss {
   288  		if filtered[ns] == nil {
   289  			filtered[ns] = new(IstioConfigList)
   290  			filtered[ns].IstioValidations = IstioValidations{}
   291  			filtered[ns].DestinationRules = []*networking_v1beta1.DestinationRule{}
   292  			filtered[ns].EnvoyFilters = []*networking_v1alpha3.EnvoyFilter{}
   293  			filtered[ns].Gateways = []*networking_v1beta1.Gateway{}
   294  			filtered[ns].K8sGateways = []*k8s_networking_v1.Gateway{}
   295  			filtered[ns].K8sGRPCRoutes = []*k8s_networking_v1alpha2.GRPCRoute{}
   296  			filtered[ns].K8sHTTPRoutes = []*k8s_networking_v1.HTTPRoute{}
   297  			filtered[ns].K8sReferenceGrants = []*k8s_networking_v1beta1.ReferenceGrant{}
   298  			filtered[ns].K8sTCPRoutes = []*k8s_networking_v1alpha2.TCPRoute{}
   299  			filtered[ns].K8sTLSRoutes = []*k8s_networking_v1alpha2.TLSRoute{}
   300  			filtered[ns].VirtualServices = []*networking_v1beta1.VirtualService{}
   301  			filtered[ns].ServiceEntries = []*networking_v1beta1.ServiceEntry{}
   302  			filtered[ns].Sidecars = []*networking_v1beta1.Sidecar{}
   303  			filtered[ns].WorkloadEntries = []*networking_v1beta1.WorkloadEntry{}
   304  			filtered[ns].WorkloadGroups = []*networking_v1beta1.WorkloadGroup{}
   305  			filtered[ns].AuthorizationPolicies = []*security_v1beta.AuthorizationPolicy{}
   306  			filtered[ns].PeerAuthentications = []*security_v1beta.PeerAuthentication{}
   307  			filtered[ns].RequestAuthentications = []*security_v1beta.RequestAuthentication{}
   308  			filtered[ns].WasmPlugins = []*extentions_v1alpha1.WasmPlugin{}
   309  			filtered[ns].Telemetries = []*v1alpha1.Telemetry{}
   310  		}
   311  		for _, dr := range configList.DestinationRules {
   312  			if dr.Namespace == ns {
   313  				filtered[ns].DestinationRules = append(filtered[ns].DestinationRules, dr)
   314  			}
   315  		}
   316  
   317  		for _, ef := range configList.EnvoyFilters {
   318  			if ef.Namespace == ns {
   319  				filtered[ns].EnvoyFilters = append(filtered[ns].EnvoyFilters, ef)
   320  			}
   321  		}
   322  
   323  		for _, gw := range configList.Gateways {
   324  			if gw.Namespace == ns {
   325  				filtered[ns].Gateways = append(filtered[ns].Gateways, gw)
   326  			}
   327  		}
   328  
   329  		for _, gw := range configList.K8sGateways {
   330  			if gw.Namespace == ns {
   331  				filtered[ns].K8sGateways = append(filtered[ns].K8sGateways, gw)
   332  			}
   333  		}
   334  
   335  		for _, route := range configList.K8sGRPCRoutes {
   336  			if route.Namespace == ns {
   337  				filtered[ns].K8sGRPCRoutes = append(filtered[ns].K8sGRPCRoutes, route)
   338  			}
   339  		}
   340  
   341  		for _, route := range configList.K8sHTTPRoutes {
   342  			if route.Namespace == ns {
   343  				filtered[ns].K8sHTTPRoutes = append(filtered[ns].K8sHTTPRoutes, route)
   344  			}
   345  		}
   346  
   347  		for _, rg := range configList.K8sReferenceGrants {
   348  			if rg.Namespace == ns {
   349  				filtered[ns].K8sReferenceGrants = append(filtered[ns].K8sReferenceGrants, rg)
   350  			}
   351  		}
   352  
   353  		for _, route := range configList.K8sTCPRoutes {
   354  			if route.Namespace == ns {
   355  				filtered[ns].K8sTCPRoutes = append(filtered[ns].K8sTCPRoutes, route)
   356  			}
   357  		}
   358  
   359  		for _, route := range configList.K8sTLSRoutes {
   360  			if route.Namespace == ns {
   361  				filtered[ns].K8sTLSRoutes = append(filtered[ns].K8sTLSRoutes, route)
   362  			}
   363  		}
   364  
   365  		for _, se := range configList.ServiceEntries {
   366  			if se.Namespace == ns {
   367  				filtered[ns].ServiceEntries = append(filtered[ns].ServiceEntries, se)
   368  			}
   369  		}
   370  
   371  		for _, sc := range configList.Sidecars {
   372  			if sc.Namespace == ns {
   373  				filtered[ns].Sidecars = append(filtered[ns].Sidecars, sc)
   374  			}
   375  		}
   376  
   377  		for _, vs := range configList.VirtualServices {
   378  			if vs.Namespace == ns {
   379  				filtered[ns].VirtualServices = append(filtered[ns].VirtualServices, vs)
   380  			}
   381  		}
   382  
   383  		for _, we := range configList.WorkloadEntries {
   384  			if we.Namespace == ns {
   385  				filtered[ns].WorkloadEntries = append(filtered[ns].WorkloadEntries, we)
   386  			}
   387  		}
   388  
   389  		for _, wg := range configList.WorkloadGroups {
   390  			if wg.Namespace == ns {
   391  				filtered[ns].WorkloadGroups = append(filtered[ns].WorkloadGroups, wg)
   392  			}
   393  		}
   394  
   395  		for _, wp := range configList.WasmPlugins {
   396  			if wp.Namespace == ns {
   397  				filtered[ns].WasmPlugins = append(filtered[ns].WasmPlugins, wp)
   398  			}
   399  		}
   400  
   401  		for _, tm := range configList.Telemetries {
   402  			if tm.Namespace == ns {
   403  				filtered[ns].Telemetries = append(filtered[ns].Telemetries, tm)
   404  			}
   405  		}
   406  
   407  		for _, ap := range configList.AuthorizationPolicies {
   408  			if ap.Namespace == ns {
   409  				filtered[ns].AuthorizationPolicies = append(filtered[ns].AuthorizationPolicies, ap)
   410  			}
   411  		}
   412  
   413  		for _, pa := range configList.PeerAuthentications {
   414  			if pa.Namespace == ns {
   415  				filtered[ns].PeerAuthentications = append(filtered[ns].PeerAuthentications, pa)
   416  			}
   417  		}
   418  
   419  		for _, ra := range configList.RequestAuthentications {
   420  			if ra.Namespace == ns {
   421  				filtered[ns].RequestAuthentications = append(filtered[ns].RequestAuthentications, ra)
   422  			}
   423  		}
   424  		for k, v := range configList.IstioValidations {
   425  			if k.Namespace == ns {
   426  				filtered[ns].IstioValidations.MergeValidations(IstioValidations{k: v})
   427  			}
   428  		}
   429  	}
   430  	return &filtered
   431  }
   432  
   433  // Merge two config lists. To get configs from different namespaces
   434  func (configList IstioConfigList) MergeConfigs(ns IstioConfigList) IstioConfigList {
   435  	configList.DestinationRules = append(configList.DestinationRules, ns.DestinationRules...)
   436  	configList.EnvoyFilters = append(configList.EnvoyFilters, ns.EnvoyFilters...)
   437  	configList.Gateways = append(configList.Gateways, ns.Gateways...)
   438  	configList.AuthorizationPolicies = append(configList.AuthorizationPolicies, ns.AuthorizationPolicies...)
   439  	configList.K8sGateways = append(configList.K8sGateways, ns.K8sGateways...)
   440  	configList.K8sGRPCRoutes = append(configList.K8sGRPCRoutes, ns.K8sGRPCRoutes...)
   441  	configList.K8sHTTPRoutes = append(configList.K8sHTTPRoutes, ns.K8sHTTPRoutes...)
   442  	configList.K8sReferenceGrants = append(configList.K8sReferenceGrants, ns.K8sReferenceGrants...)
   443  	configList.K8sTCPRoutes = append(configList.K8sTCPRoutes, ns.K8sTCPRoutes...)
   444  	configList.K8sTLSRoutes = append(configList.K8sTLSRoutes, ns.K8sTLSRoutes...)
   445  	configList.PeerAuthentications = append(configList.PeerAuthentications, ns.PeerAuthentications...)
   446  	configList.RequestAuthentications = append(configList.RequestAuthentications, ns.RequestAuthentications...)
   447  	configList.ServiceEntries = append(configList.ServiceEntries, ns.ServiceEntries...)
   448  	configList.Sidecars = append(configList.Sidecars, ns.Sidecars...)
   449  	configList.Telemetries = append(configList.Telemetries, ns.Telemetries...)
   450  	configList.VirtualServices = append(configList.VirtualServices, ns.VirtualServices...)
   451  	configList.WasmPlugins = append(configList.WasmPlugins, ns.WasmPlugins...)
   452  	configList.WorkloadEntries = append(configList.WorkloadEntries, ns.WorkloadEntries...)
   453  	configList.WorkloadGroups = append(configList.WorkloadGroups, ns.WorkloadGroups...)
   454  
   455  	return configList
   456  }